我们的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对我帮助最大。我接受了他的回答。
答案 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
,参数A1
,A2
,A3
,您可以立即编写目标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]) .