Reputation: 878
I am trying to print the values present in Facts. For example when I have the following Facts:
terrain(2,(2,4,3,1)).
terrain(2,(3,1,2,4)).
terrain(1,(4,3,1,2)).
terrain(3,(1,2,4,3)).
Input:
v([1,2,3],R).
It should give me:
R = [(4,3,1,2), (2,4,3,1), (3,1,2,4), (1,2,4,3)]
But the code isn't printing the second value of 2 i.e. (3,1,2,4) present in Facts. I am getting:
R = [(4,3,1,2), (2,4,3,1), (1,2,4,3)]
How do I get all possible values for a certain value present in a Fact.
My code:
%Facts
terrain(2,(2,4,3,1)).
terrain(2,(3,1,2,4)).
terrain(1,(4,3,1,2)).
terrain(3,(1,2,4,3)).
v([],[]).
v([H|T],[Q|R]):-
terrain(H,Q),
v(T,R),!.
Upvotes: 1
Views: 63
Reputation: 10102
First of all, let's look at your definition. Why did you insert a cut here? Let's see what happens without it:
?- v([1,2,3],R).
R = [(4,3,1,2),(2,4,3,1),(1,2,4,3)]
; R = [(4,3,1,2),(3,1,2,4),(1,2,4,3)].
So with this cut you removed the second solution. Now you may not like it, but let's keep in mind your definition of v/2
. To make it easier to read, I will use a generalization of your definition.
:- op(950, fy, *). * _G_0. % to remove a goal v([],[]). v([H|T],[Q|R]):- *terrain(H,Q), v(T,R).
So what remains is a relation that is true when both arguments are lists of the same length. And thus also with terrain/2
added this will hold. There is no way to make the second argument a list that is longer. If you really want to change this, you have to modify already that generalized part.
v2([], []).
v2([H|Hs], Vs0) :-
setof(V, terrain(H, V), Vs),
append(Vs, Vs1,Vs0),
v2(Hs, Vs1).
?- v2([1,2,3],R).
R = [(4,3,1,2),(2,4,3,1),(3,1,2,4),(1,2,4,3)].
Alternatively, and preferably, use a DCG:
seq([]) -->
[].
seq([E|Es]) -->
[E],
seq(Es).
v([]) -->
[].
v([H|Hs]) -->
{setof(V, terrain(H, V), Vs)},
seq(Vs),
v(Hs).
?- phrase(v([1,2,3]), Vs).
Vs = [(4,3,1,2),(2,4,3,1),(3,1,2,4),(1,2,4,3)].
?- length(Hs, 2), phrase(v(Hs), Vs).
Hs = [1,1], Vs = [(4,3,1,2),(4,3,1,2)]
; Hs = [1,2], Vs = [(4,3,1,2),(2,4,3,1),(3,1,2,4)]
; Hs = [1,3], Vs = [(4,3,1,2),(1,2,4,3)]
; Hs = [2,1], Vs = [(2,4,3,1),(3,1,2,4),(4,3,1,2)]
; Hs = [2,2], Vs = [(2,4,3,1),(3,1,2,4),(2,4,3,1),(3,1,2,4)]
; Hs = [2,3], Vs = [(2,4,3,1),(3,1,2,4),(1,2,4,3)]
; Hs = [3,1], Vs = [(1,2,4,3),(4,3,1,2)]
; Hs = [3,2], Vs = [(1,2,4,3),(2,4,3,1),(3,1,2,4)]
; Hs = [3,3], Vs = [(1,2,4,3),(1,2,4,3)].
?- Hs = [A,B], dif(A,B), phrase(v(Hs), Vs).
Hs = [1,2], A = 1, B = 2, Vs = [(4,3,1,2),(2,4,3,1),(3,1,2,4)]
; Hs = [1,3], A = 1, B = 3, Vs = [(4,3,1,2),(1,2,4,3)]
; Hs = [2,1], A = 2, B = 1, Vs = [(2,4,3,1),(3,1,2,4),(4,3,1,2)]
; Hs = [2,3], A = 2, B = 3, Vs = [(2,4,3,1),(3,1,2,4),(1,2,4,3)]
; Hs = [3,1], A = 3, B = 1, Vs = [(1,2,4,3),(4,3,1,2)]
; Hs = [3,2], A = 3, B = 2, Vs = [(1,2,4,3),(2,4,3,1),(3,1,2,4)].
And, btw, in Prolog it is often preferred to write v(4,3,1,2))
instead of (4,3,1,2)
. Just say write_canonical((4,3,1,2)).
to see why.
Upvotes: 2