Related
I am trying to develop a "simplest" prolog program.
Method 1
Conceptually, the program creates a set of facts which are stored in the database, to be queried later.
% simple facts
apple.
banana.
orange.
cherry.
The database can be queried as expected.
?- apple.
true
?- mango.
procedure `mango' does not exist
Method 2
Most textbooks which teach prolog would start such a "simplest" program using predicates, something like:
% simple facts
exists(apple).
exists(banana).
exists(orange).
exists(cherry).
The queries would then change in nature to testing whether the predicate can be satisfied, eg:
?- exists(apple).
true
?- exists(mango).
false
Question:
Is Method 1 an incorrect use of prolog? If so, why?
In my understanding, prolog is testing whether queries can be shown to be true, and to do this the database is searched. My doubt is raised by the error "procedure `mango' does not exist".
I think you are focusing on a distinction between "facts" and "predicates" which does not really exist; apple. is apple(). a predicate with no body and no arguments. The following shape:
name(argument1, argument2) :-
n2(arg3),
n3(arg4).
says that "name holds for the given arguments if n2 and n3 hold for their arguments", i.e. name only holds in certain conditions. Take the conditions away and you get:
name(argument1, argument2).
Now there are no conditions where it can fail, so it says "name holds for the given arguments". It always holds, it's like an unchanging fact, but "fact" is not a different kind of thing in Prolog, it's still a term with a functor and arity which can be called, it's just that the body of code to check is effectively true and nothing else.
Take the arguments away and you get:
name.
"name holds". It's similar to name()., no arguments.
The way Prolog is implemented, these are close to functions, procedures, subroutines in other languages - they are not the same, but Prolog looks through your code for one with a matching name (functor) and matching number of arguments (similar to method overload resolution in other languages), and calls it with the given arguments and sees whether it holds or not. If it cannot find a matching name and number of arguments, you get the "procedure does not exist" error.
In typical Prolog usage, the style name(argument1, argument2) is used so that "name" tries to describe a logical relation between the arguments, and the arguments are the data being related. e.g. length(List, Quantity) tries to explain that List is related to Quantity through the relation of length.
With method 2 you can extend it to:
exists(apple).
exists(crabapple).
exists(concrete).
food(apple).
food(crabapple).
food(snozzcumber).
edible(apple).
edible(snozzcumber).
and then ask for all things which exist, all foods, all edible things, or combinations like foods which are fictional and edible, things which exist but are inedible, etc. With method 1 you can say that apple holds, but you can't easily use it as data, can't easily query for all things which exist, can't easily change the code to describe that apple exists and is edible. With method 2 you can ask ?- exists(X). and have Prolog fill in X and tell you that apple exists. You can't easily do that with method 1.
If you put the data in place of the name (functor) that's like storing food by using an empty text file named 'apple.txt' and an empty text file named 'banana.txt' and so on, instead of putting them in a single file exists.txt. It's not a syntax or logical error to do this, if there is a reason you want to do it like that then you can, so it's hard to call it strictly "incorrect". Also like using a SQL database and making a table 'apple' and a table 'banana' and so on, instead of putting them in a table 'fruit'. Like having a bookshelf with a book named 'apple' and a book named 'banana' and so on, instead of one book named 'Fruits of the World'. You can do that, it's not incorrect to name a book "apple", but it's not a good way to use books to store lists of fruit.
If you specifically want something for codegolf where shortness trumps all other concerns then yes, fine. But it is going against the grain, against the normal use, it limits what you can do and it's not how Prolog was built to be used. It's also hard to describe something with fewer characters as "simpler" if it means a weird, limited, non-standard way of doing things.
The predicate exists/1 exists, the predicate apple/0 exists, the predicate mango/0 does not exist.
The query exists(apple). successfully reports true ("succeeds" in the Prolog vernacular), the query exists(mango). successfully reports false ("fails" to be proven, in the vernacular), the query apple. successfully reports true and the query mango. fails to execute because the predicate mango/0 does not exist.
So we can say that apple "exists", mango does not "exist", apple/0 exists, but mango/0 does not exist.
However, (in SWI Prolog),
11 ?- mango.
ERROR: toplevel: Undefined procedure: mango/0 (DWIM could not correct goal)
12 ?- [user].
:- dynamic(mango/0).
|: ^Z
true.
13 ?- mango.
false.
So you can work with your 1st method too, if you declare all the predicates of interest as dynamic.
I am using SWI Prolog and am surprised to find no obvious way to do this in Prolog. What I'm after is something similar to clause/2 but allows uninstantiated first argument (and is specific to the clauses in a given file, ie I don't want the entire Prolog library!). Here is what I wrote to find all the clauses
clauseX(H,B) :-
current_predicate(P/Arity),
functor(H,P,Arity),
absolute_file_name('filname.pl', AbsFileName),
predicate_property(H, file(AbsFileName)),
clause(H,B).
Is there a more concise way of doing this?
OK, so I've been able to shorten it somewhat, the first two literals aren't required, this will return clauses in the file filename.pl
clauseX(H,B) :-
absolute_file_name('filname.pl', AbsFileName),
predicate_property(H, file(AbsFileName)),
clause(H,B).
However I am still concerned about the efficiency of this and whether it has to consult the file every time clauseX is called
Prolog's grammar uses a <head> :- <body> format for rules as such:
tree(G) :- acyclic(G) , connected(G).
, denoting status of G as a tree depends on status as acyclic and connected.
This grammar can be extended in an implicit fashion to facts. Following the same example:
connected(graphA) suggests connected(graphA):-true.
In this sense, one might loosely define Prolog facts as Prolog rules that are always true.
My question: Is in any context a bodiless rule (one that is presumed to be true under all conditions) ever appropriate? Syntactically such a rule would look as follows.
graph(X). (suggesting graph(X):-true.)
Before answering, to rephrase your question:
In Prolog, would you ever write a rule with nothing but anonymous variables in the head, and no body?
The terminology is kind of important here. Facts are simply rules that have only a head and no body (which is why your question is a bit confusing). Anonymous variables are variables that you explicitly tell the compiler to ignore in the context of a predicate clause (a predicate clause is the syntactical scope of a variable). If you did try to give this predicate clause to the Prolog compiler:
foo(Bar).
you will get a "singleton variable" warning. Instead, you can write
foo(_).
and this tells the compiler that this argument is ignored on purpose, and no variable binding should be attempted with it.
Operationally, what happens when Prolog tries to prove a rule?
First, unification of all arguments in the head of the rule, which might lead to new variable bindings;
Then, it tries to prove the body of the rule using all existing variable bindings.
As you can see, the second step makes this a recursively defined algorithm: proving the body of a rule means proving each rule in it.
To come to your question: what is the operational meaning of this:
foo(_).
There is a predicate foo/1, and it is true for any argument, because there are no variable bindings to be done in the head, and always, because no subgoals need to be proven.
I have seen at least one use of such a rule: look at the very bottom of this section of the SWI-Prolog manual. The small code example goes like this:
term_expansion(my_class(_), Clauses) :-
findall(my_class(C),
string_code(_, "~!##$", C),
Clauses).
my_class(_).
You should read the linked documentation to see the motivation for doing this. The purpose of the code itself is to add at compile time a table of facts to the Prolog database. This is done by term expansion, a mechanism for code transformations, usually used through term_expansion/2. You need the definition of my_class/1 so that term_expansion/2 can pick it up, transform it, and replace it with the expanded code. I strongly suggest you take the snipped above, put it in a file, consult it and use listing/1 to see what is the effect. I get:
?- listing(my_class).
my_class(126).
my_class(33).
my_class(64).
my_class(35).
my_class(36).
true.
NB: In this example, you could replace the two occurrences of my_class(_) with anything. You could have just as well written:
term_expansion(foobar, Clauses) :-
findall(my_class(C),
string_code(_, "~!##$", C),
Clauses).
foobar.
The end result is identical, because the operational meaning is identical. However, using my_class(_) is self-documenting, and makes the intention of the code more obvious, at least to an experienced Prolog developer as the author of SWI-Prolog ;).
A fact is just a bodiless rule, as you call it. And yes, there are plenty of use cases for bodiless facts:
representing static data
base cases for recursion
instead of some curly brace language pseudo code
boolean is_three(integer x) {
if (x == 3) { return true; }
else { return false; }
}
we can simply write
is_three(3).
This is often how the base case of a recursive definition is expressed.
To highlight what I was initially looking for, I'll include the following short answer for those who might find themselves asking my initial question in the future.
An example of a bodiless rule is, as #Anniepoo suggested, a base case for a recursive definition. Look to the example of a predicate, member(X,L) for illustration:
member(X,[X|T]). /* recursive base case*/
member(X,[H|T]):- member(X,T).
Here, the first entry of the member rule represents a terminating base case-- the item of interest X matching to the head of the remaining list.
I suggest visiting #Boris's answer (accepted) for a more complete treatment.
I am very new to Prolog and trying to learn.
For my program, I would like to have the user provide pairs of strings which are "types of".
For example, user provides at command line the strings "john" and "man". These atoms would be made to be equal, i.e. john(man).
At next prompt, then user provides "man" and "tall", again program asserts these are valid, man(tall).
Then the user could query the program and ask "Is john tall?". Or in Prolog: john(tall) becomes true by transitive property.
I have been able to parse the strings from the user's input and assign them to variables Subject and Object.
I tried a clause (where Subject and Object are different strings):
attribute(Subject, Object) :-
assert(term_to_atom(_ , Subject),
term_to_atom(_ , Object)).
I want to assert the facts that Subject and Object are valid pair. If the user asserts it, then they belong to together. How do I force this equality of the pairs?
What's the best way to go about this?
Questions of this sort have been asked a lot recently (I guess your professors all share notes or something) so a browse through recent history might have been productive for you. This one comes to mind, for instance.
Your code is pretty wide of the mark. This is what you're trying to do:
attribute(Subject, Object) :-
Fact =.. [Object, Subject],
assertz(Fact).
Using it works like this:
?- attribute(man, tall).
true.
?- tall(X).
X = man.
So, here's what you should notice about this code:
We're using =../2, the "univ" operator, to build structures from lists. This is the only way to create a fact from some atoms.
I've swapped subject and object, because doing it the other way is almost certainly not what you want.
The predicate you want is assertz/1 or asserta/1, not assert/2. The a and z on the end just tells Prolog whether you want the fact at the beginning or end of the database.
Based on looking at your code, I think you have a lot of baggage you need to shed to become productive with Prolog.
Prolog predicates do not return values. So assert(term_to_atom(... wasn't even on the right track, because you seemed to think that term_to_atom would "return" a value and it would get substituted into the assert call like in a functional or imperative language. Prolog just plain works completely differently from that.
I'm not sure why you have an empty variable in your term_to_atom predicates. I think you did that to satisfy the predicate's arity, but this predicate is pretty useless unless you have one ground term and one variable.
There is an assert/2, but it doesn't do what you want. It should be clear why assert normally only takes one argument.
Prolog facts should look like property(subject...). It is not easy to construct facts and then query them, which is what you'd have to do using man(tall). What you want to say is that there is a property, being tall, and man satisfies it.
I would strongly recommend you back up and go through some basic Prolog tutorials at this point. If you try to press forward you're only going to get more lost.
Edit: In response to your comment, I'm not sure how general you want to go. In the basic case where you're dealing with a 4-item list with [is,a] in the middle, this is sufficient:
build_fact([Subject,is,a,Object], is_a(Subject, Object)).
If you want to isolate the first and last and create the fact, you have to use univ again:
build_fact([Subject|Rest], Fact) :-
append(PredicateAtoms, [Object], Rest),
atomic_list_concat(PredicateAtoms, '_', Predicate),
Fact =.. [Predicate, Subject, Object].
Not sure if you want to live with the articles ("a", "the") that will wind up on the end though:
?- build_fact([john,could,be,a,man], Fact).
Fact = could_be_a(john, man)
Don't do variable fact heads. Prolog works best when the set of term names is fixed. Instead, make a generic place for storing properties using predefined, static term name, e.g.:
is_a(john, man).
property(man, tall).
property(john, thin).
(think SQL tables in a normal form). Then you can use simple assertz/1 to update the database:
add_property(X, Y) :- assertz(property(X, Y)).
How do I define a rule that the user cannot query?
I only want the program itself to call this rule through another rule.
Ex:
rule1():- rule2().
rule2():- 1<5.
?-rule1().
true
?-rule2().
(I don't know what the answer will be, I just want this query to fail!)
Use a Logtalk object to encapsulate your predicates. Only the predicates that you declare public can be called (from outside the object). Prolog modules don't prevent calling any predicate as using explcit qualification bypasses the list of explicitly exported predicates.
A simple example:
:- object(rules).
:- public(rule1/1).
rule1(X) :-
rule2(X).
rule2(X) :-
X < 5.
:- end_object.
After compiling and loading the object above:
?- rules::rule1(3).
true.
?- rules::rule2(3).
error(existence_error(predicate_declaration,rule2(3)),rules::rule2(3),user)
If you edit the object code and explicitly declare rule2/1 as private you would get instead the error:
?- rules::rule2(3).
error(permission_error(access,private_predicate,rule2(3)),rules::rule2(3),user)
More information and plenty of examples at http://logtalk.org/
First, some notes:
I think you mean "predicate" instead of "rule". A predicate is a name/k thing such as help/0 (and help/1 is another) and can have multiple clauses, among them facts and rules, e.g. length([], 0). (a fact) and length([H|T], L) :- ... . (a rule) are two clauses of one predicate length/2.
Do not use empty parenthesis for predicates with no arguments – in SWI-Prolog at least, this will not work at all. Just use predicate2 instead of predicate2() in all places.
If you try to call an undefined predicate, SWI-Prolog will say ERROR: toplevel: Undefined procedure: predicate2/0 (DWIM could not correct goal) and Sicstus-Prolog will say {EXISTENCE ERROR: predicate2: procedure user:predicate2/0 does not exist}
Now, to the answer. Two ideas come to my mind.
(1) This is a hack, but you could assert the predicate(s) every time you need them and retract them immediately afterwards:
predicate1 :-
assert(predicate2), predicate2, retractall(predicate2).
If you want a body and arguments for predicate2, do assert(predicate2(argument1, argument2) :- (clause1, clause2, clause3)).
(2) Another way to achieve this would be to introduce an extra argument for the predicate which you do not want to be called by the user and use it for an identification that the user cannot possibly provide, but which you can provide from your calling predicate. This might be a large constant number which looks random, or even a sentence. This even enables you to output a custom error message in case the wrong identification was provided.
Example:
predicate1 :-
predicate2("Identification: 2349860293587").
predicate2(Identification) :-
Identification = "Identification: 2349860293587",
1 < 5.
predicate2(Identification) :- Identification \= "Identification: 2349860293587",
write("Error: this procedure cannot be called by the user. Use predicate1/0 instead."),
fail.
I don't use the equivalent predicate2("Identification: 2349860293587") for the first clause of predicate2/0, because I'm not sure where the head of the clause might appear in Prolog messages and you don't want that. I use a fail in the end of the second clause just so that Prolog prints false instead of true after the error message. And finally, I have no idea how to prevent the user from looking up the source code with listing(predicate2) so that will still make it possible to simply look up the correct identification code if s/he really wants to. If it's just to keep the user from doing accidental harm, it should however suffice as a protection.
This reminds me to facility found in Java. There one can query the
curent call stack, and use this to regulate permissions of calling
a method. Translated to Prolog we find in the old DEC-10 Prolog the
following predicate:
ancestors(L)
Unifies L with a list of ancestor goals for the current clause.
The list starts with the parent goal and ends with the most recent
ancestor coming from a call in a compiled clause. The list is printed
using print and each entry is preceded by the invocation number in
parentheses followed by the depth number (as would be given in a
trace message). If the invocation does not have a number (this will
occur if Debug Mode was not switched on until further into the execution)
then this is marked by "-". Not available for compiled code.
Since the top level is usually a compiled predicate prolog/0, this could be
used to write a predicate that inspects its own call stack, and then decides
whether it wants to go into service or not.
rule2 :- ancestors(L), length(L,N), N<2, !, write('Don't call me'), fail.
rule2 :- 1<5.
In modern Prologs we don't find so often the ancestors/1 predicate anymore.
But it can be simulated along the following lines. Just throw an error, and
in case that the error is adorned with a stack trace, you get all you need:
ancestors(L) :- catch(sys_throw_error(ignore),error(ignore,L),true).
But beware stack eliminiation optimization might reduce the stack and thus
the list returned by ancestors/1.
Best Regards
P.S.: Stack elimination optimization is already explained here:
[4] Warren, D.H.D. (1983): An Abstract Prolog Instruction Set, Technical Note 309, SRI International, October, 1983
A discussion for Jekejeke Prolog is found here:
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/10_pro08/13_press/03_bench/05_optimizations/03_stack.html