这个版本的仿函数(Prolog)有什么问题?

时间:2009-12-05 08:04:18

标签: prolog

我试着在Prolog中编写functor。这是我的版本:

lenlist(L,N) :- lenlist(L,0,N).
lenlist([],N,N).
lenlist([_|T],P,N) :- P1 is P+1 , lenlist(T,P1,N).

functor1(Term,F,N) :- Term =.. [F|Args] , lenlist(Args,N).

以下是Prolog内置函子的示例执行

?- functor(Term,f,6).  
Term = f(_G247, _G248, _G249, _G250, _G251, _G252)

现在,如果我使用functor1执行相同的查询,我会收到异常

?- functor1(Term,f,6).
ERROR: =../2: Arguments are not sufficiently instantiated
   Exception: (8) _G180=..[f|_G248] ? creep

我写的functor1函数有什么问题?

2 个答案:

答案 0 :(得分:4)

starblue 是正确的,但为了正确编写您的functor1/3版本,我建议您考虑所需的“模式”:

  1. 检查现有术语(即变量)是否为functor / arity。
  2. 从仿函数/ arity描述构建一个术语(将其赋值给变量)。
  3. 所有其他模式都不相关/不正确。
  4. 考虑到这三个案例,请尝试以下方法。首先,情况(1):从现有术语中提取Functor和Arity:

    functor1(Term, Functor, Arity) :-
        \+ var(Term), !,
        % inspect existing term
        Term =.. [Functor|ArgList],
        length(ArgList, Arity).
    

    请注意,如果Term参数不是带cut(!)的变量,我们会排除其他情况。其次,案例(2):构建一个来自Functor和Arity的术语:

    functor1(Term, Functor, Arity) :-
        var(Term), 
        atom(Functor),
        number(Arity), !,
        % build a term
        length(ArgList, Arity),
        Term =.. [Functor|ArgList].
    

    请注意,切换前的子目标执行的模式检查(!)封装了此情况下的保护(前置条件)。最后,所有其他情况(即我们需要构建一个术语,但没有仿函数,或者任何一个)的情况都是无效的(3):

    functor1(_Term, _Functor, _Arity) :-
        throw('Arguments are not sufficiently instantiated.').
    

    或者,对于最后一种情况,可以省略整个子句,以实现functor/1为其将覆盖的其余参数绑定返回false的行为。

    另请注意,此版本依赖于SWI-PROLOG中存在的内置插件length/2var/1number/1atom/1(以及其他内容)。< / p>

答案 1 :(得分:2)

问题是Args尚未实例化= ..尝试将lenlist / 3放在它之前。

顺便说一下,你也可以使用内置长度/ 2。