what is the issue with the following script?
want(grocerystore).
available(grocerystore).
want(X):-
available(X).
can(grocerystore):-
want(grocerystore),
\+work(walmart),
available(grocerystore).
"Discontiguous predicate" means that you defined more than one clause for a given predicate, but defined the clause of a different predicate in between. Prolog wants all of the clauses of a given predicate together.
Here's an example of what properly defined Prolog looks like with multiple clauses for a given predicate or fact:
person(sally).
person(sue).
dog(fido).
dog(fluffy).
You can see all of the person facts are together, and all of the dog facts are together.
Here is an example of a "discontiguous predicate":
person(sally).
dog(fido).
person(sue).
dog(fluffy).
Here, the person facts are "interrupted" by a dog fact (and vice versa).
The same issue applies to predicates as it does to facts. In your case, two different want clauses are "interrupted" by the available fact:
want(grocerystore).
available(grocerystore). % 'available' clause occurs between two 'want' clauses
want(X) :- ...
Easy fix in this case:
available(grocerystore).
want(grocerystore).
want(X) :- ...
There may be other issues with your program, but I'm only addressing the question you have about "discontiguous predicate".
Related
The question of the difference between a functor and a predicate in prolog is asked often.
I am trying to develop an informal definition that is suitable for new students.
A functor is the name of a predicate. The word functor is used when
discussing syntax, such as arity, affix type, and relative priority
over other functors. The word predicate is used when discussing
logical and procedural meaning.
This looks "good enough" to me.
Question: Is it good enough, or is it fundamentally flawed?
To be clear, I am aiming to develop a useful intuition, not write legalistic text for an ISO standard!
The definition in https://www.swi-prolog.org/pldoc/man?section=glossary is:
"functor: Combination of name and arity of a compound term. The term foo(a,b,c) is said to be a term belonging to the functor foo/3." This does not help a lot, and certainly doesn't explain the difference from a predicate, which is defined: "Collection of clauses with the same functor (name/arity). If a goal is proved, the system looks for a predicate with the same functor, then uses indexing to select candidate clauses and then tries these clauses one-by-one. See also backtracking.".
One of the things that often confuses students is that foo(a) could be a term, a goal, or a clause head, depending on the context.
One way to think about term versus predicate/goal is to treat call/1 as if it is implemented by an "infinite" number of clauses that look like this:
call(foo(X)) :- foo(X).
call(foo(X,Y)) :- foo(X,Y).
call(bar(X)) :- bar(X).
etc.
This is why you can pass around at term (which is just data) but treat it as a "goal". So, in Prolog there's no need to have a special "closure" or "thunk" or "predicate" data type - everything can be treated as just data and can be executed by use of the call/1 predicate.
(There are also variations on "call", such as call/2, which can be defined as:
call(foo, X) :- foo(X).
call(foo(X), Y) :- foo(X, Y).
etc.)
This can be used to implement "meta-predicates", such as maplist/2, which takes a list and applies a predicate to each element:
?- maplist(writeln, [one,two,three]).
one
two
three
where a naïve implementation of maplist/2 is (the actual implementation is a bit more complicated, for efficiency):
maplist(_Goal, []).
maplist(Goal, [X|Xs]) :-
call(Goal, X),
maplist(Goal, Xs).
The answer by Peter Ludemann is already very good. I want to address the following from your question:
To be clear, I am aiming to develop a useful intuition, not write legalistic text for an ISO standard!
If you want to develop intuition, don't bother writing definitions. Definitions end up being written in legalese or are useless as definitions. This is why we sometimes explain by describing how the machine will behave, this is supposedly well-defined, while any statement written in natural language is by definition ambiguous. It is interpreted by a human brain, and you have no idea what is in this brain when it interprets it. As a defense, you end up using legalese to write definitions in natural language.
You can give examples, which will leave some impression and probably develop intuition.
"The Prolog compound term a(b, c) can be described by the functor a/2. Here, a is the term name, and 2 is its arity".
"The functor foo/3 describes any term with a name foo and three arguments."
"Atomic terms by definition have arity 0: for example atoms or numbers. The atom a belongs to the functor a/0."
"You can define two predicates with the same name, as long as they have a different number of arguments."
There is also the possibility of confusion because some system predicates that allow introspection might take either a functor or the head of the predicate they work on. For example, abolish/1 takes a functor, while retractall/1 takes the predicate head.....
In Prolog, this is unambiguously a fact:
foo(bar).
And this is unambiguously a rule:
foo(X) :- bar(X).
But what about a clause that has both non-singleton variables and no :- such as
identity(X,X).
or more realistically something like
my_member(X, [X|_]).
I've been calling these rules since I learned Prolog, but now that I've tried to check to be 100% sure, I can't seem to find any source making a stronger distinction than what I have in the first two examples.
So is a rule:
a clause that defines a variable logical relationship, i.e. a clause that will not always succeed.
a clause that that defines a relationship between predicates (or possibly a predicate and itself).
Sometimes terminology itself causes problems the actual Prolog systems do not have at all. In common terminology as well as standard terminology, both identity(X,X). and my_member(X, [X|_]). are facts. However, better use clause when this seems fit.
The unease stems from the set of solutions that are implied by such cases. In fact, there is an infinity of solutions for both examples. Otherwise, ground facts just describe one solution each. Sticking to ground facts only, simplifies bottom-up interpretations.
So what about the clause a :- true. Is it a fact or a rule? It uses a rule-atom. but it's body is true. A Note in 3.72 excludes (:-)/2 as principal functor of facts. Well, all of this is a clear indication that terminology is here a bit too fine grained.
So, stick as much as you can to clause.
The truth is that there is an argument over Prolog's terminology, but i' ll try to make a brief review which will hopefully lead to some answers.
Generally speaking, a Prolog program consists of objects and the relations between them.
The relations are called predicates and the objects are called arguments of the predicate. The number of the arguments is the predicate's arity.
Describing the objects and their relations is being done with clauses. There are three types of clauses: facts, rules and queries.
A fact denotes a relation between objects. This relation is unambiguously true. Syntactically, a fact consists of a name describing a relation, followed by one or more comma separated objects in parenthesis and a period. Example:
male(john).
father_of(adam, cain).
Combining facts, we can define new relations between objects. This is done with a rule, which consists of two parts: a condition section (also called body of the rule) and a conclusion (also called head of the rule). While facts denote relations that are unambiguously true, rules denote relations that are true only if certain conditions are true. These conditions are also relations between objects. Syntactically, the head of the rule is separated from the body with the neck operator (:-) which can be read as if. The conditions of the rule, if more than one, are separated by commas which can be read as and. Example:
father_of(X,Y) :-
parent(X,Y),
male(X).
In conclusion, rules and facts are clauses. A rule has the form Head :- Body. and a fact has the form Head. Predicates are relations defined by a name and number of arguments and there can be multiple facts or rules for the same predicate. Ultimately:
father_of/2 is a predicate named father_of with arity 2
father_of(adam, cain). is a fact
father_of(adam, abel). is another fact
father_of(A,B) :- parent(A,B), male(A). is a rule
I'm studying for an Artificial Intelligence exam and struggling to understand how to answer certain questions focusing on Predicates. The two questions in particular are:
Define a predicate which behaves as follows -
?- stage_name(billie, Name).
Name = rose
yes
?- stage_name(jenna,Name).
Name = clara
yes
Write a predicate that takes two argument and is true if both actors are on the same show. Thus
?-same_show(david,clara).
is true, whilst
?-same_continent(elisabeth,skippy).
is not
I don't really understand how I would answer these questions, and I'm finding very little Prolog information online. I would appreciate some help. Apologies for the formatting.
1:
stage_name(billie,rose).
stage_name(jenna,Name) :- Name=clara.
Explanation:
Given a query, Prolog looks for an appropriate predicate according to the input parameters and the name and "executes" it. The result is either true/false if no output parameter is given. In this case there is one (Name) which can be seen from the leading capital letter. Note that there are two possible ways to implement this. The former is probably the most common (predicates of this form are called "facts" whereas predicates such as the lower are called "rules").
2:
As mentioned in my comment, I don't really understand the connection between the two given predicates. Also it feels like there is something missing such as a facts that determine which person is on which show...
Assuming such facts are missing, I would write the Prolog program as follows:
onShow(david, s1).
onShow(clara, s1).
onShow(bernie, s2).
same_show(P1, P2) :- onShow(P1,X), onShow(P2,X).
Explanation:
The predicate is only true if both P1 and P2 visit the same show X.
Hints:
A "comma" represents a logical AND operator. Having different rules with the same name and parameter count represents logical OR. Edit: As Boris mentioned in a comment, this is not exactly true. This association simply helped me to understand the connection between "Logical Predicates" and "Prolog Predicates".
Visit SWISH to test your Prolog programs.
I am using SWI-Prolog. I have list of facts in my database:
a(r).
a(s).
a(t).
Now I want Prolog to insert a fact b(X) for any X where a(X) holds, so that I can interactively retract some fact b(s) or b(t). How can this be done?
The quick answer is:
?- forall(a(X), assert(b(X)))
However, notice that b/1 must be declared to be a dynamic predicate (i.e., a predicate whose clauses can be asserted/retracted at run-time). This is declared in the following way:
:- dynamic(b/1).
In Prolog you can write a ground fact as:
lost(jen).
You can also write a non-ground fact as:
lost(X).
Does this makes any sense? Could you show me a practical/real example where non ground facts are used?
Thanks,
Another case, avoiding lists, is where most cases are "true" and you just want to exclude some few cases that are false. So you deliberately fail thoses cases, then let everything else pass through.
Then you can do, say...
inhabited(antarctica) :- !, fail.
% all the other continents are inhabited
inhabited(_).
Well, you can have other things in facts besides atoms, for example you can have lists. Once you've done that, you may want to know about a one-element list, and you can have
oneelement([X]).
Likewise, say you want to compare what is the last element in a list
lastelement([X],X).
lastelement([_|Remainder],X) :- lastelement(Remainder,X).
The very useful member predicate is defined as
member([X|_],X).
member([_|Remainder],X) :- member(Remainder,X).
Each of these uses a non-ground fact as its base case, by matching a special form that's more specific than just lost(X)