Arguments are not sufficiently instantiated with prolog clpfd - prolog

I am working with CLPFD and I cannot seem to get rid of the error:
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [16] throw(error(instantiation_error,_9234))
ERROR: [12] clpfd:drep_to_domain(_9270..15,_9266) at /usr/lib/swi-prolog/library/clp/clpfd.pl:3652
ERROR: [11] clpfd:clpfd_in(_9302,_9308..15) at /usr/lib/swi-prolog/library/clp/clpfd.pl:1608
ERROR: [10] computeShapeBelow([[circle|...],6|...],[[diamond|...],_9370|...])
Below is my program and it is clear to me that Dim1 and Dim2 which come from nth0/3 are causing Prolog to throw this error. How can I work around this? I cannot find a way to apply the solutions I have seen here on StackOverflow with CLPFD
:- use_module(library(clpfd)).
computeShapeBelow(Shape1,Shape2) :-
nth0(2,Shape1,Location1),
nth0(2,Shape2,Location2),
nth0(1,Shape1,Dim1),
nth0(1,Shape2,Dim2),
nth0(0,Location1,Xcord1),
nth0(0,Location2,Xcord2),
nth0(1,Location1,Ycord1),
nth0(1,Location2,Ycord2),
XlowerLimit1 #= Dim1,
XupperLimit1 #= 20-Dim1,
YlowerLimit1 #= Dim1,
YupperLimit1 #= 15-Dim1,
XlowerLimit2 #= Dim2,
XupperLimit2 #= 20-Dim2,
YlowerLimit2 #= Dim2,
YupperLimit2 #= 15-Dim2,
Ycord1 in YlowerLimit1..YupperLimit1,
Ycord2 in YlowerLimit2..YupperLimit2,
Xcord1 in XlowerLimit1..XupperLimit1,
Xcord2 in XlowerLimit2..XupperLimit2,
Ycord2 #> Ycord1+Dim2+Dim1,
labeling([min(Xcord1),
min(Ycord2),
max(Xcord2),
max(Ycord2)],
[Xcord1,Ycord1,Xcord2,Ycord2]).
Edit
listing(computeShapeBelow) produces the following.
computeShapeBelow(A, B) :-
nth0(2, A, C),
nth0(2, B, D),
nth0(1, A, E),
nth0(1, B, J),
nth0(0, C, Q),
nth0(0, D, R),
nth0(1, C, O),
nth0(1, D, P),
( integer(E)
-> F=E
; clpfd:clpfd_equal(F, E)
),
( integer(E)
-> G is 20-E
; clpfd:clpfd_equal(G, 20-E)
),
( integer(E)
-> H=E
; clpfd:clpfd_equal(H, E)
),
( integer(E)
-> I is 15-E
; clpfd:clpfd_equal(I, 15-E)
),
( integer(J)
-> K=J
; clpfd:clpfd_equal(K, J)
),
( integer(J)
-> L is 20-J
; clpfd:clpfd_equal(L, 20-J)
),
( integer(J)
-> M=J
; clpfd:clpfd_equal(M, J)
),
( integer(J)
-> N is 15-J
; clpfd:clpfd_equal(N, 15-J)
),
clpfd:clpfd_in(O, H..I),
clpfd:clpfd_in(P, M..N),
clpfd:clpfd_in(Q, F..G),
clpfd:clpfd_in(R, K..L),
( integer(P)
-> ( integer(O),
integer(J),
integer(E)
-> P>=O+J+E+1
; S=P,
clpfd:clpfd_geq(S, O+J+E+1)
)
; integer(O),
integer(J),
integer(E)
-> S is O+J+E+1,
clpfd:clpfd_geq(P, S)
; clpfd:clpfd_geq(P, O+J+E+1)
).

The reason for this error is your using variables as domain boundaries in (in)/2.
As a minimal example that shows the problem, consider:
?- Var in X..Y.
ERROR: Arguments are not sufficiently instantiated
For (in)/2, the domain must be ground. It is not admissible to use only partially instantiated domains.
A possible workaround for this concrete issue is using arithmetic constraints like (#>)/2 etc. instead of (in)/2. For example:
my_in(Var, Lower, Upper) :-
Lower #=< Var, Var #=< Upper.
If you use this predicate instead of (in)/2 in your code, your issue disappears. I leave figuring out how to use the predicate as a small challenge.
However, other issues will then surface. I think they should be discussed separately, in a new question.

Related

Prolog predicate works only when I send [ ] "an empty list"

getSwaps(CurrentList,InitialList,L,R) :-
CurrentList = [H,S,W|_],
Indexo is L-1,
nth0(Indexo, InitialList, ReplacingW),
nth0(StopAt , InitialList , W),
StopAtIndex is StopAt-1,
ReplacingW > W,
NewW is ReplacingW,
( not(memberx([H,S,NewW], R)) ->
NewL is L-1,
not(StopAtIndex =:= NewL),!,
appendx([[H,S,NewW]], R, NewResult),
getSwaps([H,S,W],InitialList, NewL, NewResult);
NewL is L-1,
not(StopAtIndex =:= NewL),!,
getSwaps([H,S,W],InitialList, NewL, R)
).
getSwaps(_,_,_,R) :-
printList(R).
I wrote this code in prolog, it works well when I test it with:
?- swapTwice([3,8,9],[3,8,9,10,12,14],6,[]).
but when I use a variable instead of an empty list, e.g.,
?- swapTwice([3,8,9],[3,8,9,10,12,14],6,Result).
it won't work, it just prints so many numbers starting with underscore (_32512 _32518 _32524 _32530... etc.) and won't stop until I abort execution.
I need to test it with a variable in order to use the output in other predicates.
So, what can be causing this or how can I solve it?
Add a TempResult parameter to your predicate then add another predicate that takes one less parameter and calls it, like this:
getSwaps(CurrentList,InitialList,L,R) :-
getSwaps(CurrentList,InitialList,L,[],R).
getSwaps(CurrentList,InitialList,L,TempR,R) :-
CurrentList = [H,S,W|_],
Indexo is L-1,
nth0(Indexo, InitialList, ReplacingW),
nth0(StopAt , InitialList , W),
StopAtIndex is StopAt-1,
ReplacingW > W,
NewW is ReplacingW,
(
not(memberx([H,S,NewW], TempR)) ->
NewL is L-1,
not(StopAtIndex =:= NewL),!,
appendx([[H,S,NewW]], TempR, NewResult);
NewL is L-1,
not(StopAtIndex =:= NewL),!,
NewResult = TempR
),
getSwaps([H,S,W],InitialList, NewL, NewResult, R).
getSwaps(_,_,_,R,R).

Unknown procedure card/2 in knights and knaves puzzle

I'm programming some knight and knaves puzzles using both sat/1 and a more natural language approach using the custom propositions A says B and false().
Question 3 is stated as follows:
You meet three inhabitants, A, B and C.
A says: "All three of us are knaves".
B says: "Exactly one of us is a knight".
However, in my solutions that use custom propositions for some reason prolog is giving me Unknown procedure card/2. Here's the code (see question3_again proposition).
question3(A,B,C):- sat(A =:= card([0],[A,B,C])), sat(B =:= card([1],[A,B,C])).
% Now let's make it more intuitive to work with prolog by creating our own operator:
:- op(900,xfy,says).
knight says S :- S.
knave says S :- false(S).
false(A = B) :- dif(A,B).
false( (A ; B) ) :- false(A), false(B).
false( (A , B) ) :- false(A); false(B).
question3_again(A,B,C) :- A says ( A = knave, B = knave, C = knave ),
B says ( card( [1], [A = knight, B = knight, C = knight] ) ).
I tried counting the number of knights and using this solution below instead, but it gives me incorrect answers( I added false(A #= B) :- A #\= B. so false could reason about integers):
false(A #= B) :- A #\= B.
counte(_,[],Count,Count).
counte(E,[H|T],C,Count) :- (E = H, CC is C+1 ; CC is C), counte(E,T,CC,Count).
counte(E,L,Count) :- counte(E,L,0,Count).
question3_again(A,B,C) :- counte(knight,[A,B,C],Knights),
A says ( Knights #= 0 ),
B says ( Knights #= 1 ).
Can someone give me a light?
Thank you in advance!
question3_again(A,B,C) :- A says ( A = knave, B = knave, C = knave ),
B says (permutation([A, B, C], [knave, knave, knight])).
?- question3_again(A, B, C).
A = C, C = knave,
B = knight
With permutation you will get same solution multiple times. If you want to, you can avoid that with some thing like:
one_knight(X) :- nth0(_, X, knight, [knave, knave]).
?- one_knight(X).
X = [knight, knave, knave] ;
X = [knave, knight, knave] ;
X = [knave, knave, knight] ;
false.
permutation would have given 6 choices.
Now your solution will be:
question3_again(A,B,C) :- A says ( A = knave, B = knave, C = knave ),
B says (one_knight([A, B, C])).

bagof/3 is unpredictable

I am baffled by the following results. I am using SWI-Prolog.
?- bagof(Q, (Q=A, (A=[a,_] ; A=[_,b])), X).
A = [_G16898, b],
X = [[_G16898, b]] ;
A = [a, _G16892],
X = [[a, _G16892]].
Notice that [a,_] and [_,b] are not unified to produce an answer A = [a,b], X=[[a,b],[a,b]].
Now, lets try the same with arithmetic constraints:
?- bagof(Q, (Q=A, (A in 1..5 ; A in 3..8)), X).
X = [A, A],
A in 3..5.
Strangely, this time the arithmetic constraints are taken together but there are no answers A in 1..5, X=[A] and A in 3..8, X=[A].
Now lets try this in yet another way:
?- bagof(Q, (Q=A, ((1 #=< A, A #=< 5) ; (3 #=< A, A #=< 8))), X).
X = [A],
A in 3..5 ;
X = [A],
A in 3..5.
The arithmetic constraints are combined like before, but we have two answers instead of one.
How can all this be explained?
EDIT: Some more strange results. Compare this:
?- A=[_,_], bagof(Q, K1^K2^(Q=A, (A=[a,K1] ; A=[K2,b])), X).
A = [_G16886, b],
X = [[_G16886, b]] ;
A = [a, _G16889],
X = [[a, _G16889]].
with this:
?- A=[a,b], bagof(Q, K1^K2^(Q=A, (A=[a,K1] ; A=[K2,b])), X).
A = [a, b],
X = [[a, b], [a, b]].
Thats an artefact of SWI-Prolog, which also does copy attributed variables while taking findall/3 copies. findall/3 copies are used inside bagof/3 before doing keysort/2. But the effect can already be explained by means of findall/3:
SWI-Prolog, findall/3 copies attributed variables conditions:
?- findall(A, A in 1..5, L).
L = [_3464],
_3464 in 1..5.
?- findall(A, (A in 1..5, (true; true)), L).
L = [_3762, _3768],
_3762 in 1..5,
_3768 in 1..5
Jekejeke Prolog, findall/3 does not copy attributed variables conditions:
?- findall(A, A in 1..5, L).
L = [_A]
?- findall(A, (A in 1..5, (true; true)), L).
L = [_A, _B]
Inside bagof/3, there is not only a keysort/2 step, but also step where variables are restored. In this step for SWI-Prolog, constraints might be joined, since constraints will be present.
This explains the first result in the question of the OP. The second result in the question of the OP can be explained in that SWI-Prolog does goal expansion and introduce new variables in the case of (#=<)/2. You can check yourself:
?- [user].
test(A) :- A in 1..5 ; A in 3..8.
test(A) :- (1 #=< A, A #=< 5) ; (3 #=< A, A #=< 8).
?- listing(test/1).
test(A) :-
( ( integer(A)
-> between(1, 5, A)
; clpfd:clpfd_in(A, 1..5)
)
; integer(A)
-> between(3, 8, A)
; clpfd:clpfd_in(A, 3..8)
).
test(A) :-
( ( integer(A)
-> A>=1
; B=1,
clpfd:clpfd_geq(A, B)
),
( integer(A)
-> 5>=A
; C=5,
clpfd:clpfd_geq(C, A)
)
; ( integer(A)
-> A>=3
; D=3,
clpfd:clpfd_geq(A, D)
),
( integer(A)
-> 8>=A
; E=8,
clpfd:clpfd_geq(E, A)
)
).
There are no fresh variables in the expansion of (in)/2. But I guess the fresh variables inside the (#=<)/2 expansion, then causes bagof/3 to see two solutions, instead of only one.
Edit 19.08.2019:
Now I wonder how tabling with CLP(FD) solves the problem...

How to remove every second occurrence of an element in a given nested list in Prolog?

Briefly, for input:
?- remove_second(([1,[2,1,[2],[3,3,[[3]],1,[1]],1],2,1,2,1,3],R).
Output: R=[1,[2,[],[3,[[3]],1,[]],1],2,1].
My attempt isn't functioning:
delete_second_occurrence(_, _, [], []):-!.
delete_second_occurrence(X, Z, [X|O], [X|L]):-Z==0,nested_memeber(X, O),
delete_second_occurrence(X, 1, O, L).
delete_second_occurrence(X, Z, [X|O1], L):-Z==1, delete_second_occurrence(X, 0, O1, L).
nested_memeber(X, [X|O]):-!.
nested_memeber(X, [Y|O]):-not(is_list(Y)),!, nested_member(X, O).
nested_member(X, [Y|O]):-(!,nested_member(X, Y));(!,nested_member(X,O)).
is_list([]).
is_list([_|_]).
I think you want all the lists to be unique?Every nested list and outer lists must have unique elemts.This should work in that case:
memberr(X,[X|_]):-
!.
memberr(X,[_H|T]):-
memberr(X,T).
lengthOfList(List,R):-
lengthOfList(List,0,R).
lengthOfList([],L,L).
lengthOfList([_|Tail],Acc,R):-
NewAcc is Acc + 1,
lengthOfList(Tail,NewAcc,R).
remove_second([],[]).
remove_second([H|T],R):-
remove_second(H,T,R,[]).
remove_second(H,[],[H|[]],List):-
integer(H),
\+ memberr(H,List).
remove_second(H,[],[],List):-
integer(H),
memberr(H,List).
remove_second(Elem,[H2|Tail2],[Elem|R],List):-
integer(Elem),
(
\+ memberr(Elem,List) ->
remove_second(H2,Tail2,R,[Elem|List])
).
remove_second(Elem,[H2|Tail2],R,List):-
integer(Elem),
(
memberr(Elem,List) ->
remove_second(H2,Tail2,R,List)
).
remove_second(Elem,[H2|Tail],[P|R],List):-
(
\+ integer(Elem) ->
lengthOfList(Elem,L),
L > 0,
remove_second(Elem,P),
remove_second(H2,Tail,R,List)
).
remove_second(Elem,[H2|Tail],[[]|R],List):-
(
\+ integer(Elem) ->
lengthOfList(Elem,L),
L == 0,
remove_second(H2,Tail,R,List)
).
remove_second(Elem,[],[[]],_):-
(
\+ integer(Elem) ->
lengthOfList(Elem,L),
L == 0
).
remove_second(Elem,[],[P],_):-
(
\+ integer(Elem) ->
lengthOfList(Elem,L),
L > 0,
remove_second(Elem,P)
).
Not the most optimal code but it will solve the problem.
You get this output R = [1,[2,1,[2],[3,[[3]],1,[1]]],2,3] with your input = remove_second([1,[2,1,[2],[3,3,[[3]],1,[1]],1],2,1,2,1,3],R).
There are many predefined predicates which you can remove, like memberr to member and lengthOfList etc

How do I find elements that are not common in Lists using prolog? [duplicate]

I am trying to implement a list difference routine in prolog.
For some reason the following fails:
difference(Xs,Ys,D) :- difference(Xs,Ys,[],D).
difference([],_,A,D) :- D is A, !.
difference([X|Xs],Ys,A,D) :-
not(member(X,Ys)),
A1 is [X|A],
difference(Xs,Ys,A1,D).
When trying:
?- difference([1,2],[],D).
I get this error:
ERROR: '.'/2: Type error: `[]' expected, found `1' ("x" must hold one character)
^ Exception: (10) _L161 is [2|1] ?
Your usage A1 is [X|A] is incorrect. Predicate is is used only for arithmetics.
Btw, SWI-Prolog has built-in subtract predicate:
1 ?- subtract([1,2,3,a,b],[2,a],R).
R = [1, 3, b].
2 ?- listing(subtract).
subtract([], _, []) :- !.
subtract([A|C], B, D) :-
memberchk(A, B), !,
subtract(C, B, D).
subtract([A|B], C, [A|D]) :-
subtract(B, C, D).
true.
Is this what you need?
minus([H|T1],L2,[H|L3]):-
not(member(H,L2)),
minus(T1,L2,L3).
minus([H|T1],L2,L3):-
member(H,L2),
minus(T1,L2,L3).
minus([],_,[]).
minus([1,2,3,4,3], [1,3], L).
output: L=[2,4]
Using find all the solution becomes obvious:
difference(Xs,Ys,D) :-
findall(X,(member(X,Xs),not(member(X,Ys))),D).
always (subtructLists(List, [Head|Rest], Result): -
(
delete_element(Head, List, Subtructed)
, !
, subtructLists(Subtructed, Rest, Result)
) ; (
subtructLists(List, Rest, Result)
)
).
always (subtructLists(List, [], List)).
always( delete_element(X, [X|Tail], Tail)).
always( delete_element(X, [Y|Tail1], [Y|Tail2]): -
delete_element(X, Tail1, Tail2)
).

Resources