首页 > 解决方案 > Prolog if then else 逻辑(错误:操作员优先级冲突)

问题描述

我是 prolog 的新手,所以要练习一下。我现在对第 5 行的错误感到困惑Syntax error: Operator priority conflict。这可能是由于逻辑的嵌套,但我想知道是否有办法使这种嵌套工作。

loopOver3(elt1, elt3, [H|T], sum):-
    ( =(elt1, elt2) =:= true ->  
      sum is sum + (elt1 + elt2),
      ;   =(elt1, elt2) =\= false -> ( =(elt1, H) =:= true ->  
            sum is sum + (elt1 * H),
            ;  =(elt1, H) =\= false -> ( =(elt2, H) =:= true ->  
                    ( \=(H, 0) =:= true ->
                      sum is sum + (100 / H)
                    )
                )
          )
    )
    loopOver3(elt1, elt3, T, sum).

我正在尝试做的 Sudo 代码:

for elt3 in list3: 
    if elt1 == elt2: 
        sum = sum + (elt1 + elt2) 
    else: 
        if elt1 == elt3: 
            sum = sum + (elt1 * elt3) 
        else: 
            if (elt2 == elt3) and (elt3 != 0): 
                sum = sum + (100 / elt3)

标签: prolog

解决方案


你需要做一些工作来理解 Prolog 中的概念。您最初的尝试充满了原子(小写)而不是变量(大写)。它具有可变性。你认为 Prolog 有返回值的函数(它有谓词)(它们没有——它们要么成功,要么失败)。

我假设您要从列表中剥离前三个值,然后删除第一项并向下递归。

所以,如果我有这个列表[1,2,1,2],我会先看[1,2,1],然后再看[2,1,2]

或者,在这个更长的例子中:

[1,2,1,2,2,1,1] => [1,2,1]
[2,1,2,2,1,1] => [2,1,2]
[1,2,2,1,1] => [1,2,2]
[2,2,1,1] => [2,2,1]
[2,1,1] => [2,1,1]

只要列表只有 2 个元素,我就可以停止。

我假设三个值列表中的每一个都是您的[Elt1, Elt2, Elt3].

为了计算这个,我们需要一个输入列表和一个输出总和,但是为了向下递归列表,我们需要一个累加器来跟踪当前的总和。第一个谓词很简单:

compute(List,Sum) :- compute(List,0,Sum).

现在,您有 5 个我们必须匹配的谓词。

  1. 包含 2 个元素的列表 - 我们可以返回我们的累加器
  2. Elt1 = Elt2然后sum = sum + (elt1 + elt2)
  3. Elt1 = Elt3然后sum = sum + (elt1 * elt3)
  4. Elt2 = Elt3然后Elt3 \= 0_sum = sum + (100 / elt3)
  5. 以上都不是,所以我们只是传递当前的累加器,即sum = sum
compute([_,_],Sum,Sum).

compute([Elt1,Elt2,Elt3|Tail],AccNow,Sum) :-
    Elt1 = Elt2,
    !,
    AccNext is AccNow + Elt1 + Elt2,
    compute([Elt2,Elt3|Tail],AccNext,Sum).

compute([Elt1,Elt2,Elt3|Tail],AccNow,Sum) :-
    Elt1 = Elt3,
    !,
    AccNext is AccNow + Elt1 * Elt3,
    compute([Elt2,Elt3|Tail],AccNext,Sum).

compute([_,Elt2,Elt3|Tail],AccNow,Sum) :-
    Elt3 \= 0,
    Elt2 = Elt3,
    !,
    AccNext is AccNow + 100 / Elt3,
    compute([Elt2,Elt3|Tail],AccNext,Sum).

compute([_,Elt2,Elt3|Tail],Acc,Sum) :-
    compute([Elt2,Elt3|Tail],Acc,Sum).  

如果我试试这个,?- compute([1,2,1,2],X).我会得到X = 5。那是在Elt1 = Elt3谓词上匹配并给我0 + 1 * 1,然后再在Elt1 = Elt3谓词上给我1 + 2 * 2or 5

如果我试试这个,?- compute([1,2,1,2,2,1,1],X).我会得到X = 159。我会把它留给你,看看它是否是正确的结果。

请记住,Prolog 所要做的就是成功。如果要求证明一个目标(即compute/3),它会找到第一个匹配的谓词并尝试证明(通过证明任何子目标),当它失败时,它只是回溯到前一个选择点并尝试另一个选择并继续。如果它证明了最初的目标,那么它就成功了。如果没有,那么它就失败了。没有返回值 - 只有绑定变量。


推荐阅读