如何在Prolog中使用类似变量的仿函数名称?

时间:2014-06-10 08:59:21

标签: variables prolog functor meta-predicate

我们的Prolog课程有这项任务。经过两个月每周一小时的Prolog,对我来说仍然是一个谜,我的想法似乎无法适应程序语言 - 但是。

知识库包含具有相同名称和arities 1,2和3的谓词/仿函数。 呼叫表格应为

  

搜索(functor_name,参数,S)。

答案应该找到具有此仿函数名称和参数的所有事件,无论arity如何。 答案应该是以下形式:

S = functor_name(argument);
S = functor_name(argument,_);
S = functor_name(_,argument);
S = functor_name(argument,_,_);
S = functor_name(_,argument,_);
S = functor_name(_,_,argument);
false.

我发现我可以使用call来测试知识库中的条目是否存在。

但是调用似乎不适用于函子名称的变量。我完全感到困惑,不知道如何将变量用作仿函数名称。

更新:

我的问题得到了部分回答。 我的新代码给了我真实和假的第1,第2和第3(见下文)。

search(Person,Predicate) :-
   ID = Person, Key = Predicate, current_functor(Key,1),
   call(Key,ID)
 ; ID = Person, Key = Predicate, current_functor(Key,2),
   (call(Key,ID,_);call(Key,_,ID))
 ; ID = Person, Key = Predicate, current_functor(Key,3),
   (call(Key,ID,_,_);call(Key,_,ID,_);call(Key,_,_,ID)).

UPDATE2:

另一个部分答案已经出现。那个人给了我一个术语列表,但是"其他"参数是占位符:

search2(Predicate, Arg, S) :-
   ( Arity = 2 ; Arity = 3 ; Arity = 4 ),
   functor(S, Predicate, Arity),
   S =.. [_,Predicate|Args],
   member(Arg, Args).

结果非常好。仍然缺失:谓词不应该在括号内,其他参数应该从知识库中逐字逐句,而不是写为占位符。目前的结果如下:

 ?- search2(parent,lars,S).
S = parent(parent, lars) ;
S = parent(parent, lars, _G1575) ;
S = parent(parent, _G1574, lars) ;
S = parent(parent, lars, _G1575, _G1576) ;
S = parent(parent, _G1574, lars, _G1576) ;
S = parent(parent, _G1574, _G1575, lars).

我放弃了这个问题,因为问题从一开始就以错误的方式提出。我应该更具体地问 - 我不能,因为我在Prolog中仍然不擅长。

@false对我帮助最大。我接受了他的回答。

2 个答案:

答案 0 :(得分:4)

这里有两种方法,一种是#34;传统的" (20世纪70年代)实现了你想要的字面意思:

search(F, Arg, S) :-
   ( N = 1 ; N = 2 ; N = 3 ), % more compactly: between(1,3, N)
   functor(S, F, N),
   S =.. [_|Args],            % more compactly: between(1,N, I), arg(I,S,Arg)
   member(Arg, Args).

另一个人重新考虑明确构建目标。实际上,如果您有一个仿函数F,参数A1A2A3,您可以立即编写目标call(F, A1, A2, A3)而不使用{{1} }或functor/3

使用(=..)/2代替call(F, A1, A2, A3)有很多好处:在许多情况下,它更清晰,更快速,更容易进行类型检查。此外,在使用模块系统时,Goal =.. [F, A1, A2, A3], call(Goal)的潜在模块资格的处理将无缝地工作。虽然F必须明确处理所有丑陋的细节,但代码更多,错误更多。

(=..)/2

如果您想缩短它,那么请动态构建search(F,A,call(F,A)). search(F,A,call(F,A,_)). search(F,A,call(F,_,A)). search(F,A,call(F,A,_,_)). search(F,A,call(F,_,A,_)). search(F,A,call(F,_,_,A)).

call/N

请注意,调用需要额外的参数search(F, Arg, S) :- ( N = 2 ; N = 3 ; N = 4 ), functor(S, call, N), S =.. [_,F|Args], member(Arg, Args).

答案 1 :(得分:3)

您可以使用“univ”运算符=..动态构建目标:

?- F=member, X=1, L=[1,2,3], Goal =.. [F, X, L], call(Goal).
F = member,
X = 1,
L = [1, 2, 3],
Goal = member(1, [1, 2, 3]) .