我正在尝试定义一个带有自由变量的单个术语的谓词,并返回这些变量的映射列表,例如,如果数据库是
a(0,1).
a(1,1).
预期输出为
?- eval(a(X,1),Maps).
Maps = [[[X,0]],[[X,1]]].
?- eval(a(X,Y),Maps).
Maps = [[[X,0],[Y,1]],[[X,1],[Y,1]]].
我一直试图通过使用findall/3
来实现这一目标,但我无法找到一种方法来询问自由变量及其可能的值。如果它有帮助,我正在使用swiprolog。
感谢。
答案 0 :(得分:3)
这是类似问题的解决方案。查询[V,term]
找到一对goal_answers(Goal, Answerp)
,而不是表示为每个变量的条目为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]].
[编辑]要以原始格式返回答案,请使用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]]].
答案 1 :(得分:2)
您想要做的事情存在问题。您为变量(例如X,Y)提供的用户友好名称对于顶级解析器是已知的,但在程序中“丢失”。 此代码段将列出所有绑定,但变量将具有通用名称:
find_mappings(Template, Mappings):-
term_variables(Template, Vars),
find_mappings1(Vars, Mapping),
findall(Mapping, Template, Mappings).
find_mappings1([], []).
find_mappings1([Var|Vars], [[Name,Var]|Mappings]):-
term_to_atom(Var, Name),
find_mappings1(Vars, Mappings).
?- find_mappings(a(X,Y), L).
L = [[['_G385', 0], ['_G386', 1]], [['_G385', 1], ['_G386', 1]]].
您可能更喜欢在过程中添加另一个参数来接收变量的正确名称:
find_mappings(Template, Names, Mappings):-
term_variables(Template, Vars),
find_mappings1(Vars, Names, Mapping),
findall(Mapping, Template, Mappings).
find_mappings1([], [], []).
find_mappings1([Var|Vars], [Name|Names], [[Name,Var]|Mappings]):-
find_mappings1(Vars, Names, Mappings).
?- find_mappings(a(X,Y), ['X', 'Y'], L).
L = [[['X', 0], ['Y', 1]], [['X', 1], ['Y', 1]]].
答案 2 :(得分:0)
我面前没有翻译,但我想你可以用'a'谓词为这个特定的设置做这个。
var(X),
var(Y),
findall(U,
( a(XSol,YSol), U=[[X,XSol], [Y,YSol]] ),
Maps).
(var可能是不必要的) 我不知道你为什么要用这种方法解决任何问题......
查看unifiable/3可能有更好的方法来执行此类操作。