Why doesn't 'Q' unify in this PROLOG program - prolog

I am writing a PROLOG program in which the variable of interest (Q) refuses to unify. I have gotten around this with a hacky solution (include a write statement). But there has to be a way to make this unify, but for the love of me, I am not able to figure it out.
I'd really appreciate any help.
Thanks in advance.
Here is my code (I have annotated wherever I have excluded code for brevity)
:- use_module(library(bounds)).
:- use_module(library(lists)).
solve([17],Q,_,_,_):- write(Q). %this is the hacky workaround
solve(L,Q,1,3,2) :- jump(L,Q,N,1,3,2,R), solve(N,R,S,D,M), member([S|[D|[M|[]]]],[[1, 3, 2], [1, 9, 4], [2, 10, 5] this list contains 76 items - all of which are lists of length 3. I have omitted them here for the sake of brevity]).
% there are about 75 other definitions for solve, all of which are structured exactly the same. The only difference is that the numbers in the input parameters will be different in each definition
jump(L,Q,N,S,D,M,R):- member(S,L), not(member(D,L)), member(M,L), delete(L,S,X), delete(X,M,Y), append(Y,[D],N), append(Q,[[S,D]],R).
cross_sol(Q) :- solve([5,9,10,11,17,24],Q,S,D,M), member([S,D,M], [
I have edited out this list here for the sake of brevity. It is the same list found in the definition of solve
]).
For some reason, Q does not unify. Please help!
Thank you!

The cross_sol/1 predicate seems malformed.
cross_sol(Q) :- solve([5,9,10,11,17,24],[],S,D,M), member([S,D,M], [
I have edited out this list here for the sake of brevity. It is the same list found in the definition of solve
]).
The variable Q is a singleton -- it is not referenced anywhere in the body (unless it is the portion you have suppressed).

Related

Prolog: existentially quantifying

I am trying to understand the usage of existentially quantifying. What I know by now is this technique is used with setof, findall, bagof. Further, I found a tutorial. However, I am not sure when and how I do the Vars^Goal (existentially quantifying) in Prolog.
Here is the example, my goal is to find two employees who know each other but work at different companies, binding the result with L showing Name1-Name2:
company('Babbling Books', 500, 10000000).
company('Crafty Crafts', 5, 250000).
company('Hatties Hats', 25, 10000).
employee(mary, 'Babbling Books').
employee(julie, 'Babbling Books').
employee(michelle, 'Hatties Hats').
employee(mary, 'Hatties Hats').
employee(javier, 'Crafty Crafts').
knows(javier, michelle).
My first instinct is to use the query
?-employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2).
The query found the answer but doesn't render it into the correct format. The correct one is:
?-setof(N1-N2, (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)), L).
How could I understand the (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)) ? And what's the concept of it? Thanks.
I am not sure when and how I do the Vars^Goal (existentially quantifying) in Prolog.
The easiest answer is: Don't do it, ever. You can always introduce an auxiliary predicate that captures exactly the query you want, exposing exactly the arguments you want and nothing else (that would require quantification), and with a nice self-documenting name.
In your example, you can define:
different_company_acquaintances(N1, N2) :-
employee(N1, C1),
employee(N2, C2),
C1 \= C2,
knows(N1, N2).
and then express your setof query as:
?- setof(N1-N2, different_company_acquaintances(N1, N2), L).
L = [javier-michelle].
This is easier to read because of the predicate name and because it hides the irrelevant implementation details. Note that in the predicate definition the arguments are only the data the caller cares about (the employees), and there are no arguments for the data the caller doesn't care about (the companies).
How could I understand the (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)) ?
The ^ syntax, whatever the exact correct form is, is meant to signal variables that, if you wrote out a separate predicate definition, would only occur in the predicate's body, not as its arguments. This tells setof and friends that every time it tries to execute the goal (employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)) it should do so with unbound variables C1 and C2. In other words, it should not try to retain the values of C1 and C2 from one attempt to the next.

How to print variable value from a question?

I´m making a one bit addition:
sumbit(CIN,A,B,CO,R):- ...
?- sumbit(0
,1
,1
,CO
,R)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(CO),write(R),nl.
What I want to do is to print the variable values of CIN,A,B,CO and R.
It should come out something like this:
0
1
+
1
--
10
Instead it comes out as this:
_40
_73
+
_149
--
10
Yes.
Also is there a way to not print the "Yes"?
I´m using strawberry prolog if it helps.
Thank you in advance
One way to achieve that without altering your predicate definition is to tweak the query, like so:
?- [CIN, A, B] = [0, 1, 1]
,sumbit(CIN
,A
,B
,CO
,R)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(CO),write(R),nl.
Now all variables are instantiated, either by the call itself, or prior to the call.
When a variable is not instantiated, there's no value to print, so its "name" is printed instead. But since non-used name has no meaning in itself, it can be freely renamed by the system to anything. In SWI Prolog:
1 ?- write(A).
_G1338
true.
The renaming is usually done, as part of the Prolog problem solving process, to ensure that any two separate invocations of the same predicate do not interfere with each other.
So where SWI Prolog uses names like _G1338, the Prolog implementation you're using evidently uses names with the numbers only, after the underscore, like _40.
I found an answer by putting the write() inside the sumbit(...) predicate:
sumbit(CIN,A,B,CO,R):-
xor_(A,B,R1)
,and(A,B,R2)
,xor_(R1,CIN,R)
,and(R1,CIN,R4)
,or(R2,R4,CO)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(R),nl.
There are still some unanswered questions though:
is there a way to not print the "Yes"?
what was the _number that came out before?

setof with compound predicate

I am struggling with a question in an assignment with prolog.
So, I have the following fact database in prolog:
student(name(doe, [john]), 33332, ['CSI1120'] ).
student(name(doe, [jane]), 33336, ['CSI1120'] ).
evaluation('CSI1120', homework(1), ['Prolog', database ], 5).
mark('CSI1120', 33332, homework(1), 3.5 ).
mark('CSI1120', 33336, homework(1), 4.0 ).
My goal here is to create a predicate listAllMarks/3 such as
?- returnAllMarks('CSI1120',homework(1),L).
Returns:
L= [(33332, 3.5), (33336, 4.0)].
In order to resolve this problem, I was thinking of making use of the prolog setof/3, so I came with the following predicate.
returnAllMarks(C,H,L):- setof(L,mark(C,_,H,X),[L|X]).
This doesn't seems to work, the predicate always return false. I"m suspecting that this may be due to the fact I am using setof against a compound predicate, but I could be wrong (I'm still in the early stages of learning prolog).
Do you guys have an idea? I look at this problem from all angles, and I am stuck here.
Thank you.
You could write something like:
returnAllMarks(C,H,L):- setof( (X,Y), mark(C,X,H,Y), L).
Example:
?- returnAllMarks('CSI1120',homework(1),L).
L = [ (33332, 3.5), (33336, 4.0)].

Prolog problem! 'singles' !

I have a prolog homework, which should work like this:
singles([1,2,3,2,2,4,1], [3,4]).
true
Now I've figured out I should test if one element is single in the list then put all the single element together..then I wrote down:
singles(L,SL):-findall(X,isSingle(X,L),SL).
isSingle(X,L):-member(X,L),append(Y,[X|Z],L),not(member(X,L1)),append(Y,Z,L1).
in the isSingle function the X should be in List L but not in the new List L1 without X, like 1 is in [2,1,3] but not in [2,3], but sadly the whole thing doesn't work like I thought :(
I think the problem is in the isSingle part, can anyone help me?
Switch the order of not(member(X,L1)) and append(Y,Z,L1) and your code works. I'm no Prolog expert, so I'm not entirely sure about this, but, going through the trace, it seems to have to do with the subtleties of using not. You're forcing the evaluation of member on L1 before it has been unified in append(Y,Z,L1) bit.
singles(List,SelectList) :-
singles(List,List,SelectList).
singles([],List,[]).
singles([A|R1],List,[A|R2]) :-
unique(A,List),
singles(R1,List,R2).
singles([A|R1],List,R2) :-
\+(unique(A,List)),
singles(R1,List,R2).
unique(A,List) :-
append(L0,[A|R],List),
\+(append(_,[A|_],L0)),
\+(append(_,[A|_],R)).

Splitting atoms with pipe symbols

I have a list of lists of this structure in GNU-Prolog:
[[1|5], [1|6], [2|6], [3|6]]
What might be the best way to extract the numbers in each sublist separately? I can't unify each term because of the pipe, unless there is something I am missing. Any help would be great; I'm very new to Prolog and haven't found much online for this issue
Then I tryed this in console (SWI).
Does this help?
?- [1|2]=..A.
A = ['[|]', 1, 2].
?- [1|2]='[|]'(A,B).
A = 1,
B = 2.
I mean matching like
[1|2]='[|]'(A,B).
will succeed.
Typically righthand side of the | operator should be a list(including empty list []).
You should write like :
[[1|[5]], [1|[6]], [2|[6]], [3|[6]]]
or simply
[[1,5],[1,6],[2,6],[3,6]]

Resources