我有一个数字,比方说123,我想生成一组所有可能的方法来分割它:
[[1, 23], [12, 3], [1, 2, 3]].
我想过要创建[1,2,3]的幂集:
?- findall(Powerset, powerset([1,2,3], Powerset), Z).
Z = [[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]].
然后将这些集合在一起并用append/3
检查它们的串联是否是初始集合[1,2,3],即
[[1], [2, 3]] -> [1, 23]
[[1, 2], [3]] -> [12, 3]
[[1], [2], [3]] -> [1, 2, 3]
您是否考虑过另一种更简单(更优雅)的解决方案?
我使用gnu Prolog powerset modification
中的这个谓词powerset(L, [H|T]):-
append([H|T], _, L).
powerset([_|L], P):-
powerset(L, P).
答案 0 :(得分:2)
此处无需使用findall/3
---使用dcg!
int_split(X) -->
int_split__aux(X,10,[]).
int_split__aux(X,P,Ds) -->
( { X =:= 0 }
-> [Ds]
; { X < P }
-> [[X|Ds]]
; { X0 is X mod P,
X1 is X div P },
int_split__aux(X1,10,[X0|Ds]),
{ P1 is P*10 },
int_split__aux(X,P1,Ds)
).
样品使用:
?- phrase(int_split(123),Zss).
Zss = [[1,2,3], [12,3], [1,23], [123]].
?- phrase(int_split(1234),Zss).
Zss = [[1,2,3,4], [12,3,4], [1,23,4], [123,4], [1,2,34], [12,34], [1,234], [1234]].
答案 1 :(得分:2)
而不是powerset,我们可以有一个更集中的谓词
parts(C, [C]).
parts(L, Ps) :-
append(H, T, L), H \= [], T \= [],
parts(T, Ts),
append([H], Ts, Ps).
现在
?- number_codes(123,Cs),parts(Cs,Ps),maplist(number_codes,Ns,Ps).
Cs = [49, 50, 51],
Ps = [[49, 50, 51]],
Ns = [123] ;
...etc...
所以我们可以用findall
收集有趣的N.?- findall(Ns,(number_codes(123,Cs),parts(Cs,Ps),maplist(number_codes,Ns,Ps)),Rs).
Rs = [[123], [1, 23], [1, 2, 3], [12, 3]].