I am trying to make an expression simplifier in Prolog, but one part has me stuck.
What I want to happen is simplify(x*(4*x),R). evalutes to simplify(x*4*x,R). then the rest will work its magic. But I can't seem to remove the parens. Here is the evaluation code below
simplify(x,x).
simplify(C*x,C*x) :- atomic(C),number(C),C\==1,C\==0.
simplify(x*C*x,W):- atomic(C),number(C), simplify(C*x^2,W).
simplify(C*x^N,C*W) :- atomic(C),number(C),atomic(N),number(N), simplify(x^N,W).
simplify(x^1,x).
simplify(x^N,x^N) :- atomic(N),number(N),N \== 1.
simplify(U*(V),R2):- simplify(U,U1),simplify(V,V1),simplify(U1*V1,R2).%why will it not return a paren less output
simplify(U*V,R2):- simplify(U,U1),simplify(V,V1),simplify(U1*V1,R2).
Parenthesis are used to change a term interpretation in the presence of operators. Note that, for the Prolog parser, there's no distinction between simplify(U*(V),R2) and simplify(U*V,R2):
| ?- write_canonical(simplify(U*(V),R2)).
simplify(*(_279,_280),_284)
yes
| ?- write_canonical(simplify(U*V,R2)).
simplify(*(_279,_280),_284)
yes
Thus, the last two clauses have the same head; there's a single operator in the U*(V) term.
Now consider the goal simplify(x*(4*x),R). The operator definition for (*)/2 is:
| ?- current_op(Priority, Type, *).
Priority = 400
Type = yfx
yes
I.e. the operator is left-associative. This means that e.g. a*b*c is parsed as *(*(a,b),c). Therefore:
| ?- write_canonical(simplify(x*(4*x),R)).
simplify(*(x,*(4,x)),_285)
yes
| ?- write_canonical(simplify(x*4*x,R)).
simplify(*(*(x,4),x),_285)
yes
Related
I am working on a prolog problem and need some help here.
/*Write a predicate listtran(L,E) which translates a list of Latin number words
* to the corresponding list of English number words. */
%% predicate
listtran(L,E).
%% clauses
tran(unus,one).
tran(duo,two).
tran(tres,three).
tran(quattuor,four).
tran(quinque,five).
tran(sex,six).
tran(septem,seven).
tran(octo,eight).
tran(novem,nine).
%% rules
% base case: empty list
listtran([], []).
% inductive cases:
listtran([L | T0], [E | T1]) :-
tran(L, E), % translate the head of the list
listtran(T0, T1). % translate the tail of the list, using recursion
What is needed to be written in predicates and query to test:
?- listtran([unus,novem,duo],X).
should give:
X = [one,nine,two].
and
?- listtran(X,[one,seven,six,two]).
it should return:
X = [unus,septem,sex,duo].
Also, what can be done to avoid the error message:
Clauses of listtran/2 are not together in the source-file
Thanks!
That is a discontigous predicate error.
Prolog is complaining that all the clauses of a predicate are not defined in one place. You should just delete the listtrans(L, E).(why is it even there?) at the start and the rest should work fine.
An explanation of the error: https://stackoverflow.com/a/40614467/4437190
For some reason, these two pieces of code aren't equivalent, with the first producing very strange (and incorrect results).
-- Method 1
highestElement1([],A,A).
highestElement1([H|T],A,Max) :-
H > A,
highestElement1(T,H,Max);
highestElement1(T,A,Max).
-- Method 2
highestElement2([],A,A).
highestElement2([H|T],A,Max) :-
H > A,
highestElement2(T,H,Max).
highestElement2([H|T],A,Max) :-
H =< A,
highestElement2(T,A,Max).
From my understanding, they should be identical, as I believe(d) that pattern matching and 'or' are basically syntatic sugar for one another. Is this not the case?
Method1 is actually equivalent to:
highestElement2([],A,A).
highestElement2([H|T],A,Max) :-
H > A,
highestElement2(T,H,Max).
highestElement2([H|T],A,Max) :-
highestElement2(T,A,Max).
This is due to the relative priorities of the (,)/2 and (;)/2 operators:
| ?- current_op(Priority, Type, ',').
Priority = 1000
Type = xfy
yes
| ?- current_op(Priority, Type, ';').
Priority = 1100
Type = xfy
yes
I.e. the second clause of highestElement1 is parsed as:
highestElement1([H|T],A,Max) :-
(H > A, highestElement1(T,H,Max))
;
highestElement1(T,A,Max).
One way to visualize how a term is parsed if we're not sure about operator notation is to use the standard write_canonical/1 built-in predicate:
| ?- write_canonical((a :- b,c; d)).
:-(a,;(','(b,c),d))
(1 ms) yes
The output tells us that we have a compound term with name :- and two arguments, a and ;(','(b,c),d). The second argument is also a compound term with name ; and two arguments, ','(b,c) and d.
I would like to know the difference between those terms :
facts
functor
predicate.
rule
in Prolog.
if I write: brother(john, jack).
is that a fact? or a predicate?
To address your given example:
brother(john, jack).
^ ^ ^
functor | |
argument |
argument
\________ ________/
\/
fact/predicate
brother/2 is a predicate AND a fact as well (see 3.72 fact in #GuyCoder's quote from the standard) since you can write it as a clause with a body that consists of the single goal true:
brother(john, jack) :- % <- head of the clause
true. % <- body of the clause
The predicate brother in your example has two arguments, therefore the arity 2 and is referred to as brother/2 (see 3.129 predicate in #GuyCoder's post). The name or identifier of the predicate brother/2 is also called the functor of the predicate (see 3.77 functor; note that 3.77 and 3.129 use the same definition). You can think of a fact as a special kind of predicate that you can define without rules.
If you had some facts parent_of/2 and male/2 and defined a predicate brother_of/2 based on those, e.g...
brother_of(X,Y) :- % X is brother of Y if
dif(X,Y), % X and Y are different AND
male(X), % X is male AND
parent_of(P,X), % X has a parent P AND
parent_of(P,Y). % Y has the same parent P
... then the above definition constitutes a rule because the body of the clause is not the goal true (see 3.154 rule). The rule above consists of the following parts:
brother_of(X,Y) :- % head of the rule
dif(X,Y), % goal \
male(X), % goal \ body of
parent_of(P,X), % goal / the rule
parent_of(P,Y). % goal /
The head of the rule is followed by :- which is an implication arrow pointing towards the head of the rule and the goals are separated by , which is a logical AND (conjunction). So the body of a rule consists of a single goal or a conjunction of goals and the body of a rule implies the head of the rule. Hence you can read the above definition of brother_of/2 as a logic formula:
brother_of(X,Y) ← dif(X,Y) ∧ male(X) ∧ parent_of(P,X) ∧ parent_of(P,Y)
If you come from mathematical logic you might find it helpful to recall that a predicate is defined as a boolean-valued function, that is, a function that maps its arguments to true or false. So a predicate is the characteristic function of a relation (see Predicate (mathematical logic). Since you can query facts and get true/false as an answer, they constitute predicates. You can observe this when you query your definition of brother/2:
?- brother(john,jack).
true. % <- maps to true
?- brother(john,jason).
false. % <- maps to false
If you issue queries with variables, you get substitutions for said variables that make the predicate true instead of the answer true, e.g.:
?- brother(X,Y).
X = john, % these substitutions for X and Y
Y = jack. % map to true
A final remark: When talking about Prolog the terms predicate and relation are often used interchangeably and it is quite helpful to think about writing predicates as describing relations (see the comments in the definition of brother_of/2 above). Hence, for the above queries it is also appropriate to say: The relation brother(john,jack) holds. The relation brother(john,jason) does not hold. The relation brother(X,Y) holds for the substitutions X=john and Y=jack.
From
ISO/IEC 13211-1 First edition 1995-06-01
Information technology - Programming languages - Prolog -
Part 1:
General Core
3.9 arity: The number of arguments of a compound term. Syntactically, a non-negative integer associated with a functor or predicate.
3.19 body: A goal, distinguished by its context as part
of a rule (see 3.154).
3.32 clause: A fact or a rule. It has two parts: a head,
and a body.
3.37 compound term: A functor of arity N, N positive, together with a sequence of N arguments.
3.72 fact: A clause whose body is the goal true.
NOTE - A fact can be represented in Prolog text by a term
whose principal functor is neither (:-)/1 nor (:-)/2.
3.77 functor: An identifier together with an arity.
3.81 goal: A predication which is to be executed (see
body, query, and 7.7.3).
3.84 head (of a rule): A predication, distinguished by its context.
3.88 identifier: A basic unstructured object used to denote an atom, functor name or predicate name.
3.129 predicate: An identifier together with an arity.
3.133 predication: A predicate with arity N and a
sequence of N arguments.
3.143 query: A goal given as interactive input to the
top level.
3.154 rule: A clause whose body is not the goal true.
During execution, if the body is true for some substitution,
then the head is also true for that substitution. A rule
is represented in Prolog text by a term whose principal
functor is (:-)/2 where the first argument is converted
to the head, and the second argument is converted to the
body.
So brother(john, jack). is a fact.
The difference between a term and a predicate (or goal) can be subtle. They look the same and are distinguished by context. For example:
foo(1).
foo(2).
foo_results(Results) :- setof(X, foo(X), Results).
?- foo_results(Results).
Results = [1, 2].
The predicate foo/1 has two clauses. The predicate foo_results/1 calls this, but indirectly ... the setof/3 meta-predicate takes a term as its second argument, which it interprets as a predicate. In other words, a functor (name/arity) is the skeleton of a kind of term; some meta-predicates (e.g., call/1, setof/3, etc.) can interpret a term (functor/arity) as a predicate.
A fact is a predicate expression that makes a declarative statement about the problem domain.
likes(john, mary).
A rule is a predicate expression that uses logical implication (:-) to describe a relationship among facts. A rule could be
left :- right.
friends(X,Y) :- likes(X,Y),likes(Y,X).
Both facts and rules are predicates.
So for your question, brother(john, jack) is a fact.
Can anybody explain the following code? I know it returns true if X is left of Y but I do not understand the stuff with the pipe, underscore and R. Does it mean all other elements of the array except X and Y?
left(X,Y,[X,Y|_]).
left(X,Y,[_|R]) :- left(X,Y,R).
If you are ever unsure about what a term "actually" denotes, you can use write_canonical/1 to obtain its canonical representation.
For example:
| ?- write_canonical([X,Y|_]).
'.'(_16,'.'(_17,_18))
and also:
| ?- write_canonical([a,b|c]).
'.'(a,'.'(b,c))
and in particular:
| ?- write_canonical([a|b]).
'.'(a,b)
This shows you that [a|b] is the term '.'(a,b), i.e., a term with functor . and two arguments.
To reinforce this point:
| ?- [a|b] == '.'(a,b).
yes
#mat answered the original question posted quite precisely and completely. However, it seems you have a bigger question, asked in the comment, about "What does the predicate definition mean?"
Your predicate, left(X, Y, L), defines a relation between two values, X and Y, and a list, L. This predicate is true (a query succeeds) if X is immediately left of Y in the list L.
There are two ways this can be true. One is that the first two elements in the list are X and Y. Thus, your first clause reads:
left(X, Y, [X,Y|_]).
This says that X is immediately left of Y in the list [X,Y|_]. Note that we do not care what the tail of the list is, as it's irrelevant in this case, so we use _. You could use R here (or any other variable name) and write it as left(X, Y, [X,Y|R]). and it would function properly. However, you would get a singleton variable warning because you used R only once without any other references to it. The warning appears since, in some cases, this might mean you have done this by mistake. Also note that [X,Y|_] is a list of at least two elements, so you can't just leave out _ and write [X,Y] which is a list of exactly two elements.
The above clause is not the only case for X to be immediately left of Y in the list. What if they are not the first two elements in the list? You can include another rule which says that X is immediately left of Y in a list if X is immediately left of Y in the tail of the list. This, along with the base case above, will cover all the possibilities and gives a complete recursive definition of left/3:
left(X, Y, [_|R]) :- left(X, Y, R).
Here, the list is [_|R] and the tail of the list is R.
This is about the pattern matching and about the execution mechanism of Prolog, which is built around the pattern matching.
Consider this:
1 ?- [user].
|: prove(T):- T = left(X,Y,[X,Y|_]).
|: prove(T):- T = left(X,Y,[_|R]), prove( left(X,Y,R) ).
|:
|: ^Z
true.
Here prove/1 emulates the Prolog workings proving a query T about your left/3 predicate.
A query is proven by matching it against a head of a rule, and proving that rule's body under the resulting substitution.
An empty body is considered proven right away, naturally.
prove(T):- T = left(X,Y,[X,Y|_]). encodes, "match the first rule's head. There's no body, so if the matching has succeeded, we're done."
prove(T):- T = left(X,Y,[_|R]), prove( left(X,Y,R) ). encodes, "match the second rule's head, and if successful, prove its body under the resulting substitution (which is implicit)".
Prolog's unification, =, performs the pattern matching whilst instantiating any logical variables found inside the terms being matched, according to what's being matched.
Thus we observe,
2 ?- prove( left( a,b,[x,a,b,c])).
true ;
false.
3 ?- prove( left( a,b,[x,a,j,b,c])).
false.
4 ?- prove( left( a,b,[x,a,b,a,b,c])).
true ;
true ;
false.
5 ?- prove( left( a,B,[x,a,b,a,b,c])).
B = b ;
B = b ;
false.
6 ?- prove( left( b,C,[x,a,b,a,b,c])).
C = a ;
C = c ;
false.
The ; is the key that we press to request the next solution from Prolog (while the Prolog pauses, awaiting our command).
I've just started experimenting with Prolog, and I was trying to write a rule to find out whether a list contained only unique elements. I got it working in the second variation (by negating a positive test), but I've completely failed to understand why the first variation doesn't work.
Given this file:
uniqueElements([X|Y]) :-
notmember(X, Y),
uniqueElements(Y).
notmember(X, Y) :-
\+ member(X, Y).
hasRepeatedElements([X|Y]) :-
(
member(X, Y) ->
true
; hasRepeatedElements(Y)
).
uniqueElements_2(X) :-
\+ hasRepeatedElements(X).
The GNU Prolog interpreter gives these responses:
| ?- uniqueElements([1,2,3]).
no
| ?- uniqueElements([1,2,3,2,3]).
no
| ?- uniqueElements_2([1,2,3]).
yes
| ?- uniqueElements_2([1,2,3,2,3]).
no
Why is the first response 'no'? (I would have expected member to return false, be negated to true, and thus have notmemeber return true on each iteration of uniqueElements). I guess I'm expecting '\+' to behave like '!' does in a C if clause, or the 'not' keyword in Python. Is this a misunderstanding?
In uniqueElements, you haven't provided the base case for the recursion:
uniqueElements([]).
Without that clause, when a particular call chain gets to the empty list case, it doesn't find any applicable clauses, which means fail in Prolog. Meaning, "unprovable". So, your call uniqueElements([1,2,3]) has produced an equivalent of true && true && true && false.
Now it should work.
hasRepeatedElements doesn't have a clause defined for the base case either, but its failure in finding whether there were repeated elements in an empty list [] is consistent with its semantics - it should have found that there are no repeated elements in empty list, in the first place.
In Prolog, "not" means "can't prove that ...".