【问题标题】:Prolog -- Arguments are not sufficiently instantiatedProlog -- 参数没有充分实例化
【发布时间】:2017-04-21 21:21:32
【问题描述】:

我试图通过计算玩家和列来检查游戏中的偶数/奇数玩家和偶数/奇数列。在某些时候,似乎我没有正确实例化我的变量。 这是我对游戏的称呼:

playGame(Game):- 
    countPlayers(Game,TotalPlayers),
    colSize(Game,TotalCols),
    checkEvens(TotalPlayers,TotalCols);
    checkOdds(TotalPlayers,TotalCols).

我认为问题在于未正确分配 TotalPlayers 和 TotalCols。

我尝试查看其他问题,但问题似乎有所不同。我是 prolog 新手,很可能在某个地方犯了一个小错误。

经过一些跟踪,当输入奇数/偶数的组合时,似乎会导致错误。给定两个偶数或两个奇数的输入,程序按预期运行。给定一个奇数和一个偶数的输入,它会中断。

完全错误:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [11] 1 is _34862 mod 2
ERROR:   [10] checkOdds(_34894,_34896)

【问题讨论】:

  • mod 运算符要求实例化它的所有参数。它不会在1 is X mod 2 中“解决 x”。您输入了什么查询?
  • 我正在传递球员和小队。这些在 columnsAndPlayers 谓词中作为 TotalPlayers 和 TotalCols 收集并传入。那么我假设这些变量没有被实例化?
  • 我不是在寻找一般描述。我的意思是当你收到错误时你输入了什么查询?而且,是的,您可以在错误消息中看到 Players 和 Cols 都没有被实例化(它们显示为匿名变量,_34894 和 _34896)。
  • 根据经验,不要将数字放在is/2 的左侧。 is/2 的操作语义是评估其右侧的算术表达式,然后将其数值与左侧的项统一。拥有1 is ..... 是没有意义的
  • 您的代码的另一个问题:所有这些括号都是完全不必要的,而且看起来很奇怪。如果你使用析取,你应该加上括号(;)。永远不要把这些写在行尾。

标签: prolog instantiation-error


【解决方案1】:
?- X = 3, between(1, X, 2), between(1, X, 3).
X = 3.

?- X = 3, between(1, X, 2); between(1, X, 3).
X = 3 ;
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:    [9] between(1,_7656,3)
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

你能看出发生了什么吗?


这样的谓词:

foo :- a, b; c.

与以下内容相同:

foo :- a, b.
foo :- c.

换句话说,a, b 确实与c 处于不同的“上下文”中。

通常,您的意思是说a, (b ; c)。这就是为什么; 通常放在行首,并且你确实在它周围使用了括号。所以它要么是

(   a,
    b
;   c
)

或

a,
(   b
;   c
)

(这不是一回事!)

这绝对令人困惑:

a,
b;
c

你看不到这样写的“好的”Prolog 代码(比如库代码)。

但实际上,尝试阅读教科书或其他东西,Stackoverflow 有助于找出错误在哪里,但不适合真正学习。

【讨论】:

  • 所以在这里,我认为 X 超出了第二个的范围,因为它已经执行了第一部分。
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多