1

我有一个汽车列表(德语为 auto),其中第一个变量是车牌,第二个变量是速度:

[auto(eu-ts884, 69), auto(dn-gh184, 64), auto(ac-lj123, 72)].

现在我尝试编写一个平均谓词,但它失败并显示错误消息:

错误:参数没有充分实例化

到目前为止我的代码:

durchschnitt([], 0, 0).
durchschnitt([auto(_, X)|Tail], L, Y):-
                        Y is S/L,
                        L > 0,
                        cardinal([auto(_, X)|Tail], L),
                        sumKilometer([auto(_, X)|Tail], S).


sumKilometer([], 0).
sumKilometer([auto(_, X)|Tail], Sum) :-
            sumKilometer(Tail, N),
            Sum is N + X.


cardinal([], 0).
cardinal([_|Tail], Result) :-
  cardinal(Tail, N),
  Result is N + 1.

我的代码与那篇文章完全等效,尽管我无法弄清楚我的错误。

注意sumKilometer并且cardinal工作正常。

4

1 回答 1

2

你写:

durchschnitt([], 0, 0).
durchschnitt([auto(_, X)|Tail], L, Y):-
    Y is S/L,
    L > 0,
    cardinal([auto(_, X)|Tail], L),
    sumKilometer([auto(_, X)|Tail], S).

第一个问题是,当你调用时durchschnitt([auto(foo,2)],L,Y)L是一个自由变量。因此,您无法计算Y is S/L,因为两者SL这里都是未知的。

但是,您可以使用:

durchschnitt([], 0, 0).
durchschnitt([auto(_, X)|Tail], L, Y):-
    cardinal([auto(_, X)|Tail], L),
    sumKilometer([auto(_, X)|Tail], S),
    Y is S/L.

所以在这里你计算两者后的平均值LS都是已知的。此外,您不会将列表与[auto(_,X)|Tail]等统一起来。像这样的简单检查A = [_|_]就足够了:

durchschnitt([], 0, 0).
durchschnitt(A, L, Y):-
    A = [_|_],
    cardinal(A, L),
    sumKilometer(A, S),
    Y is S/L.

这也将减少打包拆包所花费的时间。

总和、长度和平均值同时进行

您可以构造一个同时计算这三个的谓词(因此无需在列表上循环两次)。您可以简单地使用accumulators,例如:

durchschnitt(A,L,Y) :-
    durchschnitt(A,0,0,L,Y).

这里第二个和第三个元素分别是运行总和和长度。

现在对于durchschnitt/5,有两种情况。在第一种情况下,我们已经到达列表的末尾,因此我们必须计算平均值并返回它,例如:

durchschnitt([],S,L,L,Y) :-
    (L \= 0
    -> Y is S/L
    ; Y = 0).

所以我们使用 if-then-else 来检查长度是否不同于0(如果列表中没有autos,我们返回0平均值。

在递归情况下,我们简单地增加运行长度并更新运行总和,例如:

durchschnitt([auto(_,Si)|T],RS,RL,L,Y) :-
    RSN is RS+Si,
    L1 is L+1,
    durchschnitt(T,RSN,L1,L,Y).

或者把它放在一起:

durchschnitt(A,L,Y) :-
    durchschnitt(A,0,0,L,Y).

durchschnitt([],S,L,L,Y) :-
    (L \= 0
    -> Y is S/L
    ; Y = 0).
durchschnitt([auto(_,Si)|T],RS,RL,L,Y) :-
    RSN is RS+Si,
    L1 is L+1,
    durchschnitt(T,RSN,L1,L,Y).
于 2017-03-23T17:14:54.453 回答