我写了下面的代码,用于转置(有限)列表的(有限)列表(在Prolog中利用足够的懒惰来处理无限的情况,至今我还没有找到)。
transpose_opt([],[]) :- !.
transpose_opt(L,M) :-
maplist(go,L,C,R),
step(C,R,M).
go([],none,[]).
go([H|T],some(H),T).
step(C,_,[]) :- list_to_set(C,[none]), !.
step(C,R,[C|S]) :- transpose_opt(R,S).
transpose(L,M) :-
transpose_opt(L,O),
maplist(
[X,Y]>>(
maplist([X,Y]>>(X=..[_|Y]),X,V),
append(V,Y)
),O,M).
它是可行的,但在我看来,那些辅助谓词 go
和 step
可以内联。有什么建议怎么做?
我尝试了下面的步骤,没有成功(结果是用一个unboud变量的单子来统一M)。
transpose_opt([],[]) :- !.
transpose_opt(L,M) :-
maplist(go,L,C,R),
forall(member(X,C),X=none) ->
M=[], !;
transpose(R,S), M=[C|S], !.
(出于某种原因,我不明白为什么要用以下方法来检查 forall
和 member
的条件下工作,但更简单的 list_to_set
不)。)
你写道。
结果是将M与一个非布德变量的单子统一起来。
试试吧
transpose_opt(L,M) :-
maplist(go,L,C,R),
( forall(member(X,C),X=none) ->
M=[]
; transpose(R,S), M=[C|S]
),
!.