首页 > 解决方案 > prolog中如何实现数据结构

问题描述

我有以下谓词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)" 和一个指令,例如,移动和交换。交换(交换位置XX + 1)和移动(复制其中的内容X并将其存入X + 1)以及我希望它作为最终状态返回的内容是我的问题陈述中描述的示例。

标签: prolog

解决方案


我会采取以下方法。该解决方案的关键要素是:

  • 用于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 prolog,则需要包含 clpfd 库,:- use_module(library(clpfd)).. 还有一些 Prologs,比如 Ciao Prolog,没有nth1/3. 但是,Ciao 确实提供nth/3了具有相同行为的功能,因此可以替换它。

请注意,我在这里使用 CLP(FD) 以获得更多通用性。如果您的系统不支持 CLP(FD),您可以使用is代替#=,尽管它不太理想。

请注意,只要索引寄存器的参数在“范围内”,此解决方案就可以工作。所以它会失败executed(regs(1,2,+), move(3), NS).。作为练习,如果需要,您应该尝试增强此解决方案以满足该需求。它将帮助您学习 Prolog,而不是获得解决方案的每个细节。


推荐阅读