Простой предикат nth1 в Прологе - PullRequest
4 голосов
/ 21 ноября 2010

В SWI Prolog есть предикат, который находит n-й элемент в списке с именем nth1.Я хочу реализовать свою собственную версию предиката, но SWI настолько сложны, если вы посмотрите на код листинга (nth1).Есть ли более простой способ сделать это?

Спасибо:).

Ответы [ 3 ]

4 голосов
/ 21 ноября 2010

Рассмотрите возможность использования ограничений конечной области для общей (обратимой) целочисленной арифметики:

:- use_module(library(clpfd)).

nth1(1, [E|_], E).
nth1(N, [_|Xs], E) :-
        N #> 1,
        N #= N1 + 1,
        nth1(N1, Xs, E).
2 голосов
/ 21 ноября 2010

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

Я сам это сейчас реализовал, но не могли бы вы, ребята, предложить улучшения или лучшие способы сделать это? В Прологе я часто пишу предикат с, скажем, счетчиком или набором счетчиков и получаю предикат с меньшим количеством аргументов, чтобы вызывать предложения с дополнительными аргументами. Это часто приводит к тому, что получается совсем немного кода. Во всяком случае, вот моя реализация, которую я только что сделал:

item_at( N, L, Item ) :-
    item_at( N, 0, L, Item ).   
item_at( N, Count, [H|_], Item ) :-
    CountNew is Count + 1,
    CountNew = N,
    Item = H.
item_at( N, Count, [_|T], Item ) :-
    CountNew is Count + 1,
    item_at( N, CountNew, T, Item ).

Есть комментарии? Спасибо :). Использование:

?- item_at(3,[a,b,c,d,e],Item).
Item = c ;
2 голосов
/ 21 ноября 2010

Код SWI немного сложен, потому что предикат можно использовать для генерации из индекса переменной:

?- nth1(Idx,[a,b,c],X).
Idx = 1,
X = a ;
Idx = 2,
X = b ;
Idx = 3,
X = c ;
false.

Если вы не хотите, чтобы такое поведение, nth1/3 может быть легко реализовано в терминахиз nth0:

nth1(Idx,List,X) :-
    Idx0 is Idx-1,
    nth0(Idx0,List,X).

Редактировать : также можно обойтись без nth0 всего в нескольких строках кода:

nth1(1,[X|_],X) :- !.
nth1(Idx,[_|List],X) :-
    Idx > 1,
    Idx1 is Idx-1,
    nth1(Idx1,List,X).
...