CHR: How do you call Prolog code inside a rule - prolog

CHR: How do you call Prolog code inside a rule ?
I assume it is like DCG !!! but doesn't seem right
:- use_module(library(chr)).
:- chr_constraint move/2,pos/2, next/0.
:- [utils].
main :- pos(5,5).
rand(X,Y) :- random(0,2,X), random(0,2,Y), say("~w,~w",[X,Y]).
pos(X,Y), move(A,B) <=> pos(6,6).%X1 > 0, X1 < 10, Y1 > 0, Y1 < 10 | pos(X1,Y1), {X1 is X + A, Y1 is Y + B}.
next <=> move(X,Y), {rand(X,Y)}. <<<-----
error :
?- pos(5,5),next.
ERROR: Unknown procedure: {}/1
ERROR: In:
ERROR: [13] {rand(_35671298,_35671300)}
ERROR: [12] next___0__0(suspension(470241,removed,_35671332,0,user: ...,next)) at grid.pl:12
ERROR: [9] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
Exception: (13) {rand(_35670676, _35670678)} ? abort
% Execution Aborted
======================
this works, but have to set the position LAST !!! and cant use the GUARD !
:- use_module(library(chr)).
:- chr_constraint move/2,pos/2, next/0.
:- [utils].
rand(X,Y) :- random(0,2,X), random(0,2,Y), say("~w,~w",[X,Y]).
next <=> move(X,Y), rand(X,Y).
move(A,B),pos(X,Y) <=> X1 is X + A, Y1 is Y + B , X1 > 0, X1 < 10, Y1 > 0, Y1 < 10, pos(X1,Y1).
first generate the moves !! weird ... any time I put next after pos() it fails..
?- next,next,next,pos(5,5).
1,0
1,1
0,0
pos(7, 6).

Seems like I got it ..!! the prolog calls have to be first in this case rand() i.e.
next <=> rand(X,Y), move(X,Y).
except the guard, still cant use the updated values ... probably cause they are calculated afterwards.

Related

Prolog: Multiplication(X,Y)

double(X, Y) :-
X is Y/2, Y is X*2.
I'm trying to execute this but its given error always
Arguments are not sufficiently instantiated
In:
[2] 4 is _1604/2
[1] double(4,_1662) at line 2
how can I get double of two variables.
You are trying to make a bidirectional procedure, where at least one of the parameters is instantiated.
You may use CLP(fd) like this:
double(X, Y):- Y #= X*2.
Note this will only work with integer values, so for example
?- double(2, Y).
Y = 4.
?- double(X, 4).
X = 2.
but
?- double(2.5, Y).
ERROR: Domain error: `clpfd_expression' expected, found `2.5'
ERROR: In:
ERROR: [14] throw(error(domain_error(clpfd_expression,2.5),_2162))
ERROR: [11] clpfd:parse_clpfd(2.5*2,_2200) at c:/swi/swi8/library/clp/clpfd.pl:7359
ERROR: [9] clpfd:clpfd_equal(_2236,2.5*2) at c:/swi/swi8/library/clp/clpfd.pl:2795
ERROR: [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
?- double(X, 5).
false.
or if you want to use is/2 then you should make sure that the right hand side of is/2 is bound to an number, for example like this:
double(X, Y) :-
( number(X)
-> Y is X*2
; number(Y)
-> X is Y/2
).
The procedure using CLP(fd) is clearly more powerful as it does not require the right hand arithmetic expression to be instantiated prior to issue the constraint, and thus allows queries like double(X,Y) to succeed (giving the remaining constraints upon querying).
You may also try CLP(r) which works over reals:
:- use_module(library(clpr)).
double(X, Y):- { Y=X*2 }.
sample runs:
?- double(2, Y).
Y = 4.
?- double(X, 4).
X = 2.
?- double(2.5, Y).
Y = 5.0.
?- double(X, 5).
X = 2.5.

Prolog clpfd :: operator expected

Dear Stackoverflow Community,
I just wanted to test out the constrained logic programming library (clpfd) for Prolog.
So I am including the library by calling
:- use_module(library(clpfd)).
Then I want to do sth like the following.
[X,Y] :: [1..2], X #\= Y, X+Y #\= 3.
But I always get the answer that
ERROR: Syntax error: Operator expected
ERROR: [X,Y]
ERROR: ** here **
ERROR: :: [1..2], X #\= Y, X+Y #\= 3 .
The same happens when executing the following example
? member(X,[42,1,17]), [X,Y] :: [0..20].
ERROR: Syntax error: Operator expected
ERROR: member(X,[42,1,17]), [X,Y]
ERROR: ** here **
ERROR: :: [0..20] .
Seems like Prolog does not recognise the :: operator properly.
Any help is appreciated
As far as I know, there is no (::)/2 predicate in the clpfd library. You are probably looking for the ins/2 predicate. For example:
?- [X,Y] ins 1..2, X #\= Y, X+Y #\= 3, label([X,Y]).
false.
?- [X,Y] ins 1..3, X #\= Y, X+Y #\= 3, label([X,Y]).
X = 1,
Y = 3 ;
X = 2,
Y = 3 ;
X = 3,
Y = 1 .
So if X and Y are in 1..2, then there is no solution, since your first constraint says X should be different from Y, and the second constraint says that X + Y should be different from 3.
In case we add 3 to the result, then there are solutions.
We can here use ins/2 to filter as well:
?- member(X,[42,1,17]), [X,Y] ins 0..20.
X = 1,
Y in 0..20 ;
X = 17,
Y in 0..20.

PROLOG Stack overflow recursive multiply

multiply(A,0,0).
multiply(A,B,C) :- D is B-1, multiply(A,D,E), C is E+A.
After using this rule once and Prolog returns an answer, if I want it to continue searching (prompts A = 5 ? and I hit ;), Prolog crashes. I don't understand why? Would anyone be able to explain. Thank you.
The problem is,
multiply(A,B,C) :- D is B-1, multiply(A,D,E), C is E+A.
This code does not have the constraint B > 0 that would prevent the stack overflow from occurring.
You can modify the code as,
multiply(A,B,C) :- B > 0, D is B-1, multiply(A,D,E), C is E+A.
Also, this line multiply(A,0,0). gives a singleton warning, so you can possibly change it into multiply(_,0,0)
Note : I wrote the constraint B > 0 thinking that you call the predicate as multiply(5,1,A).
Here is how you can make an endless loop easily:
?- [user].
|: loop(0).
|: loop(X) :- X0 is X - 1, loop(X0).
|: ^D% user://1 compiled 0.01 sec, 2 clauses
true.
?- loop(3).
true ;
After you redo (when you press ;) you backtrack into the second clause with a 0.
Then X0 becomes -1, you go into the recursive loop(X0), and from here on the first clause will never again match.
Try for example querying:
?- loop(-1).
Your version of the infinite loop is not tail-recursive, which means that it will use up the stack eventually. Here is a minimal example:
?- [user].
|: out_of_stack(0, 0).
|: out_of_stack(X, Y) :- X0 is X - 1, out_of_stack(X0, Y0), Y is Y0 + 1.
|: ^D% user://1 compiled 0.01 sec, 2 clauses
true.
?- out_of_stack(3, R).
R = 3 ;
ERROR: Stack limit (1.0Gb) exceeded
ERROR: Stack sizes: local: 1.0Gb, global: 19Kb, trail: 1Kb
ERROR: Stack depth: 11,183,864, last-call: 0%, Choice points: 3
ERROR: Possible non-terminating recursion:
ERROR: [11,183,864] user:out_of_stack(-11183853, _5046)
ERROR: [11,183,863] user:out_of_stack(-11183852, _5066)
So this is what is happening and why Prolog crashes.
To get rid of the problem, do as other have suggested. The other solution is to use 0, s(0), s(s(0)), ... to represent natural numbers.

what is wrong with the following prolog program

I made the following program, which is this:
eval([],_,_).
eval([(U, V)| Tail], X, Y):-
Y + evaluate([Tail], X, Y), Y is U * (X ** V).
it returns false, and I dont know why. How can I fix it?
So this eval([(4,3), 4, X) should return 256.
and eval([(4,3),(1,0)], 4, X). should return 257.
Now I get this error"
ERROR: Undefined procedure: (+)/2
ERROR: In:
ERROR: [9] _5562+eval([...],4,_5572)
ERROR: [8] eval([(4,3),...],4,_5606) at c:/users/parya lotfi/desktop/exe2.pl:2
ERROR: [7] <user>
eval([], _,0).
eval([(U,V)|UVs], X, Y0) :-
eval(UVs, X, Y1),
Y0 is Y1 + U*X^V.
?- eval([(4,3),(1,0)], 4, X).
X = 257.

Syntax error in prolog

I am trying to write the following formula into swi prolog but get an error,
Here is the code/query I am typing
[X, Y, Z] ins 0 .. 4, X #= Y + 1.
and here is the error I am getting
ERROR: Syntax error: Operator expected
ERROR: [X, Y, Z]
ERROR: ** here **
ERROR: ins 0..4, X #= Y + 1 .
Could someone let me know what I did wrong.
The problem was that I forgot to import the library [library(clpfd)] so basically had to use the following statement use_module(library(clpfd)). This was spotted by #CapelliC

Resources