How to implement data structure in prolog

Deadly 提交于 2020-05-17 06:48:06

问题


I have the following predicate execute(actualState, instruction, nextState):- such that when executing with the instructions: move, swap , i have the following solutions:

?- 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

How can I implement it?

what I want it to do is that it has an initial state, an instruction and a final state "executed (actualState, instruction, nextState)" and what I want to do is pass it a list of registers as initial state, for example "regs (1,2,3,4)" and an instruction, for example, move and swap. swap (swap the position X, X + 1) and move (copy what is in X and deposit it in X + 1) and what I want it to return, as final state, are the examples described in the statement of my question.


回答1:


I would take the following approach. The key elements of this solution are:

  • Use of nth1/3 for considering an element of a list at a specified position

  • =../2 for mapping between a term with arguments and a list

  • A "substitution" predicate that substitutes a value at specified position in a list with another

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

If you are using SWI prolog, you'll need to include the clpfd library, :- use_module(library(clpfd)).. Also some Prologs, such as Ciao Prolog, does not have nth1/3. Ciao does provide, however, nth/3 which has the same behavior, so it may be substituted.

Note that I'm using CLP(FD) here for more generality. If your system doesn't support CLP(FD) you can use is in place of #=, although it's less desirable.

Note that this solution works as long as the arguments indexing the registers are "in range". So it will fail on executed(regs(1,2,+), move(3), NS).. As an exercise, if this is required, you should try to enhance this solution to meet that need. It will help you to learn Prolog versus being given every detail of the solution.




回答2:


Here is a solution of swap. The key is term to list =... The rest is to dissect the list and put it back together. Move is a piece of cake based on this answer and I left it "as an exercise"

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


来源:https://stackoverflow.com/questions/61639909/how-to-implement-data-structure-in-prolog

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!