Prolog - 平均谓词:未充分实例化的参数
Prolog - average predicate: Arguments not sufficiently instantiated
我有一个汽车列表(德语为 auto),其中第一个变量是车牌,第二个变量是速度:
[auto(eu-ts884, 69), auto(dn-gh184, 64), auto(ac-lj123, 72)].
现在我尝试编写一个平均谓词,但失败并显示错误消息:
ERROR: Arguments are not sufficiently instantiated
到目前为止我的代码:
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.
我的代码与 post 完全相同,尽管我无法找出我的错误。
注意:sumKilometer
和 cardinal
工作正常。
你写:
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
,因为 S
和 L
在这里都是未知的。
但是您可以使用:
durchschnitt([], 0, 0).
durchschnitt([auto(_, X)|Tail], L, Y):-
cardinal([auto(_, X)|Tail], L),
sumKilometer([auto(_, X)|Tail], S),
<b>Y is S/L</b>.
因此这里计算 在 L
和 S
都已知后的平均值。此外,您没有将列表与 [auto(_,X)|Tail]
等统一。像 A = [_|_]
这样的简单检查就足够了:
durchschnitt([], 0, 0).
durchschnitt(<b>A</b>, L, Y):-
<b>A = [_|_],</b>
cardinal(<b>A</b>, L),
sumKilometer(<b>A</b>, S),
Y is S/L.
这也将减少打包和解包所花费的时间。
同时求和、长度和平均值
您可以构造一个同时计算这三个的谓词(因此无需在列表上循环两次)。您可以简单地使用 accumulators,例如:
durchschnitt(A,L,Y) :-
durchschnitt(A,0,0,L,Y).
这里第二个和第三个元素分别是运行和和长度
现在durchschnitt/5
,有两种情况。在第一种情况下,我们已经到达列表的末尾,因此我们必须计算平均值并 return 它,例如:
durchschnitt([],S,L,L,Y) :-
(L \= 0
-> Y is S/L
; Y = 0).
所以我们使用 if-then-else 来检查长度是否与 0
不同(如果列表中没有 auto
,我们 return 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).
我有一个汽车列表(德语为 auto),其中第一个变量是车牌,第二个变量是速度:
[auto(eu-ts884, 69), auto(dn-gh184, 64), auto(ac-lj123, 72)].
现在我尝试编写一个平均谓词,但失败并显示错误消息:
ERROR: Arguments are not sufficiently instantiated
到目前为止我的代码:
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.
我的代码与 post 完全相同,尽管我无法找出我的错误。
注意:sumKilometer
和 cardinal
工作正常。
你写:
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
,因为 S
和 L
在这里都是未知的。
但是您可以使用:
durchschnitt([], 0, 0).
durchschnitt([auto(_, X)|Tail], L, Y):-
cardinal([auto(_, X)|Tail], L),
sumKilometer([auto(_, X)|Tail], S),
<b>Y is S/L</b>.
因此这里计算 在 L
和 S
都已知后的平均值。此外,您没有将列表与 [auto(_,X)|Tail]
等统一。像 A = [_|_]
这样的简单检查就足够了:
durchschnitt([], 0, 0).
durchschnitt(<b>A</b>, L, Y):-
<b>A = [_|_],</b>
cardinal(<b>A</b>, L),
sumKilometer(<b>A</b>, S),
Y is S/L.
这也将减少打包和解包所花费的时间。
同时求和、长度和平均值
您可以构造一个同时计算这三个的谓词(因此无需在列表上循环两次)。您可以简单地使用 accumulators,例如:
durchschnitt(A,L,Y) :-
durchschnitt(A,0,0,L,Y).
这里第二个和第三个元素分别是运行和和长度
现在durchschnitt/5
,有两种情况。在第一种情况下,我们已经到达列表的末尾,因此我们必须计算平均值并 return 它,例如:
durchschnitt([],S,L,L,Y) :-
(L \= 0
-> Y is S/L
; Y = 0).
所以我们使用 if-then-else 来检查长度是否与 0
不同(如果列表中没有 auto
,我们 return 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).