Является ли предикат с переменной арностью допустимым в Прологе? - PullRequest
3 голосов
/ 28 ноября 2011

Возможно ли иметь «предикат переменной арности» в Прологе?

Я имею в виду что-то вроде этого:

my_predicate( [a,b,c], [a,c], [a], [a,b,c,d], N, RESULT)

с количеством начальных списков, неизвестных в начале?1006 *

Используя оператор univ (= ..), можно объединить его со списком терминов и обходить его, как и любой другой список.Но как написать цель?

my_predicate(??) =.. [??]

Я действительно не знаю, возможно ли это вообще ..

Ответы [ 3 ]

5 голосов
/ 28 ноября 2011

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

foo(1).
foo(2,1).

?-foo(2).
false

Я предлагаю изменить кодировку;вместо нескольких начальных списков, иметь список начальных списков.
другое решение будет писать предикаты для всех возможных чисел аргументов (или динамически генерировать их).

4 голосов
/ 29 ноября 2011

Как подсказывает @thanosQR, вероятно, лучше всего изменить свое представление на какой-то список.

Однако есть - очень редко, но тем не менее - ситуации, когда вы хотите определить предикат для множества различных артиклей.В этом очень редком случае вы можете определить такой предикат вручную.То есть для каждой арности вручную.Конечно, вы будете определять только несколько случаев.В качестве примера см. library (lambda) .

2 голосов
/ 29 ноября 2011

Вы всегда можете подняться на один уровень :) Много лет назад я видел реализацию интерпретатора прологов ANSI в Turbo Prolog.Идея была очень простой, заключить все факты и правила в пользовательском пространстве в единый факт, подкрепленный операциями типа assert / retract.

Рассмотреть возможность включения всех ваших целей в другую композицию:

target(my_predicate( [a,b,c], [a,c], [a], [a,b,c,d], N, RESULT)) :- RESULT=[a], N=1.
target(H) :- H =.. [my_predicate|_].
target(using_my_predicate(X, Y)) :- target(my_predicate(X,1,Y)).

НекоторыеПрологи (по крайней мере, YAP) имеют директивы для объявления обработчиков для неизвестных целей:

:- module(sumtest).

target(sum(0)).
target(H) :-
    H =.. [sum, S, X|XS],
    H1 =.. [sum, S1|XS],
    H1,
    S is (S1+X).

target(sumtest:G):- target(G). % HACK: strip-off module

:- unknown(_, target(_)).

test:-
    sum(X,1), write(X), nl,
    sum(Y,2,3), write(Y), nl,
    sum(Z,3,4,2), write(Z), nl,
    target(sum(X1,1)), write(X1), nl,
    target(sum(Y1,2,3)), write(Y1), nl,
    target(sum(Z1,3,4,2)), write(Z1), nl.


:- test, halt.
% % yap -l sumtest.pl
% YAP 6.2.0 (amd64): Thu Oct 21 10:31:27 EEST 2010
% MYDDAS version MYDDAS-0.9.1
% 1
% 5
% 9
% 1
% 5
% 9
%  % YAP execution halted
...