Как реализовать структуру данных в прологе - PullRequest
0 голосов
/ 06 мая 2020

У меня есть следующий предикат execute(actualState, instruction, nextState):- такой, что при выполнении с инструкциями: move, swap у меня есть следующие решения:

?- executed(regs(1,4,*,+,2), swap(1,2), NS).
solution:
NS = regs(4,1,*,+,2)?;
no


?- executed(regs(1,4,3,6,+), move(4), NS).
solution:
NS = regs(1,4,3,6,6)?;
no

Как я могу его реализовать?

я хочу, чтобы он имел начальное состояние, инструкцию и конечное состояние «выполнено (фактическое состояние, инструкция, nextState)», и я хочу передать ему список регистров в качестве начального состояния, например » regs (1,2,3,4) "и инструкция, например, переместить и поменять местами. swap (поменять местами X, X + 1) и переместить (скопировать то, что находится в X, и поместить его в X + 1), и то, что я хочу, чтобы он возвращал в качестве конечного состояния, - это примеры, описанные в заявлении моего вопроса.

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

Я бы выбрал следующий подход. Ключевые элементы этого решения:

  • Использование nth1/3 для рассмотрения элемента списка в указанной позиции

  • =../2 для отображения между термином с аргументами и списком

  • Предикат «подстановки», который заменяет значение в указанной позиции в списке другим

    subst([_|T], Y, 1, [Y|T]).
    subst([X|T], Y, N, [X|T1]) :-
        N #> 1,
        N1 #= N - 1,
        subst(T, Y, N1, T1).

    executed(AS, swap(X,Y), NS) :-
        AS =.. [regs|P],
        nth1(X, P, Xe),
        nth1(Y, P, Ye),
        subst(P, Ye, X, P1),
        subst(P1, Xe, Y, P2),
        NS =.. [regs|P2].

    executed(AS, move(X), NS) :-
        AS =.. [regs|P],
        nth1(X, P, Xe),
        X1 #= X + 1,
        subst(P, Xe, X1, P1),
        NS =.. [regs|P1].

Если вы используете пролог SWI, вам необходимо включить библиотеку clpfd, :- use_module(library(clpfd)).. Также некоторые прологи, такие как Ciao Prolog, не имеют nth1/3. Однако Ciao предоставляет nth/3 с таким же поведением, поэтому его можно заменить.

Обратите внимание, что здесь я использую CLP (FD) для большей общности. Если ваша система не поддерживает CLP (FD), вы можете использовать is вместо #=, хотя это менее желательно.

Обратите внимание, что это решение работает до тех пор, пока аргументы, индексирующие регистры, " в диапазоне". Так что это не сработает на executed(regs(1,2,+), move(3), NS).. В качестве упражнения, если это необходимо, вы должны попытаться улучшить это решение для удовлетворения этой потребности. Это поможет вам изучить Prolog, а не получить каждую деталь решения.

0 голосов
/ 07 мая 2020

Вот решение свопа. Ключ - это термин для списка =... Остальное - проанализировать список и собрать его обратно. Основанный на этом ответе Move - это несложно, и я оставил его «в качестве упражнения»

:- use_module(library(lists)).
executed(H,swap(X,Y),Result):-
    H =.. [regs|TH],
    LL1 is X-1,
    LL2 is Y-X-1,
    length(TH,LL),
    LL3 is LL-Y,
    length(L1,LL1),
    length(L2,LL2),
    length(L3,LL3),
    append(L1,LI1,TH),[EX|LIX]=LI1,append(L2,LI2,LIX),[EY|L3]=LI2,
    flatten([regs,L1,EY,L2,EX,L3],LR),
    Result =.. LR.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...