0

我在要求我在 Prolog中实现经典的arg谓词的练习中遇到了一些麻烦。

arg(?Arg, +Term, ?Value)

其中 Arg 是 Term 参数列表中参数的索引。值它是这个参数的值。

例如:

arg(1, t(f(X),Y,a), Value)
Value = f(X).

因为 f(x) 它是 t 主函子的参数列表中的第一个参数。

所以我试图以这种方式使用 univ =.. 谓词来解决练习:

argom(ArgIndex,Term,ValueArg):- Term =.. [_|ArgsList],
                            element_n(ArgIndex,ArgsList,ValueArg).

element_n(1,[ValueArg,_],ValueArg).

element_n(N,[_,Tail],ValueArg):- N1 is N-1,
                                 element_n(N1,Tail,ValueArg).

其中argom关系是我个人对内置谓词arg的实现......

问题是解决方案不起作用......这个想法是我有一个argom谓词:

  1. ArgIndex:我将获得的参数的索引。
  2. 术语是一个表达式,如:f(a,b,c)
  3. ValueArg:表示以ArgIndex为索引的参数的值

所以,如果我有f(a,b,c)作为Term并且ArgIndex是 1,那么ArgValue必须是a

我使用unive内置谓词,从我的Term创建一个列表,其中头部是我的Term的主要仿函数,尾部(名为ArgsList)是主要仿函数的参数列表。

我将使用第 n 个参数,因此我将使用 ArgsList 中的第 n 个元素并获得它,我定义了element_n关系:ArgIndex、ArgsList、ValueArg。

如果我希望列表中的第一个元素ArgIndex值为 1 并且基本情况匹配:

 element_n(1,[ValueArg,_],ValueArg).

所以 ValueArg 在我的 ArgsList 参数列表的头部并统一它。

否则调用规则获取ArgsList中的第n个元素

问题是,当我咨询它不起作用时,答案总是:如果我尝试获取第一个元素也会失败(这是我使用基本案例规则的最简单情况)

查看跟踪我有同样的情况:

[trace] 9 ?- argom(1,f(a,b,c),a).
   Call: (6) argom(1, f(a, b, c), a) ? creep
   Call: (7) f(a, b, c)=..[_G3148|_G3149] ? creep
   Exit: (7) f(a, b, c)=..[f, a, b, c] ? creep
   Call: (7) element_n(1, [a, b, c], a) ? creep
   Fail: (7) element_n(1, [a, b, c], a) ? creep
   Fail: (6) argom(1, f(a, b, c), a) ? creep
false.

因此,它调用 argom 规则对它说:“主函子的第一个参数是 a 是真的吗?”

它以正确的方式使用univ =..内置谓词从我的 Term f(a, b, c)生成列表[f, a, b, c]

现在它调用element_n谓词,这是基本情况,因此必须将ValueArg列表的头部统一,但随后失败

我也尝试过问:如果 ArgIndex 值为 1 且 Term 为 f(a,b,c),ValueArg 的值是多少?

[trace] 10 ?- argom(1,f(a,b,c),ValueArg).
   Call: (6) argom(1, f(a, b, c), _G3483) ? creep
   Call: (7) f(a, b, c)=..[_G3553|_G3554] ? creep
   Exit: (7) f(a, b, c)=..[f, a, b, c] ? creep
   Call: (7) element_n(1, [a, b, c], _G3483) ? creep
   Fail: (7) element_n(1, [a, b, c], _G3483) ? creep
   Fail: (6) argom(1, f(a, b, c), _G3483) ? creep
false.

所以很明显,问题在于将列表的头部与此规则中的 ValueArg 统一起来似乎有些问题:

element_n(1,[ValueArg,_],ValueArg).

为什么?

4

1 回答 1

1

琐碎:是[Head|Tail],不是[Head,Tail]。这:[A,B]匹配一个二元素列表!

另请参阅此处....

于 2013-04-14T08:43:37.707 回答