我在练习中遇到一些麻烦,要求我在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 谓词:
所以,如果 f(a,b,c)为 Term 且 ArgIndex 为1,那么 ArgValue < / strong>必须 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规则对它说:“主仿函数的第一个参数是一个吗?”
以正确的方式使用 univ = .. 内置谓词从我的术语 f生成列表 [f,a,b,c] (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).
为什么?