Why are DCGs defined as a compact way to describe lists? - prolog

In my opinion, define the DCGs (Definite Clause Grammars) as a compact way to describe the lists in Prolog, is a poorly way to define them. As far as I know, the DCGs are not only used in Prolog, but also in other programming languages, such as Mercury.
In addition, they are called DCGs, because they represent a grammar in a set of definite clauses (Horn clauses), the basis of logic programming.
So why if an entire Prolog program can be written using definite clauses, DCGs are solely defined as a compact way to describe the lists in Prolog?
Note: The doubt arises from the description for the tag dcg given by SO.

The extended info from the DCG tag wiki provides additional information, which I think is both correct and also in close agreement with your first point:
"DCGs are usually associated with Prolog, but similar languages such
as Mercury also include DCGs."
Regarding your second point: Emphasizing the close association with Prolog lists is in my opinion well justified, since a DCG indeed always describes a list, and typically also quite compactly.

Related

Does HiLog add anything that can not be done with "call" in Prolog? [duplicate]

This question already has answers here:
Are HiLog terms still useful in modern Prolog?
(2 answers)
Closed 2 years ago.
The Wikipedia article for Prolog states:
Higher-order programming style in Prolog was pioneered in HiLog and λProlog.
The motivation for HiLog includes its ability to implement higher-order predicates like maplist:
maplist(F)([],[]).
maplist(F)([X|Xs],[Y|Ys]) <- F(X,Y), maplist(F)(Xs,Ys).
The paper that describes HiLog assumes that Prolog only has call/1, not call/3.
However, since Prolog (now) has call/3, maplist can be easily implemented in it:
maplist(_, [], []).
maplist(P, [X|Xs], [Y|Ys]) :- call(P, X, Y), maplist(P, Xs, Ys).
Is HiLog mostly of historical interest, or is its "higher-order" logic more general that what's available in Prolog now?
From wiki
Although syntactically HiLog strictly extends first order logic, HiLog can be embedded into this logic.
Any HiLog term can be translated into a Prolog term (HiLog: A foundation for higher-order logic programming - Weidong Chen, Michael Kifer, David S.Warren - 1993). So in a sense yes, it is not more general than Prolog.
Let me quote a few conclusions from the paper
Firstly, programming in HiLog makes more logic programs logical. We all admonish Prolog programmers to make their programs as pure as possible and to eschew the evils of Prolog’s nonlogical constructs. In Prolog, the intermixing of predicate and function symbols, in particular in the predicate, call/ 1, is nonlogical, whereas in HiLog, it is completely logical and is a first-class citizen. So in HiLog, programmers
need not avoid using call/l, and thus have more flexibility in their
task of writing pure logic programs.
Secondly, even though one might say that HiLog is simply a syntactic variant of Prolog, syntax is important when one is doing meta-programming.
Since in meta-programming the syntax determines the data structures to be manipulated, a simpler syntax means that meta-programs can be much simpler.
A bit vaguely:
HiLog is not in Prolog (Prolog stays Prolog) but is used in Flora, which is basically an logic-based object-oriented database. It has its own syntax and runs on XSB Prolog.
If I understand correctly, the idea of HiLog is to have a defined practical syntax for "higher-order" predicates, by allowing variables in predicate name positions. This is the difference between the two maplist examples.
This looks as if this was 2-nd order logic (which becomes uncomputable/untractable as there is no way to find out whether a predicate F is related to a predicate G in general as you may be forced to compare their extent, all the points where they succeed) but is flattened down to 1-st order (computable) by restriction to syntactic equality (F and G are the same if the name the same predicate, foo/2) at which point one can deploy call/N to generate Prolog code.
So, yes, currently you have to jump through hoops to express statements in Prolog that may be a one-liner in HiLog (I have no examples though, not having though too deeply about this). It's the difference between C and ... uh ... Prolog!
Similar to a host of other ideas for extensions/modifications to Prolog into various X-logs, not all of which were implemented (I once tried to make a an overview image here), "HiLog syntax" (or something similar to it) may be found in a specialized X-log of the future that breaks out of its niche.
Since I answered my own question in the comments, I'll post it here:
There are things you can do in HiLog, that can not be done with call in Prolog, for example:
Queries like:
?- X(dog, 55, Y).
Assertions like:
foo(X, Y) :- Z(X), Z(Y(X)).
As stated in the aforementioned HiLog paper and the HiLog Wikipedia page, Prolog can emulate HiLog. However, this requires converting the whole program and all queries into a single predicate.

Looking for a more compact syntax for Prolog

Prolog is a nice language. I use it occasionally, from time to time.
But approaching it every subsequent time makes me feel less and less comfortable syntactically.
The modern programming languages are moving to allow
programmer less repeating himself
omit unnecessary pieces if they can be deduced, or their names are just placeholders.
The DCG is a step in the right direction allowing one to write
sentence --> noun_phrase, verb_phrase.
instead of
sentence(A,Z) :- noun_phrase(A,B), verb_phrase(B,Z).
but its entanglement with difference lists makes it less useful.
So what I am looking for are projects giving Prolog
a more compact syntactic representation, while preserving its semantic expressiveness.
Higher-order programming based on call/N is still a pretty much unexplored terrain. Major implementations like SICStus Prolog added call/N as late as 2006. So there is still a lot to explore. Consider library(lambda), library(reif) (both here) and other definitions using the meta-predicate declaration.
One thing you might want to look into in case of Swi-Prolog are actual language extensions introduced specifically by Swi-Prolog 7:
http://www.swi-prolog.org/pldoc/man?section=extensions
Another thing is Quasi-Quotation library which allows you to insert pieces of code in your own language (defined using DCG) inside "regular" Prolog code:
http://www.swi-prolog.org/pldoc/man?section=quasiquotations
The last thing I can recommend is the list of additional Swi-Prolog packages, some of which are specifically designed to extend the language, e.g. 'func', 'lambda', etc.:
http://www.swi-prolog.org/pack/list

How to choose between bagof, setof and findall in Prolog

How does one choose between bagof, setof and findall? Are there any important differences? Which is most commonly used and which is the safest? Thanks for your comments/answers.
I checked the SWI-Prolog manual page on findall/3 and found them to be very similar.
That's a great question!
I am not attempting to give an exhaustive answer, but I would like to suggest a few lines of thought that can help you to understand these predicates better:
Think about which of these predicates are more fundamental in the sense of what can be expressed in terms of what. For example, can you express findall/3 in terms of setof/3? And what about the other way around? This helps to see what you need to provide at least to implement all these predicates.
Think about which declarative properties are preserved by these predicates. For example, does the order in which the solutions are found influence the results? For which of these predicates precisely? Can any of these predicates fail? In which cases precisely?
Think about the space and time complexity of each of these predicates. Which of these predicates, if any, can be implemented and used more efficiently than others? And at what cost and tradeoffs?
In addition, I recommend you read Richard O'Keefe's book The Craft of Prolog for valuable information about these predicates.
an important difference I found between findall/3 and bagof/3, is that the latter doesn't make copies of the terms it accumulates. This can be crucial, for instance, if your list collects attributed variables, like when modelling a problem with library(clpfd).

Implementing arithmetic for Prolog

I'm implementing a Prolog interpreter, and I'd like to include some built-in mathematical functions (sum, product, etc). For example, I would like to be able to make calculations using knowledge bases like this one:
NetForce(F) :- Mass(M), Acceleration(A), Product(M, A, F)
Mass(10) :- []
Acceration(12) :- []
So then I should be able to make queries like ?NetForce(X). My question is: what is the right way to build functionality like this into my interpreter?
In particular, the problem I'm encountering is that, in order to evaluate Sum, Product, etc., all their arguments have to be evaluated (i.e. bound to numerical constants) first. For example, while to code above should evaluate properly, the permuted rule:
NetForce(F) :- Product(M, A, F), Mass(M), Acceleration(A)
wouldn't, because M and A aren't bound when the Product term is processed. My current approach is to simply reorder the terms so that mathematical expressions appear last. This works in simple cases, but it seems hacky, and I would expect problems to arise in situations with multiple mathematical terms, or with recursion. Is there a better solution?
The functionality you are describing exists in existing systems as constraint extensions. There is CLP(Q) over the rationals, CLP(R) over the reals - actually floats, and last but not least CLP(FD) which is often extended to a CLP(Z). See for example
library(clpfd).
In any case, starting a Prolog implementation from scratch will be a non-trivial effort, you will have no time to investigate what you want to implement because you will be inundated by much lower level details. So you will have to use a more economical approach and clarify what you actually want to do.
You might study and implement constraint languages in existing systems. Or you might want to use a meta-interpreter based approach. Or maybe you want to implement a Prolog system from scratch. But don't expect that you succeed in all of it.
And to save you another effort: Reuse existing standard syntax. The syntax you use would require you to build an extra parser.
You could use coroutining to delay the evaluation of the product:
product(X, A, B) :- freeze(A, freeze(B, X is A*B))
freeze/2 delays the evaluation of its second argument until its first argument is ground. Used nested like this, it only evaluates X is A*B after both A and B are bound to actual terms.
(Disclaimer: I'm not an expert on advanced Prolog topics, there might be an even simpler way to do this - e.g. I think SICStus Prolog has "block declarations" which do pretty much the same thing in a more concise way and generalized over all declarations of the predicate.)
Your predicates would not be clause order independent, which is pretty important. You need to determine usage modes of your predicates - what will the usage mode of NetForce() be? If I were designing a predicate like Force, I would do something like
force(Mass,Acceleration,Force):- Force is Mass * Acceleration.
This has a usage mode of +,+,- meaning you give me Mass and Acceleration and I will give you the Force.
Otherwise, you are depending on the facts you have defined to unify your variables, and if you pass them to Product first they will continue to unify and unify and you will never stop.

Theorem Proof Using Prolog

How can I write theorem proofs using Prolog?
I have tried to write it like this:
parallel(X,Y) :-
perpendicular(X,Z),
perpendicular(Y,Z),
X \== Y,
!.
perpendicular(X,Y) :-
perpendicular(X,Z),
parallel(Z,Y),
!.
Can you help me?
I was reluctant to post an Answer because this Question is poorly framed. Thanks to theJollySin for adding clean formatting! Something omitted in the rewrite, indicative of what Aman had in mind, was "I inter in Loop" (sic).
We don't know what query was entered that resulted in this looping, so speculation is required. The two rules suggest that Goal involved either the parallel/2 or the perpendicular/2 predicate.
With practice it's not hard to understand what the Prolog engine will do when a query is posed, especially a single goal query. Prolog uses a pretty simple "follow your nose" strategy in attempting to satisfy a goal. Look for the rules for whichever predicate is invoked. Then see if any of those rules, starting with the first and going down in the list of them, can be applied.
There are three topics that beginning Prolog programmers will typically struggle with. One is the recursive nature of the search the Prolog engine makes. Here the only rule for parallel/2 has a right-hand side that invokes two subgoals for perpendicular/2, while the only rule for perpendicular/2 invokes both a subgoal for itself and another subgoal for parallel/2. One should expect that trying to satisfy either kind of query inevitably leads to a Hydra-like struggle with bifurcating heads.
The second topic we see in this example is the use of free variables. If we are to gain knowledge about perpendicularity or parallelism of two specific lines (geometry), then somehow the query or the rules need to provide "binding" of variables to "ground" terms. Again without the actual Goal being queried, it's hard to guess how Aman expected that to work. Perhaps there should have been "facts" supplied about specific lines that are perpendicular or parallel. Lines could be represented merely as atoms (perhaps lowercase letters), but Prolog variables are names that begin with an uppercase letter (as in the two given rules) or with an underscore (_) character.
Finally the third topic that can be quite confusing is how Prolog handles negation. There's only a touch of that in these rules, the place where X\==Y is invoked. But even that brief subgoal requires careful understanding. Prolog implements "negation as failure", so that X\==Y succeeds if and only if X==Y does not succeed. This latter goal is also subtle, because it asks whether X and Y are the same without trying to do any unification. Thus if these are different variables, both free, then X==Y fails (and X\==Ysucceeds). On the other hand, the only way for X==Yto succeed (and thus for X\==Y to fail) would be if both variables were bound to the same ground term. As discussed above the two rules as stated don't provide a way for that to be the case, though something might have taken care of this in the query Goal.
The homework assignment for Aman is to learn about these Prolog topics:
recursion
free and bound variables
negation
Perhaps more concrete suggestions can then be made about Prolog doing geometry proofs!
Added: PTTP (Prolog Technology Theorem Prover) was written by M.E. Stickel in the late 1980's, and this 2006 web page describes it and links to a download.
It also summarizes succinctly why Prolog alone is not " a full general-purpose theorem-proving system." Pointers to later, more capable theorem provers can be followed there as well.

Resources