如何在 Prolog 中将谓词作为另一个谓词的参数传递?

2023-11-30

我有这 3 个谓词:

times(X, Y):-
    Result is X * Y.
minus(X, Y):-
    Result is X - Y.
plus(X, Y):-
    Result is X + Y.

例如我想通过times(2,2) in the plus(X, Y)像这样plus(times(2,2), minus(X, Y)).


我不清楚你的问题标题和问题文本之间的关系,我认为@false可能是对的,这里对Prolog存在更根本的误解。我不知道这是否真的满足您的需求,但这里的替代方案是编写您自己的评估器。

eval(times(X,Y), Result) :-
    eval(X, XResult),
    eval(Y, YResult),
    Result is XResult * YResult.
eval(minus(X,Y), Result) :-
    eval(X, XResult),
    eval(Y, YResult),
    Result is XResult - YResult.
eval(plus(X,Y), Result) :-
    eval(X, XResult),
    eval(Y, YResult),
    Result is XResult + YResult.

递归调用eval/2每条规则的内部都需要处理类似的情况plus(times(2,2), minus(X, Y))。那么你需要一个数字规则:

eval(Num, Num) :- number(Num).

这对于这样的情况非常有用:

?- eval(plus(times(2,2), minus(7,1)), Result).
Result = 10.

对于这样的情况,它对你没有任何好处:

?- eval(plus(times(2,2), minus(X,Y)), Result).
ERROR: Out of local stack

当然,如果我们在到达那里之前建立了 X 和 Y 的绑定,那么它会起作用,但是如果您希望它为 X 和 Y 生成可能的解决方案,那么您就不走运了,您需要使用clpfd。如果你追查的话,这个奇怪错误的原因是因为number(X) when Xis unbound 是 false,因此它实际上生成涉及时间、减号和加号结构的新子句并尝试它们,这不是您在求值器中想要的。

Edit:实施printterm/1.

The eval/2谓词向您展示如何执行递归树遍历。原理与制作漂亮的打印机相同。我很懒所以只画了草图,细节你得自己填写。

printterm(T) :- format_term(T, Formatted), write(Formatted), nl.

format_term(plus(X,Y), Formatted) :- 
  format_term(X, XFormatted),
  format_term(Y, YFormatted),
  format(atom(Formatted), '(~a + ~a)', [XFormatted, YFormatted]).

% other format_term clauses here for other arithmetic expressions

format_term(X, X) :- number(X).

希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Prolog 中将谓词作为另一个谓词的参数传递? 的相关文章

  • 如何在 SQL Server 2000 中传递大于 varchar(8000) 的字符串参数?

    如果将字符串参数定义为大小大于 8000 则会出现编译错误 e g The size 9000 given to the type varchar exceeds the maximum allowed for any data type
  • Prolog 罗马数字(属性语法)

    我正在做一项作业prolog questions tagged prolog扫描数字列表并应返回该列表是否是有效的罗马数字以及数字的十进制值 前任 1 roman N I N 1 true 2 当我运行我认为应该工作的程序时 十进制值总是正
  • 表达式树深度限制

    我在尝试对类型为 Expression gt 的 LambdaExpression 调用 Compile 时遇到问题 该表达式的深度约为 400 较小的值不会导致任何问题 我找不到任何有关此类限制的信息 谁能澄清这一点吗 我可以增加这个限制
  • 升压参数库

    最近我发现参数 http www boost org doc libs 1 50 0 libs parameter doc html index htmlBoost 中的库 老实说 我不明白为什么这是 Boost 的一部分 当需要向函数传递
  • SWI Prolog 使用的检查优化会发生什么情况?

    去引用SICStus Prolog 手册 https sicstus sics se sicstus docs 3 12 9 html sicstus Occur html 逻辑编程背后的通常数学理论禁止 创建循环项 规定发生检查应该是 每
  • Powershell“特殊”开关参数

    我有下面的powershell功能 Function Test Param Parameter string Text default text Write Host Text Text 我希望能够像下面这样调用这个函数 测试 文本 应该在
  • C 中的复合语句表达式

    下面的代码不起作用 int i void 999 100 添加括号就可以了 为什么 int i void 999 100 还有另一种方法可以完成此类分配 int i void 999 100 是什么让他们与众不同 在这份声明中 int i
  • 根据传递的参数覆盖 Javascript 函数

    是否可以根据传递给函数的参数数量来重写函数 例如 function abc name document write My name is name function abc name friend document write My nam
  • 斜线(/)在序言中做什么?

    我有这个代码 set value X Value X T X Value T set value X Value Y V T Y V NewT X Y set value X Value T NewT set value X Value X
  • 将 < 或 > 运算符作为参数传递给函数?

    我的函数里面有一个if 像这样的声明 if passedValue lt staticValue 但我需要能够传递一个参数来指示 if 表达式是像上面那样还是 if passedValue gt staticValue 但我真的无法通过 l
  • Prolog:子句在源文件中不在一起

    我有这段代码 Family tree female pen male tom male bob female liz female pat female ann male jim parent pam bob parent tom bob
  • C 中函数参数中的固定数组或指针之间的区别?

    之间有区别吗 void draw line float p0 2 float p1 2 float color 4 和这个 void draw line float p0 float p1 float color in C 项目清单 C 和
  • 从表达式函数获取父属性

    假设我有以下课程 public class Model public AnotherModel InnerModel get set public class AnotherModel public String Value get set
  • 使用 Newtonsoft.Json.NET 搜索 JSON 根对象的正确 JsonPath 表达式是什么?

    大多数例子涉及Stefan G ssner 的书店示例 http goessner net articles JsonPath index html e3 但是我正在努力为简单对象 无数组 定义正确的 JsonPath 表达式 Id 1 N
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • 通过递归扩展 Prolog 目标?

    我 最终 实现了一些目标 这些目标将根据开始由 开始之后 and duration 然而 计划目标仅接受规定数量的任务 我想扩展计划目标的功能以接受单个列表并在计划时迭代该列表 不幸的是 我认为这将需要与can run and 冲突目标如下
  • Prolog中如何选择bagof、setof和findall

    如何在 bagof setof 和 findall 之间做出选择 有什么重要的区别吗 哪个最常用 哪个最安全 感谢您的评论 回答 我检查了SWI Prolog 手册页findall 3 http www swi prolog org pld
  • Doxygen:记录函数指针类型的参数 (ANSI-C)

    我的代码需要一些函数指针类型 例如 brief Callback function type foo typedef int foo int a int b 我想记录函数参数的语义 但是 param in out 旁边的 brief声明似乎
  • SWI-Prolog 中的跨模块“接口”调用

    这可能是 SWI Prolog 模块系统特有的 假设我们有三个 Prolog 模块 在 SWI Prolog 模块系统中 robin 在文件中robin pl arthur 在文件中arthur pl helper 在文件中helper p
  • HttpClient请求设置属性问题

    我使用这个 HttpClient 库玩了一段时间 几周 我想以某种方式将属性设置为请求 不是参数而是属性 在我的 servlet 中 我想使用 Integer inte Integer request getAttribute obj 我不

随机推荐