如何在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

我该如何实现它?

我想让它有一个初始状态、一条指令和一个最终状态"executed(actualState,instruction,nextState(",我想给它传递一个寄存器列表作为初始状态,例如"regs (1,2,3,4)"和一条指令,例如move和swap。swap(交换位置XX + 1(和move(复制X中的内容并将其存放在X + 1中(以及我希望它返回的内容,作为最终状态,是我的问题陈述中描述的示例。

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

  • 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)).。还有一些Prolog,如Ciao Prolog,没有nth1/3。然而,Ciao确实提供了具有相同行为的nth/3,因此它可以被取代。

请注意,我在这里使用CLP(FD(是为了更通用。如果您的系统不支持CLP(FD(,您可以使用is来代替#=,尽管这不太理想。

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

这里有一个交换的解决方案。关键是要列出=..的术语。剩下的就是对列表进行剖析并重新组合。根据这个答案,移动是小菜一碟,我把它"作为练习"留给

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

最新更新