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