我正在尝试将简单的Python program转换为Prolog。
我已经达到了move()
函数,并且在尝试执行基本列表操作时遇到了困难。
在Python中为move()
:
def move(kd,fot) :
k,d=kd
f,o,t=fot
if d[f]==1 and d[o]==1 and d[t]==0 :
c=list(d)
c[f]=0 # moved away
c[o]=0 # remove jumped over
c[t]=1 # landing here after jump
return (k-1,c)
else :
return None
这是我尝试的Prolog版本(以及其他上下文):
use_module(library(lists)).
moves(0,1,3).
moves(0,2,5).
moves(1,3,6).
moves(1,4,8).
moves(2,4,7).
moves(2,5,9).
moves(3,6,10).
moves(3,7,12).
moves(4,7,11).
moves(4,8,13).
moves(5,8,12).
moves(5,9,14).
moves(3,4,5).
moves(6,7,8).
moves(7,8,9).
moves(10,11,12).
moves(11,12,13).
moves(12,13,14).
step(Step, Reversed) :-
moves(F, O, T),
Step = [F, O, T],
Reversed = [T, O, F].
init(I, Board) :-
length(L0, 14),
maplist(=(1), L0),
nth0(I, Cells, 0, L0),
Board = [14, Cells].
move(Board, Move, BoardAfterMove) :-
[PegsLeft | [CellList]] = Board,
(step(Move, _); step(_, Move)),
PegsLeft > 2,
[F, O, T] = Move,
nth0(F, CellList, 1),
nth0(O, CellList, 1),
nth0(T, CellList, 0),
NewPegsLeft is PegsLeft-1,
nth0(F, NewCellList, 0),
nth0(O, NewCellList, 0),
nth0(T, NewCellList, 1),
nth0(I, CellList, V), % Questionable
I \= F, I \= O, I \= T, % Questionable
nth0(I, NewCellList, V), % Questionable
length(CellList, Length) = length(NewCellList, Length), % Questionable
BoardAfterMove = [NewPegsLeft, NewCellList].
我已将问题范围缩小到创建NewCellList
和使用length()
。
我要做的就是创建一个新列表,该列表是CellList
的副本,其中索引F
,O
和T
上的一些元素设置为不同值。
当前输出:
?- move([14,[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]], Move, Board).
Move = [3, 1, 0],
Board = [13, [1, 0, 1, 0|_G7261]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, 1|_G7267]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, 1|_G7270]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, 1|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
Move = [3, 1, 0],
Board = [13, [1, 0, _G7257, 0, _G7266, _G7269, _G7272|...]] ;
% (results for next move, [5, 2, 0] omitted)
所需的输出:
?- move([14,[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]], Move, Board).
Move = [3, 1, 0],
Board = [13, [1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]] ;
% (results for next move, [5, 2, 0] omitted)
基本上,此问题归结为在Prolog中执行以下操作:
c=list(d)
c[f]=0
c[o]=0
c[t]=1
我在做什么错了?
编辑
以下是应用于nth0/4
的答案(使用move()
的助手):
setat(P,LO,V,LN):-nth0(P,LO,_,T),nth0(P,LN,V,T).
move(Board, Move, BoardAfterMove):-
[PegsLeft | [CellList]] = Board,
(step(Move, _) ; step(_, Move)),
PegsLeft > 2,
[F, O, T] = Move,
nth0(F, CellList, 1),
nth0(O, CellList, 1),
nth0(T, CellList, 0),
NewPegsLeft is PegsLeft-1,
setat(F, CellList, 0, NewCellList0),
setat(O, NewCellList0, 0, NewCellList1),
setat(T, NewCellList1, 1, NewCellListFinal),
BoardAfterMove = [NewPegsLeft, NewCellListFinal].
编辑2
这是基于反馈的简化版本:
setat(Index, List, Val, OldVal, Result):-
nth0(Index, List, OldVal, BeforeSet),
nth0(Index, Result, Val, BeforeSet).
move(Board, Move, BoardAfterMove):-
[PegsLeft | [CellList]] = Board,
(step(Move, _) ; step(_, Move)),
PegsLeft > 2,
[F, O, T] = Move,
NewPegsLeft is PegsLeft-1,
setat(F, CellList, 0, 1, NewCellList0),
setat(O, NewCellList0, 0, 1, NewCellList1),
setat(T, NewCellList1, 1, 0, NewCellListFinal),
BoardAfterMove = [NewPegsLeft, NewCellListFinal].
编辑3
这是一个更简单的版本(PegsLeft> 2是不必要的):
move(Board, Move, BoardAfterMove):-
[PegsLeft | [CellList]] = Board,
(step(Move, _); step(_, Move)),
[F, O, T] = Move, NewPegsLeft is PegsLeft-1,
set_at(F, CellList, 0, 1, NewCellList0),
set_at(O, NewCellList0, 0, 1, NewCellList1),
set_at(T, NewCellList1, 1, 0, NewCellListFinal),
BoardAfterMove = [NewPegsLeft, NewCellListFinal].
谢谢!
答案 0 :(得分:2)
例如nth0 / 4:
?- [user].
|: setat(P,LO,V,LN) :- nth0(P,LO,_,T),nth0(P,LN,V,T).
% user://1 compiled 0.11 sec, 1 clauses
true.
?- setat(2,[a,b,c,d],0,R).
R = [a, b, 0, d].