I'm trying to define a predicate that receives a single term with free variables and returns a list of mappings of those variables, so for example if the database is
a(0,1).
a(1,1).
the expected output would be
?- eval(a(X,1),Maps).
Maps = [[[X,0]],[[X,1]]].
?- eval(a(X,Y),Maps).
Maps = [[[X,0],[Y,1]],[[X,1],[Y,1]]].
I've been trying to accomplish this by using findall/3
, but I can't figure out a way to ask for the free variables and their possible values. If it helps, I'm using swiprolog.
Thanks.
Here is a solution to a similar problem. Instead of a list of answers represented as a list with entries [V,term]
for each variable, the query goal_answers(Goal, Answerp)
finds a pair Vars-Terms
.
goal_answerp(Goal, Answerp) :-
term_variables(Goal, Vars),
findall(Vars, Goal, Substs),
Answerp = Vars-Substs.
?- goal_answerp(a(X,1), Ms).
Ms = [X]-[[0],[1]].
?- goal_answerp(a(X,Y), Ms).
Ms = [X,Y]-[[0,1],[1,1]].
[Edit] To get the answers back in the original format use library(lambda)
:
?- goal_answerp(a(X,1), Vs-Dss),
maplist(Vs+\Ds^VDs^maplist(\V^D^[V,D]^true,Vs,Ds,VDs),Dss,VDss).
Vs = [X], Dss = [[0],[1]], VDss = [[[X,0]],[[X,1]]].
?- goal_answerp(a(X,Y), Vs-Dss),
maplist(Vs+\Ds^VDs^maplist(\V^D^[V,D]^true,Vs,Ds,VDs),Dss,VDss).
Vs = [X,Y], Dss = [[0,1],[1,1]], VDss = [[[X,0],[Y,1]],[[X,1],[Y,1]]].