查找谓词的所有解法

时间:2011-07-20 12:56:19

标签: prolog prolog-findall

我正在尝试定义一个带有自由变量的单个术语的谓词,并返回这些变量的映射列表,例如,如果数据库是

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。 感谢。

3 个答案:

答案 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可能有更好的方法来执行此类操作。