Boolean assignment in Prolog - prolog

all.
I want to assign a boolean value to a variable.
I've tried stuff like.
Diagonal is (XPiece = XFinal)
Diagonal is (XPiece =:= XFinal)
Diagonal is (XPiece is XFinal)
None work...
Any solutions?

Prolog's built-in predicate is/2 evaluates the right-hand side of the expression as an arithmetic expression and unifies the result with the left-hand side.
Also, prolog doesn't have a boolean type. Prolog's built-in types are
integer
float
atom
unbound variable
compound term
You could elect to represent a boolean value as the atoms true/false (useful for readability), or you could represent a boolean value as the integer values 1/0 (useful for computation). The way most procedural languages, like C, evaluate arithmetic values as booleans is broken WRT formal logic, though: falsity is single-valued (0) and truth multi-valued (non-zero), meaning that which is not false. In formal logic, truth is single-valued and falsity is defined as that which is not true.
So you might want to consider the semantics of your representation and build some predicates to manipulate your booleans, possibly adding some operators to "extend" prolog a bit.

Use an if-then-else:
(XPiece = XFinal ->
Diagonal = true
;
Diagonal = false
)
or use 1/0, or whatever you want. Alternatively, use CLP(FD), that supports the idiom you want:
use_module(library(clpfd)).
diag(XPiece, XFinal, Diagonal) :-
Diagonal #= (XPiece #= XFinal).

What about
diagonal(XPiece, XFinal) :- XPiece = XFinal.

Related

SWI-Prolog: Write predicate union(A,B,C) in form C = A ∪ B

Is their some way in SWI-Prolog to write predicates with three variables for example union(A,B,C) in the following form C = A ∪ B. For predicates with two variables I know their are operators to do that, but I am not sure if their is something similar in that case.
No.
Not directly. Prolog only supports defining unary operators (prefix/suffix operators such as -- 32 or 32 ++, both of which correspond to '--'/1 or '++'/1) and infix operators (e.g. X is Y which corresponds to is/2).
If you look at the operator definitions and precedences, you would need to define your union operator as an infix operator with a precedence of less than 700.
Then, reading a term like x = y ∪ z would yield '='( x , '∪'(y,z) ).
Another way to do it would be to write a DCG (definite clause grammar) to parse the text as desired. See this tutorial: https://www.metalevel.at/prolog/dcg

What's the difference between functor, a fact, a predicate and a rule in Prolog?

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.

Prolog - subsitution and evaluation

Hello good people of programming .
Logic programming is always fascinating compare to imperative programming.
As pursuing unknown of logic programming, there is some problems encountering arithmetic expressions.
Here is the code I have done so far.
number_atom(N) :-
(number(N) -> functor(N, _, _); functor(N, _, _), atom(N)).
arithmeticAdd_expression(V,V,Val,Val).
arithmeticAdd_expression(N, _Var, _Val, N) :-
number_atom(N).
arithmeticAdd_expression(X+Y, Var, Val, R) :-
arithmeticAdd_expression(X, Var, Val, RX),
arithmeticAdd_expression(Y, Var, Val, RY),
(number(RX), number(RY) -> R is RX + RY; R = RX + RY).
Taking add operation as example:
arithmeticAdd_expression(Expression, Variable, Value, Result)
?- arithmeticAdd_expression(a+10, a, 1, Result).
?- Result = 11;
?- Result = a + 10.
?- arithmeticAdd_expression(a+10, b, 1, Result).
?- Result = a + 10.
What I would like to achieve is that
if the atom(s) in the Expression can only be substituted by given Variable and value, then Result is the number only like the example shown above(Result = 11). Else, the Result is the Expression itself only. My problem with the code is somewhere there, I just could figure it out. So, Please someone can help me? Thank you.
An important attraction of logic programming over, say, functional programming is that you can often use the same code in multiple directions.
This means that you can ask not only for a particular result if the inputs are given, but also ask how solutions look like in general.
However, for this to work, you have to put some thought into the way you represent your data. For example, in your case, any term in your expression that is still a logical variable may denote either a given number or an atom that should be interpreted differently than a plain number or an addition of two other terms. This is called a defaulty representation because you have to decide what a variable should denote by default, and there is no way to restrict its meaning to only one of the possible cases.
Therefore, I suggest first of all to change the representation so that you can symbolically distinguish the two cases. For example, to represent expressions in your case, let us adopt the convention that:
atoms are denoted by the wrapper a/1
numbers are denoted by the wrapper n/1.
and as is already the case, (+)/2 shall denote addition of two expressions.
So, a defaulty term like b+10 shall now be written as: a(b)+n(10). Note the use of the wrappers a/1 and n/1 to make clear which case we are dealing with. Such a representation is called clean. The wrappers are arbitrarily (though mnemonically) chosen, and we could have used completely different wrappers such as atom/1 and number/1, or atm/1 and nmb/1. The key property is only that we can now symbolically distinguish different cases by virtue of their outermost functor and arity.
Now the key advantage: Using such a convention, we can write for example: a(X)+n(Y). This is a generalization of the earlier term. However, it carries a lot more information than only X+Y, because in the latter case, we have lost track of what these variables stand for, while in the former case, this distinction is still available.
Now, assuming that this convention is used in expressions, it becomes straight-forward to describe the different cases:
expression_result(n(N), _, _, n(N)).
expression_result(a(A), A, N, n(N)).
expression_result(a(A), Var, _, a(A)) :-
dif(A, Var).
expression_result(X+Y, Var, Val, R) :-
expression_result(X, Var, Val, RX),
expression_result(Y, Var, Val, RY),
addition(RX, RY, R).
addition(n(X), n(Y), n(Z)) :- Z #= X + Y.
addition(a(X), Y, a(X)+Y).
addition(X, a(Y), X+a(Y)).
Note that we can now use pattern matching to distinguish the cases. No more if-then-elses, and no more atom/1 or number/1 tests are necessary.
Your test cases work as expected:
?- expression_result(a(a)+n(10), a, 1, Result).
Result = n(11) ;
false.
?- expression_result(a(a)+n(10), b, 1, Result).
Result = a(a)+n(10) ;
false.
And now the key advantage: With such a pure program (please see logical-purity for more information), we can also ask "What do results look like in general?"
?- expression_result(Expr, Var, N, R).
Expr = R, R = n(_1174) ;
Expr = a(Var),
R = n(N) ;
Expr = R, R = a(_1698),
dif(_1698, Var) ;
Expr = n(_1852)+n(_1856),
R = n(_1896),
_1852+_1856#=_1896 ;
Expr = n(_2090)+a(Var),
R = n(_2134),
_2090+N#=_2134 .
Here, I have used logical variables for all arguments, and I get quite general answers from this program. This is why I have used clpfd constraints for declarative integer arithmetic.
Thus, your immediate issue can be readily solved by using a clean representation, and using the code above.
Only one very small challenge remains: Maybe you actually want to use a defaulty representation such as c+10 (instead of a(c)+n(10)). The task you are then facing is to convert the defaulty representation to a clean one, for example via a predicate defaulty_clean/2. I leave this as an easy exercise. Once you have a clean representation, you can use the code above without changes.

swi-prolog truth assignment?

So I have this exercise that I'm stuck on:
A formula is:
tru
fls
variable(V) iff V is an atom.
or(Flist) iff every element in the list is a formula
there are implies, and, neg too. the form looks similar.
We can represent a truth assignment (an assignment of values to variables) by a Prolog list of the form [Var1/Value1, Var2/Value2,...VarN/ValueN]. Write a predicate sub(?F,?Asst,?G) which succeeds iff G is a formula which is a result of substituting the variables of F with corresponding values from the assignment Asst. (You can assume that the truth assignment A is at least partially instantiated).
E.g.
sub(variable(x), [x/tru], tru).
true
sub(or([variable(a),variable(b)]), [a/tru,b/fls], G).
G = or(tru,fls)
true
I've tried
sub(variable(x),[x/value],G):-
G = variable(value).
But it just returns false.
Edit: Sorry I didn't make the question clear, Can someone explain to me if there's a way to assign values associated with variables in a list to another variable? I think it has something to do with unification.
Variables are placeholders.
Beware of case sensitivity: Prolog variable names start with an uppercase character or underscore, atoms with a lowercase character.
Your code snippet of sub/3 assumes that the list of
key-value pairs has exactly a length of one ([x/value]).
By using member/2 the lists can have arbitrary length.
When handling n-ary logical connectives like and / or, you probably want a short-circuit implementation that returns as soon as possible. Like so:
sub(tru,_,tru).
sub(fls,_,fls).
sub(variable(X),Assoc,Value) :-
member(X/Value,Assoc).
sub(or([]),_,fls).
sub(or([X|Xs]),Assoc,V) :-
sub(X,Assoc,T),
( T = tru, V = tru % short-circuit logical-or
; T = fls, sub(or(Xs),Assoc,V)
).

What does the bitwise negation operator(\) do in prolog?

I have to implement some functions, one of which is f= ~p/\~q.
I have the following :
p(a). p(b).
q(a). q(b). q(c).
I found the function as:
f(X):-p(\X);q(\X).
When I verify it ( f(X). , f(a). , f(b). , f(c). ) it always returns false.
Shouldn't it return true for c since c is not of type p?
Thank you!
(\)/1 is an evaluable functor for bitwise complement. If you use it directly in an argument, it is only an uninterpreted functor. Evaluation is only performed with (is)/2, (>)/2 and other comparison operators.
In all current Prolog implementations you get:
?- X is \ 1.
X = -2.
Fine print: An ISO conforming system is free to define the value for \. That is, it is free, whether it uses 2's complement or another representation. However, there are only systems that use 2's complement.
Your implementation of that formula seems flawed.
You are required about f : (not p) and (not q)
A restricted negation is available in Prolog, using operator (\+)/1, and conjunction (X and Y) is expressed by comma i.e. (,)/2.
Semicolon i.e. (;)/2 means or, as for instance in the following test, that shows your initial assumption about f(c) is also wrong.
?- forall(member(X,[a,b,c,d]),(f(X)->writeln(y);writeln(n))).
n
n
n
y
(of course, after f/1 has been translated correctly)

Resources