2009-12-05 2 views
2

나는 프롤로그에서 functor inbuilt를 쓰려고 노력했다. 내가 functor1과 같은 쿼리를 실행하면 내가이 버전의 Functor (Prolog)에서 잘못된 점은 무엇입니까?

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

무엇이 잘못 되었나요 예외가 여기에

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). 

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

이제 프롤로그 붙박이 펑의 샘플 실행이다 : 이것은 내 버전 내가 작성한 functor1 기능이 있습니까?

답변

2

문제는 Args가 아직 = ..에 대해 인스턴스화되지 않은 것입니다. 전에 lenlist/3을 넣으십시오.

현재, 내장 길이/2를 사용할 수도 있습니다.

+1

functor1 (Term, F, N) : 길이 (Args, N), Term = .. [F | Args],! --- This works –

+1

글쎄 나는 잘라 내기를해야했다. 다른 솔루션을 찾으러 가지 않기 때문이다. 그러나 더 이상 해결책을 강요 할 때 이상적으로는 "no"로 돌아 가야한다. 자르지 않으면 스택 밖으로 나옵니다 –

3

starblue는 정확하지만 제대로 functor1/3의 버전을 쓰기 위해, 나는 당신이 '모드'가 필요 고려하는 것이 좋습니다 :

  1. 기존의 용어를 (즉, 하지 검사를 변수) functor/arity 용입니다.
  2. 빌드 functor/arity 설명에서 용어를 (변수에 지정) 빌드하십시오.
  3. 다른 모든 모드는 부적절하거나 부정확합니다.

이러한 3 가지 경우를 염두에두고 다음을 시도하십시오. 첫째, 케이스 (1) : 기존 기간에서은 Functor와 arity에 압축을 풉니 계약 기간 인수가 절단의 변수가 아닌 경우 우리가 다른 경우를 제외

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

주의 (!). 둘째로, 케이스 (2) 모드가 절단 전의 서브 골 의한 검사 것을

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

참고이 경우의 가드 (전제)를 캡슐화 (!) 펑터 및 인수에 대응로부터 용어를 구성.

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

또는이 지난 경우에 대한이 : 마지막으로, 다른 모든 경우 (즉, 우리가 용어를 구성해야하지만 중 하나 펑, 인수에 대응하거나이없는 곳 사람들은) 무효 (3)이다 전체 절을 생략하면 functor/1이 처리 할 나머지 인수 바인딩에 대해 false를 반환하는 동작을 얻을 수 있습니다.

또한이 버전은 SWI-PROLOG에 존재하는 내장 기능 (다른 사람의 사이에서) length/2, var/1, number/1atom/1에 의존하고 있습니다.

+0

+1 세심한주의. 이것은 심각하게 훌륭한 * 대답입니다. – bcat

관련 문제