3 ms·
>> Prolog is a pretty standard functional programming language, just hidden in a backtracking query runner. I'm perplexed by your comment. Prolog is not a func
by YeGoblynQueenne 4y ago
>> Prolog is a pretty standard functional programming language, just hidden in a
backtracking query runner.
I'm perplexed by your comment. Prolog is not a functional language. It's a logic
programming language.
The terminology about "queries" and "facts" and "rules" is extremely
unfortunate. I think it's inherited from databases, because of the common
implementation trick of storing Prolog programs in a relational database. But
explaining Prolog in these terms, as is indeed very common, only begets endless
confusion. For instance, there is no "query runner" in Prolog. Because there are
no "queries". What people call a Prolog "query" is really a Horn goal proved
by SLD-refutation with respect to a set of defintie clauses, i.e. a Prolog
program.
The point of all that is automated proofs. It just so happens that proving
first-order logic theories and executing programs is the same, hence we can
write a logic program as a theory and run a proof to execute it.
>> I definitely viewed unification as a form of variable assignment (
understanding it would backtrack if unable to assign ).
Yes, that's a common mistake to make, and not your fault. These things are never
explained in Prolog courses. You can think of unification as a form of equality,
as you say, but in truth, unification is a clever optimisation that makes
execution efficient. It makes it possible to run an SLD-refutation proof without
having to ground the entire program into a set of propositions, first.
But to understand what the hell that means you really need to understand
resolution theorem-proving, and a lot of theory about first-order logic, that is
simply not taught to programmers. I was very confused about all that myself,
right up until the first year of my PhD when I finally had the leisure (and the
need) to sit down and really try to get to grips with the material.
But I don't think one needs a PhD to understand all that. What is really needed
is better teaching that doesn't muddle the water with useless terminology about
"queries" and "facts" and "rules" and so on.
- knome 4y ago>I'm perplexed by your comment. Prolog is not a functional language. It's a logic programming language. It's my impression from its use of recursion for execution flow alongside its assign-once variables, which feel a lot like haskell's lazy evaluation.
- knome 4y agoWanting to see what you saw wrong with my impression of prolog, I spent some time digging into the language. It does have an "if then else"-like statement via (->) and (;) `repeat/0` is incredibly gross looking. The examples use it like 'yield' to unify a name and let the rest of the clauses run. It appears to it creates infinite choice-points that must eventually be manually escaped from with a cut (!)? https://www.swi-prolog.org/pldoc/doc_for?object=repeat/0 https://www.swi-prolog.org/pldoc/doc_for?object=repeat/0
- YeGoblynQueenne 4y agoWhy is repeat/0 gross? It implements a failure-driven loop. If you want to force your code to backtrack over all choice points, that's what you need to do. You can't get the same result with recursion. For instance if you have a nondeterministic predicate (definition) and want to loop over all its results, if you try to do that with recursion you'll just generate the same result at every step of the recursion. Instead you want to iterate over all the choice points. To demonstrate its behaviour you can try that on the SWI-Prolog command line: ?- repeat, between(1,3,I). I = 1 ; I = 2 ; I = 3 ; I = 1 ; I = 2 ; I = 3 ; I = 1 . The ";" are where I ask for more results, the "." is where I said "stop". If you tried to recurse around between(1,3,I), you'd get I bound to "1" every step through the recursion- and still leave two choice points behind for every "1". It's been a while since I used repeat/0, but in general it's used to write generators. It usually makes more sense to use findall/3 and friends, which simply iterate over choice points without adding new ones. For example: ?- findall(I, between(1,3,I), Is). Is = [1, 2, 3]. People complain about dirty imperative constructs in Prolog like that all the time, but they are very useful to a pragmatic programmer and everytime anyone tries to "fix" Prolog by removing the impurities, they break it.
- deleted 4y ago[deleted]
- YeGoblynQueenne 4y agoI don't know Haskell but if I understand correctly it uses the Hindley-Milner type system, which itself uses unification as a type-checker? If so, maybe that's the similarity you see? As far as I understand a functional programming language is one where functions are first-class citizens and hopefully the lambada calculus is the top-level abstraction. That's not the case with Prolog, which doesn't even have functions but (like dreamcompiler says) relations which are generalisations of functions, that don't "evaluate" to anything but "relate" objects. I think you're trying to understand Prolog using the abstractions you already know which is, I guess, the way of science. But you have to be careful about applying the wrong abstractions. For example, a language can't be "functional" if it doesn't even have functions. In Prolog everything is a definite clause, and clauses are first-order logic formulae, not functions. The wikipedia article on definite clauses is I think clear and to the point: https://en.wikipedia.org/wiki/Horn_clause https://en.wikipedia.org/wiki/Horn_clause Actually that's the article on Horn clauses, of which definite clauses are a subset, but that's useful to understand, also. For me, a lot of confusion was cleared up when I found a good explanation of what is a definite clause.