Prolog 中的复合布尔表达式
Posted
技术标签:
【中文标题】Prolog 中的复合布尔表达式【英文标题】:Compound boolean expressions in Prolog 【发布时间】:2012-02-15 14:29:05 【问题描述】:在 Prolog 中,如何实现复合逻辑谓词,如 (A and B) 或 (C and D)?
这似乎是一个简单的问题,但许多平易近人的在线教程对布尔表达式不够详细。我假设你不能只写:
test(A, B, C, D) :- cond(A), cond(B); cond(C), cond(D).
那你会怎么做呢?
【问题讨论】:
如果您尝试运行那段代码,您会发现它完全符合您的要求。 【参考方案1】:正如其他人所说,您的原始示例
test(A, B, C, D) :- cond(A), cond(B); cond(C), cond(D).
完全有效(假设解析符合您的预期)。你没试过吗?
入门书
逻辑与
foo :- a , b .
逻辑或
foo :- a ; b .
合并
foo :- a , b ; c , d .
以上解析为:
foo :- ( a , b ) ; ( c , d ) .
使用括号表示不同的所需绑定:
foo :- a , ( b ; c ) , d .
更好的是,避免使用;
OR 运算符并将备选方案分解为单独的子句。对于人们来说,顺序比分支树结构更容易理解。将交替分解为多个子句可简化测试/调试并提高理解力。因此,更喜欢
foo :- a , b .
foo :- c , d .
结束
foo :- a , b ; c , d .
喜欢
foo :- a , bar , d .
bar :- b .
bar :- c .
结束
foo :- a , ( b ; c ) , d .
可能最重要的是,像这样将事情分解成多个子句可以使以后的维护更容易。结构如下:
foo :- a , b ; c , d .
当您添加另一个案例时,您会怎么做?当它扩展到 50 种替代品时呢?
每个额外的备选方案都会增加通过子句的代码路径数量,从而使测试和理解更加困难。要在测试中获得完整的代码覆盖率,必须单独测试许多替代路径。
具有等价结构
foo :- a , b .
foo :- c , d .
添加备选方案只是添加一个或多个附加子句,每个子句都可以单独测试。
专业程序员首先为那些在几年后需要理解、更改和修复代码的人编写代码(提示:那个人可能就是你自己)。
【讨论】:
【参考方案2】:连词的一个简单替代方法是使用子语句。对于析取,使用多行。你的例子:
test(A, B, C, D) :- test1(A, B).
test(A, B, C, D) :- test2(C, D).
test1(A, B) :- A, B.
test2(C, D) :- C, D.
(A 或 B)和(C 或 D)呢?
other(A, B, C, D) :- other1(A, B), other2(C, D).
other1(A, B) :- A.
other1(A, B) :- B.
other2(C, D) :- C.
other2(C, D) :- D.
请注意,这只是作为 joel76 答案的替代品而提及。
【讨论】:
【参考方案3】:test(A, B, C, D) :- (cond(A), cond(B)); (条件(C),条件(D))。
【讨论】:
@Mog:不需要括号,但如果混合 AND 和 OR,它有助于澄清运算符的优先级和绑定。对于很多人来说,像a AND b OR c AND d
这样的表达式并不清楚它是绑定为(a AND b) OR (c AND d)
还是绑定为a AND (b OR c) and d
?此外,这是故意的?这是许多编程语言中相当常见的错误来源,因此它有助于明确指出所需的绑定 —少数几个地方之一,恕我直言,多余的括号实际上可以提高信噪比。
当然可以,但在我看来,它不能作为答案接受,它至少应该精确地表明它只是明确的事情并且它相当于 OP 的代码。这就是我投反对票的原因。以上是关于Prolog 中的复合布尔表达式的主要内容,如果未能解决你的问题,请参考以下文章