避免重复谓词的序言 [英] prolog avoiding duplicate predicates

查看:95
本文介绍了避免重复谓词的序言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有可能测试谓词是否已经存在(具有相同的信息),从而避免用户再次输入相同的信息。



我已经为单个谓词做到了这一点:

 :-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆