【问题标题】:Argument is not instantiated, need it to start at zero but also be able to change it参数未实例化,需要它从零开始,但也能够改变它
【发布时间】:2022-08-11 18:02:33
【问题描述】:

每当我运行我的代码时,我都会收到一个错误,即参数未实例化。

ads(X,Z):- mod(X,2) =:= 0, Z is Z+X.
ads(X,Z) :- mod(N,2) =\\= 0,Z is Z.

sum_of_nums(0,0,0).
sum_of_nums(X,Y,Z) :-  X=<Y, ad(X,Z), sum_of_nums(X+1,Y,Z).

我希望能够将数字从 X 添加到 Y,但只有偶数。不知道为什么它不起作用。

标签: prolog failure-slice instantiation-error


【解决方案1】:

首先,有一些微小的错误,你的编译器应该指出,比如第二个子句中不必要的单例变量。修复此问题并用广告替换广告后,我们有:

ad(X,Z):- mod(X,2) =:= 0, Z is Z+X.
ad(X,Z) :- mod(X,2) =\= 0,Z is Z.

sum_of_nums(0,0,0).
sum_of_nums(X,Y,Z) :-  X=<Y, ad(X,Z), sum_of_nums(X+1,Y,Z).

?- sum_of_nums(1,2,S).
   error(instantiation_error,(is)/2).

为了定位这个错误,我将插入一些目标false使得 结果程序仍然会产生这个实例化错误。

ad(X,Z):- mod(X,2) =:= 0, Z 是 Z+X,错误的.广告(X,Z):-错误的, mod(X,2) =\= 0,Z 是 Z.sum_of_nums(0,0,0) :-错误的.
sum_of_nums(X,Y,Z) :- X=<Y, ad(X,Z),错误的,sum_of_nums(X+1,Y,Z).

?- sum_of_nums(1,2,S)。
   错误(实例化错误,(是)/ 2)。

因此,您在这部分已经有一个错误。

这是Z is Z+X。在(is)/2的右边你永远 需要具有实例化(已知)的变量。而Z 不是 已知。

Prolog 中的变量有点不同。您不能重新分配它们。

而且,直接在 Prolog 中写这个并不能真正显示出什么 语言擅长。

sum_of(X, Y, 0) :-
   X > Y.
sum_of(X1, Y, Z1) :-
   X1 =< Y,
   ( X1 mod 2 =:= 0 -> S = X1 ; S = 0 ),
   X2 is X1+1,
   sum_of(X2, Y, Z2),
   Z1 is Z2+S.

更惯用的方式是:

?- between(1,6,N).
   N = 1
;  N = 2
;  N = 3
;  N = 4
;  N = 5
;  N = 6.
?- between(1,6,N), N mod 2 =:= 0.
   N = 2
;  N = 4
;  N = 6.
?- findall(N, ( between(1,6,N), N mod 2 =:= 0 ), Ns).
   Ns = [2,4,6].
?- findall(N, ( between(1,6,N), N mod 2 =:= 0 ), Ns), sum_list(Ns,Sum).
   Ns = [2,4,6], Sum = 12.

sum_of(X,Y,Sum) :-
   findall(N, ( between(X,Y,N), N mod 2 =:= 0 ), Ns),
   sum_list(Ns,Sum).

【讨论】:

  • 可能是您上一个定义中的错字? sum_of(X, Y, Z) 没有在任何地方引用 Z。
  • 或者,aggregate_all(sum(N), ( between(1,6,N), N mod 2 =:= 0 ), Sum).aggregate_all(sum(N), ( N mod 2 #= 0, between(1,6,N) ), Sum). 在其范围之前声明N 的均匀度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多