Writing Prolog Code
ฝัง
- เผยแพร่เมื่อ 6 ก.ย. 2024
- Writing Prolog code is an exercise in linguistic precision: We describe what is true, and what follows from what. We think in terms of relations between things and let the Prolog engine derive logical consequences for us. When writing Prolog code, we strive for elegance, generality, readability and simplicity. More information: www.metalevel....
I've been doing prolog since the 80s (Turbo Prolog) and this is the clearest explanation I've seen of the true difference I've between declarative and imperative programming. The light bulb went on: Declarative programming describes states of the world before and after some action, but leaves the action to the computer, or as Markus says, it describes relations. It is really relational programming! Brilliant! Bravo! Encore!
Thank you so much Michael for your tremendously encouraging feedback, I greatly appreciate it! It is awesome to hear that you find this material useful. Enjoy!
Always excited to see new Prolog content from you - please keep posting these !!!
Thank you for your efforts!
Thank you so much for your kind words, I greatly appreciate your feedback! Enjoy!
This series on Prolog is so well done, they’re great for someone like me - new to Prolog. Also, I love the Castlevania reference ^^
OMG, this is so incredible. Thanks for posting this. I just subscribed yesterday, and this new content paid off handsomely! Thanks and keep it up.
Thanks for the new video it's as always very helpful, also I just want to clarify I like Prolog and I want actually to use it in my projects, but also I want to add what I think is the biggest frustration of using it.
For example, I want to implement list_without/3 by myself without watching this video.
First attempt:
list_without([], _, []).
list_without([E|At], E, B) :- list_without(At, E, B).
list_without([Ah|At], E, [Ah|Bt]) :- Ah \= E, list_without(At, E, Bt).
Wrong! Query: list_without([a,b,c,d,e], X, T), doesn't enumerate all possibilities.
Second attempt:
list_without([], _, []).
list_without([Ah|At], E, B) :- Ah = E -> B = Bt ; B = [Ah|Bt], list_without(At, E, Bt).
Wrong! Query: list_without([a,b,c,d], a, T). just displays 'yes' without stating what T should be unified with.
Third attempt:
list_without([], _, []).
list_without([Ah|At], E, B) :- ( Ah = E *-> B = Bt ; B = [Ah|Bt] ), list_without(At, E, Bt).
Wrong! Query: list_without([a,b,c,d,e], X, T), doesn't enumerate all possibilities.
And after 1 hour you just give up and watch the video, and in that video you realize that there is a predicate if_/3, that should behave as one would expect, but you have no idea is it even available on your target system.
Yes, that's a perfectly valid point! The reason for this is that Prolog is still under massive development, with new constructs becoming available as they are found. However, even if this is the first time you hear about if_/3, you can express this predicate correctly using only (=)/2 and dif/2. These predicates were both available already in the very first version of Prolog, sometimes called Prolog 0, whereas if_/3 is a bleeding edge development: It is perfectly understandable that not many programmers know it yet. In fact, as of today, Scryer Prolog is the only Prolog system that ships with this predicate as a built-in feature! In the coming decades, it will become more widely available, and will simply be taught instead of the predicates you mentioned.
The great frustration: "?- X = X+1."
Thanks. Great work.
I'm just learning Prolog. My system doesn't work with if/3 so here's my version without if/3 :-
listWithout([], _, []).
listWithout([H|T], X, [H|L]) :-
H \= X,
listWithout(T, X, L).
listWithout([X|T], X, L) :-
listWithout(T, X, L).
OK, this is edited after I've read a comment that I've should be using dif/2 and =/2 instead so here is my updated version :-
listWithout([], _, []).
listWithout([H|T], X, [H|L]) :-
dif(H, X),
listWithout(T, X, L).
listWithout([H|T], X, L) :-
H = X,
listWithout(T, X, L).
I hate prolog, but i like your videos
/* test */
person(i,you).
person(you,i).
greet(X,Y):-
write('thank you',X),
write('for tutorial',Y),
person(X,Y),person(Y,X).
-?false. %test
What about select/3?
list_without_(Xs, E, Ys) :-
member(E, Xs) ->
select(E, Xs, Ys) ;
Ys = Xs.
Succeeds incorrectly for ?- list_without_("aa", a, "a").
Well, it is not recursive, so it only removes one E element. :(
@@ThePowerOfProlog I see your point.
12:24 LOL
Unfortunately I can't get list_without_ to work on SWI-prolog's version of reif. Works on scryer-prolog, and the definition of if_/3 seems to be the same.
I don't get an impression that scryer-prolog is yet suited for teaching. There's no listing/1 predicate and the documentation is one README file. I love the ambition, but don't think it works well for disarming the tension of writing Prolog, as this video sets out to.
@@mwgkgk Scryer Prolog provides listing/1 in library(format), please take a look. For teaching, I recommend you set up a suitable ~/.scryerrc configuration file that you distribute to your students, so that all necessary libraries are always loaded on startup. The README contains a sensible starting point for such a configuration.
Thank you, I should have tried grepping the source for listing/1.
@@mwgkgk The libraries are all in scryer-prolog/src/lib/, and a few of them suffice to write many programs for beginners. I think it's also good practice to read some of the predicate definitions!
Is there any reason you need listing/1? For debugging, check out library(debug)!
@@ThePowerOfProlog I love the instant feedback of seeing what stuff is