我正在尝试在Prolog中执行for循环,但这不起作用。该计划应该做到以下:
generate(N,[S,E],FinalSegments):-
segments([S,E],Initialsegments),
iterate_level(N,Initialsegments,FinalSegments).
当我调用generate(5,[(10,0),(-10,0)])
时,第一步是,generate(5,[(10,0),(-10,0)],FinalSegments)
被调用,此谓词在Startpoint (10,0)
和Endpoint (-10,0)
之间生成4个坐标,并将这四个ccordinates存储在列表FinalSegments
中。这实际上是正确完成的。在下一步中,将调用谓词iterate_level(N,Initialsegments,FinalSegments)
。
谓词iterate_level()
将最后一步中的四个坐标作为名为Initialsegments
的列表:
Initialsegments:([[ (10, 0), (3.333333333333333, 0)],
[ (3.3333, 0), (-3.5527e-15, -5.7735)],
[ (-3.5527e-15, -5.77350), (-3.3333, 0)],
[(-3.3333, 0), (-10, 0)]])
现在iterate_level(5,Initialsegments,FinalSegments)
应该是一个for循环,它应该在第一次迭代后生成16个坐标,然后在第二次迭代后生成64个坐标...
但这是我的问题,这不是真的有效,我不知道我还在做错什么。
在我看到痕迹的时候,在我看来,
iterate_level(N,Ls,F):-
seq(0,N,Index),
next_level_segments(Index,Ls,F).
在for循环中调用next_level_segments(Index,Ls,F)
时,列表
每次迭代后应该包含四倍以上坐标的Ls不会刷新。(也许这就是问题所在)。
当我打电话给generate(3,[[(60,0),(-60,0)]],X).
时,我得到四次总是相同的16坐标,但我应该得到1024个不同的坐标。
也许有人可能有时间看看这个问题给我一些帮助。
感谢
这是我迄今为止的实施:
generate(N,[S,E],FinalSegments):-
segments([S,E],Initialsegments),
iterate_level(N,Initialsegments,FinalSegments).
generate(N,[],[]).
seq(From,_,From).
seq(From,To,X) :-
From<To,
Next is From+1,
seq(Next,To,X).
iterate_level(N,Ls,F):-
seq(0,N,Index),
next_level_segments(Index,Ls,F).
%fail.
iterate_level(Ls,F).
iterate_level([],[]).
segments([(Sx,Sy),(Ex,Ey)],Ls):-
X2 is Sx+(Ex-Sx)/3,
Y2 is Sy+(Ey-Sy)/3,
R1 is sqrt((X2-Sx)*(X2-Sx)+(Y2-Ey)*(Y2-Ey)),
Phi1 is atan((Y2-Sy)/(X2-Sx)),
X3 is X2 +R1*cos((Phi1-240)*pi/180),
Y3 is Y2 +R1*sin((Phi1+240)*pi/180),
X4 is X2+(X2-Sx),
Y4 is Y2+(Y2-Sy),
Ls=[
[(Sx,Sy),(X2,Y2)],
[(X2,Y2),(X3,Y3)],
[(X3,Y3),(X4,Y4)],
[(X4,Y4),(Ex,Ey)]
].
next_level_segments(N,[[(Sx,Sy),(Ex,Ey)]|E],[X|RLs]):-
segments([(Sx,Sy),(Ex,Ey)],X),
next_level_segments(N,E,RLs).
next_level_segments(N,[],[]).
答案 0 :(得分:3)
所以,首先,Prolog不会做传统意义上的for循环 - 你真正想做的是用累加器递归列表。这可以通过以下方式实现。
首先,generate(0, [[X|Y]|Z], [[X|Y]|Z]) :- !.
,其中说“如果我试图生成列表列表的第0次迭代,我已经实现了目标,我应该成功”。这也会减少,因为这里只有一个解决方案。
generate(N, [[P1, P2]|Tail], Final)
执行(外部)递归的主体。只要这是一个正迭代(即排除否定),我们do_generate
一个坐标的迭代,并递归另一个迭代(迭代0成功如上)。
do_generate([],[]).
表示如果我们尝试在空列表之间生成坐标,我们就会为此级别完成。
do_generate([Current|Rest], Interim)
获取第一对坐标并生成四对坐标的集合(如前所述使用segments([(Sx,Sy),(Ex,Ey)],Ls)
),然后递归到坐标列表的其余部分。一旦我们达到上述基本情况,我们将所有列表从最后一个追加到第一个以获得新的坐标集。然后将其与Interim
统一,以使用外部基本情况发送回generate(N, [[P1, P2]|Tail], Final)
以进一步递归或与Final
统一。
作为警告,为了使输出看起来像最终基本情况的输入,输入现在需要是坐标对列表的列表,而不仅仅是坐标对的列表。
全部放在一起,您得到以下内容:
generate(0, [[X|Y]|Z], [[X|Y]|Z]) :- !.
generate(N, [[P1, P2]|Tail], Final) :-
N > 0,
do_generate([[P1, P2]|Tail], Interim),
N1 is N-1,
generate(N1, Interim, Final).
do_generate([], []).
do_generate([Current|Rest], Interim) :-
segments(Current, Segs),
do_generate(Rest, RestSegs),
append(Segs, RestSegs, Interim).
segments([(Sx,Sy), (Ex,Ey)], Ls) :-
X2 is Sx+(Ex-Sx)/3,
Y2 is Sy+(Ey-Sy)/3,
R1 is sqrt((X2-Sx)*(X2-Sx)+(Y2-Ey)*(Y2-Ey)),
Phi1 is atan((Y2-Sy)/(X2-Sx)),
X3 is X2+R1*cos((Phi1-240)*pi/180),
Y3 is Y2+R1*sin((Phi1+240)*pi/180),
X4 is X2+(X2-Sx),
Y4 is Y2+(Y2-Sy),
Ls=[[(Sx,Sy),(X2,Y2)],
[(X2,Y2),(X3,Y3)],
[(X3,Y3),(X4,Y4)],
[(X4,Y4),(Ex,Ey)]].