最近我开始学习逻辑编程和使用Prolog,几天前我发现条件语句也可以在Prolog中使用。
我想知道,如果我有一个必须被调用的谓词在这两种情况下,以这种方式编写代码是正确的:
process(args) :-
(condition -> process_args1; process_args2),
predicateCalledAnyway.
而不是在两种情况下调用它,如下所示:
process(args) :-
(condition -> process_args1, predicateCalledAnyway; process_args2, predicateCalledAnyway).
有什么区别吗?如果是,那是什么?为什么?对我来说,似乎代码在两种情况下都会产生相同的结果。
答案 0 :(得分:3)
编写代码的这些表单等效。
第一个版本更短,更容易发现公共部分。
但是,请注意两个版本所固有的更基本的问题:(->)/2
不正确提交到第一个解决方案条件,一般情况下( Cond -> Then ; Else )
只有在Cond
被充分实例化时才有效。
例如:
?- ( member(X, [a,b,c]) -> false ; true ). false.
然而,添加约束突然使这成功:
?- X = d, ( member(X, [a,b,c]) -> false ; true ). X = d.
声明地说,我们希望添加约束导致特化,而不是程序的泛化!
因此,请谨慎使用(->)/2
:一般来说,它会破坏Prolog程序中最有价值的属性之一,即它们的关系性,允许您使用谓词在多个方向和模式。
如果可能,请使用纯Prolog子句或纯if_/3
谓词。另请参阅相关结构(*->)/2
和if/3
(在SICStus中)。