避免重复谓词的序言 [英] prolog avoiding duplicate predicates
问题描述
我想知道是否有可能测试谓词是否已经存在(具有相同的信息),从而避免用户再次输入相同的信息。
我已经为单个谓词做到了这一点:
:-dynamic(test / 2)。
测试(a,b)。
top(X,Y):-
(test(X,Y),
write('Yes'),!
; write('No' ),!
)。
此版本运行良好,如果信息已存在,则返回是,如果信息已存在,则返回否
我想知道是否有可能针对多个前提,而不仅限于'test / 2'?
我曾尝试用变量Pred替换谓词 test,但不幸的是,当我尝试编译谓词时,出现语法错误。
这是我的尝试:
main(Pred,X,Y):-
(Pred( X,Y),
write('Yes'),!
; write('No'),!
)。
是否有可能做类似的事情,如果可能的话?
顺便说一句,如果有帮助,我正在使用GNU Prolog。
非常感谢您的帮助:D !!
您要调用/ 2 ,以在运行时评估带有参数的动态目标。在您的情况下,将是 call(Pred,X,Y)
:
main(Pred,X,Y):-
(
调用(Pred,X,Y),
write('Yes'),!
)
;
(
write('No'),!
)。
请注意, Pred / 2
必须解析到运行时的实际谓词,则需要为每个数量的参数构建不同的规则。
@ Tomas-By的答案,使用(= ..)/ 2 可让您创建一个规则,其中有一个args列表,但对谓词的存在有相同的警告,尽管有额外的一行:
main(Pred, L):-%其中L是args的列表[X,Y | ...]
Term = .. [Pred | L],
(
期限,
write('Yes'),!
)
;
(
write('No'),!
)。
而且,正如@lurker的注释中指出的那样,在任一情况下,都使用(->)/ 2 :
(call(Pred,X,Y)-> write('Yes'); write('No'))
或
(术语-> write('Yes'); write('No'))
因为选择点的破坏仅限于if-> then; else结构。
I was wondering whether it is possible to test whether a predicate already exists (with the same information) to then avoid the user being able to input the same information again.
I have already managed to do it for a single predicate:
:- dynamic(test/2).
test(a,b).
top(X,Y) :-
(test(X,Y),
write('Yes'),!
;write('No'),!
).
This version works just fine, returning 'Yes' if the information already exists and 'No' if it doesn't.
I was wondering whether it would be possible to do this for multiple prediactes, not just for 'test/2'; I have tried to replace the predicate 'test' with a variable Pred but unfortunately I get a syntax error when I try to compile it. Here is my attempt:
main(Pred,X,Y) :-
(Pred(X,Y),
write('Yes'),!
;write('No'),!
).
Is it even possible to do something like this and if it is how would it be possible?
Btw I am using GNU Prolog if it helps.
Thank you very much for your help :D !!
You want call/2, to call a dynamic goal with arguments, evaluated at runtime. In your case, it would be call(Pred,X,Y)
:
main(Pred,X,Y) :-
(
call(Pred,X,Y),
write('Yes'),!
)
;
(
write('No'),!
).
Do note that Pred/2
must resolve to an actual predicate at runtime, and you will need to build a different rule for each number of arguments.
@Tomas-By's answer, using (=..)/2 lets you create a single rule, with a list of args, but with the same caveats regarding predicates existing, albeit with an extra line:
main(Pred,L) :- % where L is a list of args [X,Y|...]
Term =.. [Pred | L],
(
Term,
write('Yes'),!
)
;
(
write('No'),!
).
And, as pointed out in the comments by @lurker, in either instance, using (->)/2:
(call(Pred,X,Y) -> write('Yes') ; write('No'))
or
(Term -> write('Yes') ; write('No'))
may be preferable as the destruction of choice points is limited to the if->then;else structure.
这篇关于避免重复谓词的序言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!