如果那么删除Prolog

时间:2013-10-19 18:45:21

标签: recursion prolog conditional-statements

我想在没有if then else条件的情况下重新格式化我的代码。是否有捷径可寻?这只是代码的例子。我认为在prolog中使用IF-THEN-ELSE很奇怪:\而且我希望得到一些更复杂的案例。像模式匹配

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

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

2 个答案:

答案 0 :(得分:2)

的一般翻译方案
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指出在callA内需要C - in case there's a cut

另见-> documentation

答案 1 :(得分:0)

如果不是那么真的不是很奇怪。它们是ISO核心标准的一部分,在7.8控制结构7.8.8(;)/ 2-if-then-else中定义,它们的优点是存在各种Prolog编译方案。

enter image description here

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

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

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

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