0

我想在没有 if then else 条件的情况下重新格式化我的代码。是否有捷径可寻?这只是一个代码示例。我认为在序言中使用 IF-THEN-ELSE 很奇怪:\ 而且我正在寻找更多递归案例。喜欢模式匹配

rules(Param1, Param2) :-
(
    A ->
        B, C, D,    
        (
            E ->  F
        ;
            G, H
        )    
    ;   
        I
).

编辑:编辑我的代码看起来更像它应该看起来的样子

4

2 回答 2

1

通用翻译方案

pred(X):-
  ( A -> B
  ; C -> D
  ; G
  ).
pred(Y):- Q.

pred(X):- pred1(X).
pred(Y):- Q.

pred1(X):- call(A), !, B.
pred1(X):- call(C), !, D.
pred1(X):- G.

非常感谢j4n bur53指出需要call-以防!AC

另请参阅->文档

于 2013-10-19T18:54:21.060 回答
0

if-then-else 并不奇怪。它们是 ISO 核心标准的一部分,在 7.8 控制结构、7.8.8 (;)/2 - if-then-else 中定义,它们的好处是存在各种 Prolog 编译方案。

在此处输入图像描述

如果 if-then-else 出现在子句的中间,这些 Prolog 编译策略特别有用,因为生成的代码通常比 if-then-else 移动到单独的辅助谓词中产生的开销更少。

析取 (;)/2 也是如此。根据经验,我会说这是安全的,如果没有 if-then-else 分支与其他分支相比引入了许多新变量。然后,当 Prolog 编译器将变量创建移到 if-then-else 之外时,它就有意义了。

这是一个示例,其中 if-then-else 在 YAP Prolog 中显示出优于其他编程风格的一些性能:

tarai_cut(X,Y,_,Y) :- X=<Y, !.
tarai_cut(X,Y,Z,R) :-
    X1 is X-1, tarai_cut(X1,Y,Z,Rx),
    Y1 is Y-1, tarai_cut(Y1,Z,X,Ry),
    Z1 is Z-1, tarai_cut(Z1,X,Y,Rz),
    tarai_cut(Rx,Ry,Rz,R).

tarai_or(X,Y,Z,R) :- X=<Y, !, R=Y;
    X1 is X-1, tarai_or(X1,Y,Z,Rx),
    Y1 is Y-1, tarai_or(Y1,Z,X,Ry),
    Z1 is Z-1, tarai_or(Z1,X,Y,Rz),
    tarai_or(Rx,Ry,Rz,R).

tarai_if(X,Y,Z,R) :- X=<Y -> R=Y;
    X1 is X-1, tarai_if(X1,Y,Z,Rx),
    Y1 is Y-1, tarai_if(Y1,Z,X,Ry),
    Z1 is Z-1, tarai_if(Z1,X,Y,Rz),
    tarai_if(Rx,Ry,Rz,R). 

if-then-else 版本运行速度最快:

   YAP 6.3.3 (i686-mingw32): Sun Jan 20 18:27:56 GMTST 2013

   ?- time(tarai_cut(12,6,0,X)).
   % 0.687 CPU in 0.690 seconds ( 99% CPU)
   X = 12

   ?- time(tarai_or(12,6,0,X)).
   0.734 CPU in 0.735 seconds ( 99% CPU)
   X = 12

   ?- time(tarai_if(12,6,0,X)).
   % 0.515 CPU in 0.516 seconds ( 99% CPU)
   X = 12
于 2019-04-01T19:31:03.800 回答