首页 \ 问答 \ prolog避免重复谓词(prolog avoiding duplicate predicates)

prolog避免重复谓词(prolog avoiding duplicate predicates)

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

我已经设法为一个谓词做了:

:- dynamic(test/2).

test(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 !!


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


原文:https://stackoverflow.com/questions/42071334
更新时间:2020-02-28 15:54

最满意答案

您希望调用/ 2 ,使用参数调用动态目标,在运行时进行评估。 在你的情况下,它将是call(Pred,X,Y)

main(Pred,X,Y) :-
    (
        call(Pred,X,Y),
        write('Yes'),!
    )
    ;
    (
        write('No'),!
    ).

请注意, Pred/2必须在运行时解析为实际谓词,并且您需要为每个参数数量构建不同的规则。

@ Tomas-By的回答,使用(= ..)/ 2可以创建一个带有args列表的规则,但是关于谓词存在的注意事项相同,尽管有一个额外的行:

main(Pred,L) :- % where L is a list of args [X,Y|...]
    Term =.. [Pred | L],
    (
        Term,
        write('Yes'),!
    )
    ;
    (
        write('No'),!
    ).

并且,正如@lurker的评论中所指出的,在任一实例中,使用( - >)/ 2

(call(Pred,X,Y) -> write('Yes') ; write('No'))

要么

(Term -> write('Yes') ; write('No'))

可能是优选的,因为选择点的破坏仅限于if-> then; else结构。


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.

2017-02-06

相关文章

更多

最新问答

更多
  • jsPlumb draggable element javascript函数(jsPlumb draggable element javascript function)
  • MVC4:ViewModel(带有radiobuttonlist)在HttpPost之后为空(MVC4: ViewModel (with radiobuttonlist) is empty after HttpPost)
  • 如何在同一帐户上设置“Dev repo”(在prod和团队之间)(How to set up a “Dev repo” (between the prod and the team) on the same account)
  • 如何在tcl中将eth0配置为发送方udp端口(how to configure eth0 as a sender udp port in tcl)
  • 如何在datarow []中的列中找到最大值?(How to find max value in a column in a datarow[] ?)
  • 如何使用预定义文本替换来自数据库的部分结果(How do I replace part of result coming from Database with predefined text)
  • Selenium Java注入了新的Javascript函数(Selenium Java inject new Javascript function)
  • 使用.on的多个下拉菜单选择文本仅适用于第一个下拉列表(Multiple Dropdowns Menu Selection text using .on works only on first dropdown)
  • 快速将黄土曲线添加到大型数据集图中的方法(Quick way to add loess curve to large data set graph)
  • FilteringSelect in mvc(FilteringSelect in mvc)
  • 在Delphi XE2中开发Mac或iOS应用程序需要哪些硬件/软件?(What hardware/software is necessary to develop Mac or iOS apps in Delphi XE2?)
  • 在原型的构造函数中初始化属性时获取“未定义”(Getting 'undefined' when a property is initialized in the constructor of a prototype)
  • 通过越狱加载的应用程序的Documents文件夹位置(Location of Documents folder for an app loaded via jailbreak)
  • 在OpenGL中使用可编程和固定管道功能(Using both programmable and fixed pipeline functionality in OpenGL)
  • 将任何用户输入重定向到单独的底层程序(redirect any user input to a separate underlying program)
  • 编辑文本不能正常工作android(Edit texts not working properly android)
  • “user_denied”Facebook应用页面上的Facebook用户区域设置(Facebook user locale on “user_denied” facebook app page)
  • 在大图像中找到小的部分透明图像的坐标(find coordinates of small partially-transparent image within a large image)
  • 我如何在cakephp 3.1中获得完整的相对路径?(How i can get full relative path of image in cakephp 3.1?)
  • 如何保存拖动标记的新本地化?(How to save new localization of dragged marker?)
  • MySQL UPDATE vs INSERT和DELETE(MySQL UPDATE vs INSERT and DELETE)
  • 在执行查询之前,在SQLAlchemy模型中将datetime转换为unix时间戳?(Convert datetime to unix timestamp in SQLAlchemy model before executing query?)
  • OpenCL与OpenGL互操作的优势(Advantage of OpenCL interoperability with OpenGL)
  • 如何解析用点和等分隔的数据然后添加到listview(How to parsing data from delimited with dot and equal then add to listview)
  • 带调试输出的X3解析器段错误(BOOST_SPIRIT_X3_DEBUG)(X3 parser segfaults with debug output (BOOST_SPIRIT_X3_DEBUG))
  • 将文件夹名称添加到fgrep结果(Add folder name to fgrep result)
  • 在MySQL中加载一个表是非常慢的(Loading one table in MySQL is ridiculously slow)
  • 如何将JSON放入PHP变量?(How do I put JSON into a PHP Variable?)
  • 如何绕过Microsoft.Speech.Recognition中的不流畅?(How to bypass disfluencies in Microsoft.Speech.Recognition?)
  • 原点的最后一行是什么?(What is the last row of an origin for?)