另一个只有统一的变体。
padZerosPrep(L, [], L).
padZerosPrep(L, [_|T], [0|R]):- padZerosPrep(L, T, R).
padZerosWalk([], [], La, Lb, La, Lb).
padZerosWalk([], [_|_], La, Lb, La, Lb).
padZerosWalk([_|_], [], La, Lb, La, Lb).
padZerosWalk([_|La0], [_|Lb0], [_|La1], [_|Lb1], La, Lb):-
padZerosWalk(La0, Lb0, La1, Lb1, La, Lb).
padZeros(La0, Lb0, La, Lb):-
padZerosPrep(La0, Lb0, La1),
padZerosPrep(Lb0, La0, Lb1),
padZerosWalk(La0, Lb0, La1, Lb1, La, Lb).
只需传递两个列表,并记住第二对列表的长度相同:
?- padZeros([1,2,3],[4,5,6],A,B).
A = [1, 2, 3],
B = [4, 5, 6]
?- padZeros([1,2,3],[4,5],A,B).
A = [1, 2, 3],
B = [0, 4, 5]
?- padZeros([2,3],[4,5,6],A,B).
A = [0, 2, 3],
B = [4, 5, 6]
?- La=[A,B,C,D], Lb = [1], Lc=[B,I,T], padZeros(La, Lb, La1, Lb1), padZeros(La1, Lc, La2, Lc2), padZeros(Lb1, Lc, Lb2, Lc2).
La = [A, B, C, D],
Lb = [1],
Lc = [B, I, T],
La1 = [A, B, C, D],
Lb1 = [0, 0, 0, 1],
La2 = [A, B, C, D],
Lc2 = [0, B, I, T],
Lb2 = [0, 0, 0, 1]
?- Lc=[A,B,C,D], Lb = [1], La=[B,I,T], padZeros(La, Lb, La1, Lb1), padZeros(La1, Lc, La2, Lc2), padZeros(Lb1, Lc, Lb2, Lc2).
Lc = [A, B, C, D],
Lb = [1],
La = [B, I, T],
La1 = [B, I, T],
Lb1 = [0, 0, 1],
La2 = [0, B, I, T],
Lc2 = [A, B, C, D],
Lb2 = [0, 0, 0, 1]
另外,不要用逆向变量来尝试那些谓词。
haskell中的相同变体:
padZeros :: (Num a, Num b) => [a] -> [b] -> ([a], [b])
padZeros a b = walk (zip a b) pa pb where
pa = map (const 0) b ++ a
pb = map (const 0) a ++ b
walk [] a' b' = (a', b')
walk (_:xs) (_:a') (_:b') = walk xs a' b'