语法错误:尝试比较时预期的运算符

时间:2013-10-14 03:41:07

标签: prolog

我试图将S1与A1,S2与A2,...,S5与A5进行比较,并获得彼此匹配的对的总数。但是解释器显示“语法错误,运算符预期”。有没有简单的方法来解决这个问题,我的代码有什么问题?谢谢!

grade(S1, S2, S3, S4, S5, A1, A2, A3, A4, A5, N):-
   S1 = A1, grade2(S2, S3, S4, S5, A2, A3, A4, A5, N+1).

grade(S1, S2, S3, S4, S5, A1, A2, A3, A4, A5, N):-
   \+ S1=A1, grade2(S2, S3, S4, S5, A2, A3, A4, A5, N).

grade2(S2, S3, S4, S5, A2, A3, A4, A5, N):-
   S2=A2, grade3(S3, S4, S5, A3, A4, A5, N+1).

grade2(S2, S3, S4, S5, A2, A3, A4, A5, N):-
   \+ S2=A2, grade3(S3, S4, S5, A3, A4, A5, N).

grade3(S3, S4, S5, A3, A4, A5, N):-
   S3=A3, grade4(S4, S5, A4, A5, N+1).

grade3(S3, S4, S5, A3, A4, A5, N):-
   \+ S3=A3, grade4(S4, S5, A4, A5, N).

grade4(S4, S5, A4, A5, N):-
   S4=A4, grade5(S5, A5, N+1).

grade4(S4, S5, A4, A5, N):-
   \+ S4=A4, grade5(S5, A5, N).

grade5(S5, A5, N):-
   S5=A5, N is 1. 

grade5(S5, A5, N):-
   \+ S5=A5, N is 0.

3 个答案:

答案 0 :(得分:1)

使用SWI-Prolog和模块lambda,你可以写:

:- use_module(library(lambda)).

grade(S1, S2, S3, S4, S5, A1, A2, A3, A4, A5, N) :-
    foldl(\X^Y^Z^T^(X = Y ->  T is Z+1 ;   T = Z),
         [S1, S2, S3, S4, S5],
         [A1, A2, A3, A4, A5],
         0, N).

答案 1 :(得分:0)

我无法重现您的错误。但是,因为现在它无法工作,因为你计算N的值的方式。如果你做了跟踪,你应该能够看到它出错的地方。

无论如何,虽然你似乎事先知道你要比较多少对,但更通用的方法是将这些对放在两个列表中,甚至更好,放在一对列表中:

[S1-A1, S2-A2, ...]

-这里只是一种写-(S, A)的方式,以及通常的Prolog方式来表示"对"。一旦对象列表采用这种形式,您就可以明确地写下:

grade([], 0).
grade([S-A|Rest], N) :-
    (   S == A
    ->  Add = 1
    ;   Add = 0
    ),
    grade(Rest, N0),
    N is N0 + Add.

请注意,除非您有额外的参数来收集到目前为止的结果,否则不能使用尾递归:

grade([], N, N).
grade([S-A|Rest], Acc, N) :-
    (   S == A
    ->  NewAcc is Acc + 1
    ;   NewAcc = Acc
    ),
    grade(Rest, NewAcc, N).

(你需要"在调用谓词时初始化"累加器)

?- grade(List, 0, N).

所以对你的情况来说:

  • 使用您的初始方法,但使用显示的两种方法中的任何一种来确定如何计算N
  • 将您的对列表表示为实际的对列表
  • 如果您正在使用列表,则还有其他可用技术,例如,请参阅库(聚合)。对于更复杂的同类问题可能有用。

答案 2 :(得分:0)

我的代码没有出现任何语法错误,但无法执行:您的第一条规则(例如)应该读取

grade(S1, S2, S3, S4, S5, A1, A2, A3, A4, A5, N):-
  S1 = A1, grade2(S2, S3, S4, S5, A2, A3, A4, A5, M),
  N is M+1.

你在唯一无用的地方使用了/ 2。最后一条规则可以阅读

grade5(S5, S5, 1):-!.
grade5(_, _, 0).

然后对于一些更容易阅读的代码(了解太多无用细节的代码对我的可怜的大脑有害......),使用库(聚合)

grade(S1, S2, S3, S4, S5, A1, A2, A3, A4, A5, N):-
  aggregate_all(count,
    (nth1(I,[S1,S2,S3,S4,S5],X),
     nth1(I,[A1,A2,A3,A4,A5],X)
    ), N).

我得到了

4 ?- grade(a,b,c,d,e, u,v,c,d,x, N).
N = 2.