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

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

Related

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)

Prolog 'is/2' predicate implementation

How is the 'is/2' Prolog predicate implemented?
I know that
X is 3*4
is equivalent with
is(X, 3*4)
But is the predicate implemented using imperative programming?
In other words, is the implementation equivalent with the following C code?
if(uninstantiated(x))
{
X = 3*4;
}
else
{
//signal an error
}
Or is it implemented using declarative programming and other predicates?
Depends on your Prolog, obviously, but any practical implementation will do its dirty work in C or another imperative language. Part of is/2 can be simulated in pure Prolog:
is(X, Expr) :-
evaluate(Expr, Value),
(var(X) ->
X = Value
;
X =:= Value
).
Where evaluate is a huge predicate that knows about arithmetic expressions. There are ways to implement large parts of it in pure Prolog too, but that will be both slow and painful. E.g. if you have a predicate that adds integers, then you can multiply them as well using the following (stupid) algorithm:
evaluate(X + Y, Value) :-
% even this can be done in Prolog using an increment predicate,
% but it would take O(n) time to do n/2 + n/2.
add(X, Y, Value).
evaluate(X * Y, Value) :-
(X == 0 ->
Value = 0
;
evaluate(X + -1, X1),
evaluate(X1, Y, Value1),
evaluate(Y + Value1, Value)
).
None of this is guaranteed to be either practical or correct; I'm just showing how arithmetic could be implemented in Prolog.
Would depend on the version of Prolog; for example, CProlog is (unsurprisingly) written in C, so all built-in predicates are implemented in a imperative language.
Prolog was developed for language parsing. So, a arithmetic expression like
3 + - ( 4 * 12 ) / 2 + 7
after parsing is just a prolog term (representing the parse tree), with operator/3 providing the semantics to guide the parser's operation. For basic arithmetic expressions, the terms are
'-'/2. Negation
'*'/2, '/'/2. Multiplication, division
'+'/2, '-'/2. Addition, subtraction
The sample expression above is parsed as
'+'( '+'( 3 , '/'( '-'( '*'(4,12) ) , 2 ) ) , 7 )
'is'/2 simply does a recursive walk of the parse tree representing the right hand side, evaluating each term in pretty much the same way an RPN (reverse polish notation) calculator does. Once that expression is evaluated, the result is unified with the left hand side.
Each basic operation — add, subtract, multiply, divide, etc. — has to be done in machine code, so at the end of the day, some machine code routine is being invoked to compute the result of each elemental operation.
Whether is/2 is written entirely in native code or written mostly in prolog, with just the leaf operations written in native code, is pretty much an implementation choice.

About Prolog syntax

Sometimes I see terms like:
X = a:b
or
X = a-b
I can do requests like
X = Y:Z
and the compiler unifies Y with a and Z with b, as expected.
Now my answer:
Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!
Maybe you can give me some links with further informations about this issue.
Thanks for your help and kind regards from Germany
Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!
What you are asking here for, is the entire operator syntax definition of Prolog. To get the very full answer to this, please refer to the tag iso-prolog for full information how to obtain the Prolog standard ISO/IEC 13211-1.
But as a short answer to start with:
Prolog syntax consists of
functional notation, like +(a,b), plus
a dynamically redefinable operator syntax, plus
some extra.
It seems you want to know which "characters" can be used as operators.
The short answer is that you can use all atoms Op that succeed for current_op(Pri,Fix,Op). So you can ask dynamically, which operators are present:
?- current_op(Pri, Fix, Op).
Pri = 1, Fix = fx, Op = ($)
; Pri = 1150, Fix = fx, Op = (module_transparent)
; Pri = 700, Fix = xfx, Op = (=#=)
; Pri = 700, Fix = xfx, Op = (#>=)
; Pri = 700, Fix = xfx, Op = (>=)
; ... .
All those operators can be used in the specified manner, as pre-, in-, or postfix with the indicated priorities. Some of these operators are specific to SWI, and some are defined by the standard. Above, only #>= and >= are standard operators.
Most of the operators consist of the graphic characters #$&*+-./:<=>?#^~ only or of letters, digits and underscores starting with a lower case letter. There are two solo characters !; and then there are ,| which are even more special. Operator names that are different to above need quoting - you rarely will encounter them.
To see how operators nest, use write_canonical(Term).
The long answer is that you are also able to define such operators yourself. However, be aware that changing the operator syntax has often many implications that are very difficult to fathom. Even more so, since many systems differ in some rarely used configurations. For example, the system you mentioned, SWI differs in several ways.
I'd suggest to avoid defining new operators until you have learned more about the Prolog language.
let's see what's inside X = Y:Z
?- display( X = Y:Z ).
=(_G3,:(_G1,_G2))
true.
then we have a nested structure, where functors are operators.
An operator is an atom, and the rule for atom syntax says that we have 3 kind to consider:
a sequence of any printable character enclosed in single quote
a sequence of special characters only, where a special character is one of `.=:-+*/><##~? (I hope I have found all of them, from this page you can check if I forgot someone !)
a sequence of lowercase/uppercase characters or the underscore, starting with a lowercase character
edit
A functor (shorthand for function constructor, I think, but function is misleading in Prolog context) it's the symbol that 'ties' several arguments. The number of arguments is named arity. In Prolog a term is an atomic literal (like a number, or an atom), or a recursive structure, composed of a functor and a number of arguments, each being a term itself (at least 1).
Given the appropriate declaration, i.e. op/3, unary and binary terms can be represented as expressions, like that one you show.
An example of operator, using the : special char, is ':-'
member(X,[X|_]).
member(X,[_|T]) :- member(X, T).
The O.P., said (and I quote):
Sometimes I see terms like: X = a:b or X = a-b
I can do requests like X = Y:Z and the compiler unifies Y with a and Z with b, as expected.
Now my answer: Which characters (or sequence of characters) am I allowed
to use to combine two Prolog atoms?!
The short answer is Pretty much whatever you want (provided it is an atom).
The longer answer is this:
What are seeing are infix (x infix_op b), prefix (pfx_op b) and suffix (b sfx_op ) operators. Any structure with an arity of 2 can be an infix operator. Any structure with an arity of 1 can be a prefix or suffix operator. As a result, any atom may be an operator.
Prolog is parsed via a precedence driven, recursive descent parser (written in Prolog, naturally). Operators are defined and enumerated, along with their precedence and associativity in the operator/3 predicate. Associativity has to do with how the parse tree is constructed. An expression like a - b - c could be parsed as ( a - ( b - c ) ) (right-associative), or ( ( a - b ) - c ) (left-associative).
Precedence has to do with how tightly operators bind. An expression like a + b * c binds as ( a + ( b * c ) not because of associativity, but because '*'/2 (multiplication) has higher precedence that '+'/2 (addition).
You can add, remove and change operators to your heart's content. Not that this gives you a lot of room to shoot yourself in the foot by breaking prolog's syntax.
It should be noted, however, that any operator expression can also be written via ordinary notation:
a + b * c
is exactly identical to
'+'( a , '*'(b,c) )

Boolean assignment in 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.

Resources