Prolog 给定 x 的所有可能表达式

Posted

技术标签:

【中文标题】Prolog 给定 x 的所有可能表达式【英文标题】:Prolog all possible expressions of given x 【发布时间】:2013-11-30 00:14:58 【问题描述】:

我有一个给定语法的序言程序:

sum --> [+], mult, sum | mult | num.
mult --> [*], num, xer.
xer --> [x] | [^], [x], num.
num --> [2] | [3] ... etc

我的表达式有一个抽象的树表示。例如:mul(num(2),var(x)) 等于 [*,2,x] 是有效的。 我希望能够创建满足给定 x 和解决方案的所有表达式。使用

allExpressions(Tree, X, Solution).

例如:

?- allExpressions(Tree, 2, 6)
Tree = mul(num(3),x)
Tree = sum(num(2),mul(num(2),var(x))
etc.

由于我的语法,它显然不会是一个无限的方程组。 我已经编写了一个evaluation(Tree, X, Solution),它计算给定 X 变量的答案。所以我需要帮助的是为给定的 x 变量和解生成可能的方程组。

对我如何处理这个问题有任何想法吗?谢谢

【问题讨论】:

如下所述,它可以与更新版本的 SWI-Prolog 一起使用。要使其适用于旧版本,请在求幂子句的第一行中添加约束 N1 #< N @mat 我添加了这一行,但我的每个测试用例的输出仍然只有一行。你看有什么不对吗?另外,你知道一个简单的方法让 num 对所有整数都工作 >= 2 而不是像 2 | 那样声明它们吗? 3 | 4 | 5 ...等? 它适用于 SWI >= 6.5.2 以及您现在显示的代码。当然,您必须在第一个解决方案之后按 SPACE 以获得其他解决方案。您可以轻松地在 DCG 中描述具体的整数,例如使用 num --> [N], between(2,5,N) . 非常感谢,我的错误在于我代表 num 的方式,两者之间工作正常! 【参考方案1】:

这很容易:由于您所有的算术运算只能增加表达式的值,因此在搜索解决方案时限制深度很简单。简单地归纳地描述解决方案的外观。例如,您可以使用 SWI-Prolog 的有限域约束来进行加法和乘法,如下所示:

:- use_module(library(clpfd)).

expression(var(x), X, X).
expression(num(N), _, N) :- phrase(num, [N]).
expression(mul(A,B), X, N) :-
        N1 * N2 #= N,
        N1 #> 1,
        N2 #> 1,
        expression(A, X, N1),
        expression(B, X, N2).
expression(sum(A,B), X, N) :-
        N1 + N2 #= N,
        N1 #> 1,
        N2 #> 1,
        expression(A, X, N1),
        expression(B, X, N2).

我将其他操作留作练习。

示例查询和一些结果:

?- expression(Tree, 2, 6).
Tree = mul(var(x), num(3)) ;
Tree = mul(num(2), num(3)) ;
    [...solutions omitted...]
Tree = sum(num(2), mul(num(2), var(x))) ;
Tree = sum(num(2), mul(num(2), num(2))) ;
    [...solutions omitted...]
Tree = sum(sum(num(2), num(2)), num(2)) ;
false.

+1 用于对表达式树(var(x)num(N) 等)使用干净的、非默认的表示,这使您可以在推理时使用模式匹配。

【讨论】:

感谢您的好回答,这似乎很合乎逻辑。但是,在实现这一点时,?- expression(Tree,2,6). 只给了我一个答案Tree = num(6). 我将您的实现与附加的 [^] 运算符一起使用。知道我做错了什么吗? 其实 ?- Tree = mult(var(x), num(3)) 是我唯一得到的,在编辑中检查我的代码! 您可能没有使用最新的 git 版本的 SWI-Prolog。对于旧版本,您必须将约束 N1 #< N 添加到求幂子句中,以让约束求解器知道 N1 小于 N。在较新的版本中,它不再需要此提示并自行推断。一旦你将这个额外的约束添加到你的最后一个子句或升级你的 SWI 版本,它应该对你有用。

以上是关于Prolog 给定 x 的所有可能表达式的主要内容,如果未能解决你的问题,请参考以下文章

在prolog语言中, 符号<>表示啥意思? 比如X<>Y

Prolog 中的复合布尔表达式

谓词用于返回prolog中给定列表的元素顺序的排列

带有先决条件的 Prolog 路径查找

MiniKanren 有“非”运算符吗?

语法错误:。或表达式1错误编译失败后预期的运算符