:- prompt(_, '').
:- use_module(library(readutil)).
% set membership with non-pure builtin \==
% to cut down duplicate answers as sets
memb(X,[X|_]).
memb(X,[Y|L]) :- X \== Y, memb(X,L).
% unify finite sets (i.e. set with [] at the end)
unify_set(A,B) :- subset_of(A,B), subset_of(B,A).
subset_of([], _).
subset_of([X|R],L) :- memb(X,L), subset_of(R,L).
% unify open ended sets with possibly uninstantiated variable tail at the end
unify_oeset
(A
,B
) :- ( var(A
); var(B
) ), !, A
=B
.unify_oeset(A,B) :-
split_heads(A,Xs-T1), make_set(Xs,S1),
split_heads(B,Ys-T2), make_set(Ys,S2),
unify_oe_set(S1-T1, S2-T2).
make_set
(L
,S
) :- setof(X
,memb
(X
,L
),S
).
split_heads([],[]-[]).
split_heads
([X
|T
],[X
]-T
) :- var(T
), !, true.split_heads([X|Xs],[X|Hs]-T) :- split_heads(Xs,Hs-T).
% helper function for unify_oeset (naive solution, possibly many duplication)
unify_oe_set(Xs-T1,Ys-T2) :- T1==[], T2==[], unify_set(Xs,Ys).
unify_oe_set(Xs-T1,Ys-T2) :- T1==[], subset_of(Ys,Xs), T2=Xs.
unify_oe_set(Xs-T1,Ys-T2) :- T2==[], subset_of(Xs,Ys), T1=Ys.
unify_oe_set(Xs-T1,Ys-T2) :- append(Xs,Ys,Zs), append(Zs,T,T1), append(Zs,T,T2).
main:-
process,
process:-
/* your code goes here */
unify_oeset
([1,3,5,9|T1
],[2,3,5,6|T2
]), print
(T1
), nl, print
(T2
), nl,
:- main.
Oi0gc2V0X3Byb2xvZ19mbGFnKHZlcmJvc2Usc2lsZW50KS4KOi0gcHJvbXB0KF8sICcnKS4KOi0gdXNlX21vZHVsZShsaWJyYXJ5KHJlYWR1dGlsKSkuCgolIHNldCBtZW1iZXJzaGlwIHdpdGggbm9uLXB1cmUgYnVpbHRpbiBcPT0KJSB0byBjdXQgZG93biBkdXBsaWNhdGUgYW5zd2VycyBhcyBzZXRzCm1lbWIoWCxbWHxfXSkuCm1lbWIoWCxbWXxMXSkgOi0gWCBcPT0gWSwgbWVtYihYLEwpLgoKJSB1bmlmeSBmaW5pdGUgc2V0cyAoaS5lLiBzZXQgd2l0aCBbXSBhdCB0aGUgZW5kKQp1bmlmeV9zZXQoQSxCKSA6LSBzdWJzZXRfb2YoQSxCKSwgc3Vic2V0X29mKEIsQSkuCgpzdWJzZXRfb2YoW10sIF8pLgpzdWJzZXRfb2YoW1h8Ul0sTCkgOi0gbWVtYihYLEwpLCBzdWJzZXRfb2YoUixMKS4KCiUgdW5pZnkgb3BlbiBlbmRlZCBzZXRzIHdpdGggcG9zc2libHkgdW5pbnN0YW50aWF0ZWQgdmFyaWFibGUgdGFpbCBhdCB0aGUgZW5kCnVuaWZ5X29lc2V0KEEsQikgOi0gKCB2YXIoQSk7IHZhcihCKSApLCAhLCBBPUIuCnVuaWZ5X29lc2V0KEEsQikgOi0KCXNwbGl0X2hlYWRzKEEsWHMtVDEpLCBtYWtlX3NldChYcyxTMSksCglzcGxpdF9oZWFkcyhCLFlzLVQyKSwgbWFrZV9zZXQoWXMsUzIpLAoJdW5pZnlfb2Vfc2V0KFMxLVQxLCBTMi1UMikuCgptYWtlX3NldChMLFMpIDotIHNldG9mKFgsbWVtYihYLEwpLFMpLgoKc3BsaXRfaGVhZHMoW10sW10tW10pLgpzcGxpdF9oZWFkcyhbWHxUXSxbWF0tVCkgOi0gdmFyKFQpLCAhLCB0cnVlLgpzcGxpdF9oZWFkcyhbWHxYc10sW1h8SHNdLVQpIDotIHNwbGl0X2hlYWRzKFhzLEhzLVQpLgoKJSBoZWxwZXIgZnVuY3Rpb24gZm9yIHVuaWZ5X29lc2V0IChuYWl2ZSBzb2x1dGlvbiwgcG9zc2libHkgbWFueSBkdXBsaWNhdGlvbikKdW5pZnlfb2Vfc2V0KFhzLVQxLFlzLVQyKSA6LSBUMT09W10sIFQyPT1bXSwgdW5pZnlfc2V0KFhzLFlzKS4KdW5pZnlfb2Vfc2V0KFhzLVQxLFlzLVQyKSA6LSBUMT09W10sIHN1YnNldF9vZihZcyxYcyksIFQyPVhzLgp1bmlmeV9vZV9zZXQoWHMtVDEsWXMtVDIpIDotIFQyPT1bXSwgc3Vic2V0X29mKFhzLFlzKSwgVDE9WXMuCnVuaWZ5X29lX3NldChYcy1UMSxZcy1UMikgOi0gYXBwZW5kKFhzLFlzLFpzKSwgYXBwZW5kKFpzLFQsVDEpLCBhcHBlbmQoWnMsVCxUMikuCgoKbWFpbjotCglwcm9jZXNzLAoJaGFsdC4KCnByb2Nlc3M6LQoJLyogeW91ciBjb2RlIGdvZXMgaGVyZSAqLwoJdW5pZnlfb2VzZXQoWzEsMyw1LDl8VDFdLFsyLDMsNSw2fFQyXSksIHByaW50KFQxKSwgbmwsIHByaW50KFQyKSwgbmwsCgl0cnVlLgoKOi0gbWFpbi4=