Что не так с этой версией функтора (Пролог)? - PullRequest
3 голосов
/ 05 декабря 2009

Я пытался написать функтор, встроенный в Пролог. Это моя версия:

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 ]

4 голосов
/ 09 декабря 2009

starblue правильно, но для того, чтобы правильно написать свою версию functor1/3, я рекомендую вам рассмотреть «режимы», для которых она требуется:

  1. Проверьте существующий термин (т. Е. , а не переменная) на предмет его функтора / арности.
  2. Построить термин (присвоение его переменной) из описания функтора / арности.
  3. Все остальные режимы не имеют значения / неверны.

С учетом этих трех случаев попробуйте следующее. Во-первых, case (1): извлечь Functor и Arity из существующего термина:

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

Обратите внимание, что мы исключаем другие случаи, если аргумент Term не является переменной с разрезом (!). Во-вторых, случай (2): построить термин из функтора и 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 для оставшихся привязок аргументов, которые он будет охватывать.

Также обратите внимание, что в этой версии используются встроенные модули length/2, var/1, number/1 и atom/1 (среди прочих), которые присутствуют в SWI-PROLOG.

2 голосов
/ 05 декабря 2009

Проблема в том, что Args еще не создан для = ... Попробуйте поставить lenlist / 3 перед ним.

Кстати, вы также можете использовать встроенную длину / 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...