5

在 c 语言中,我有类似的东西:

if(cond1)
{}
else if(cond2)
{}
else
{}

这在 Prolog 中怎么可能?

4

5 回答 5

9
(   If1 -> Then1
;   If2 -> Then2
;   ...
;   otherwise
).

请注意,if-then-else 仅在您无法通过不同子句中的模式匹配来表达不同条件时才需要。可以通过模式匹配表达的一切都应该通过模式匹配来表达,因为这通常会导致更通用和更高效的代码。

于 2012-04-12T11:42:01.460 回答
7
(cond1 ->
    consequent1
; cond2 ->
    consequent2
;
    alternative
)

为了记录,这被称为条件

于 2012-04-12T11:40:21.253 回答
2

->/2 仅在您想强加某种确定性时才需要。它的作用类似于局部切割。但是如果你希望你的代码保持一些非确定性,就没有必要使用 ->/2。

采用以下命令式代码:

boolean listOfBool(Object obj) {
   if (obj instanceof ConsCell) {
       if (((ConsCell)ob).head() instanceof Boolean) {
           return listOfBool(((ConsCell)ob).tail());
       } else {
           return false;
       }
  } else if (obj == null) {
       return true;
  } else {
       return false;
  }

}

这可以在没有 ->/2 的 Prolog 中编码,如下所示:

% bool(+Bool)
% bool(-Bool)
bool(0).
bool(1).

% list_of_bool(+List)
% list_of_bool(-List)
list_of_bool(L) :-
    (L = [X|Y], bool(X), list_of_bool(Y);
     L = []).

现在的优点是它可以用于检查布尔值列表并生成布尔值列表:

?- list_of_bool([0,1,0]).
Yes 
?- list_of_bool([0,1,2]).
No
?- List=[_,_,_], list_of_bool(List).
List = [0, 0, 0] ;
List = [0, 0, 1] ;
List = [0, 1, 0] ;
List = [0, 1, 1] Etc..

通常,析取 (;)/2 可以分布在多个子句中。如果这与将统一 (=)/2 移动到头部相结合,则可以获得一些速度,因为谓词通常更适合索引。

下面是通过消除 (;)/2 和 (=)/2 来替代 list_of_bool 公式的样子:

% list_of_bool2(+List)
% list_of_bool2(-List)
list_of_bool2([X|Y]) :- bool(X), list_of_bool2(Y).
list_of_bool2([]).

上面的工作方式完全相同(它实际上工作得更好,因为在第一个查询中没有留下选择点,如果没有 (->)/2,(;)/2 通常不会检测到什么):

?- list_of_bool2([0,1,0]).
Yes
?- list_of_bool2([0,1,2]).
No
?- List=[_,_,_], list_of_bool(List).
List = [0, 0, 0] ;
List = [0, 0, 1] ;
List = [0, 1, 0] ;
List = [0, 1, 1] Etc..

这也是 Prolog 的启动方式。只有规则,没有析取(;)/2,没有统一(=)/2。后面的两个已经存在于底层的 Horn 子句中。

假设您有一个没有 (;)/2 且没有 (=)/2 的 Prolog,并且您不需要剪切透明 (;)/2,那么您可以自己定义这些构造如下:

X = X.

(A ; _) :- A.
(_ ; B) :- B.

再见

号角条款
http://en.wikipedia.org/wiki/Horn_clause

于 2012-04-12T19:51:00.083 回答
1

这并不容易找到,部分原因是(正如@mat 所指出的)Prolog 中有一个惯用的替代方案。您可以在此处找到SWI-Prolog 文档,尽管过于简洁,但它是准确的。我引用一个相关的观点:

请注意 (If -> Then) 充当 (If -> Then ; fail),如果条件失败,则使构造失败。这种不寻常的语义是 ISO 和所有事实上的 Prolog 标准的一部分。

于 2012-04-12T12:58:42.617 回答
0
if_then_else(Condition,Then,Else) :- Condition, !, Then.
if_then_else(Condition,Then,Else) :- Else.

例如:

max(X,Y,Max) :- if_then_else(X>Y,Max=X,Max=Y).

?- max(4,7,A).
A = 7
?- max(8,2,A).
A = 8
于 2018-09-28T08:51:22.080 回答