Prolog:检查未绑定集是否是绑定集的子集

时间:2013-06-05 13:39:55

标签: prolog set

我有两套

Set1 = [stone(X),  active(X),  stone(Y),  in(app2,Y),  unlocked(app2)]
Set2 = [stone(s1), active(s1), stone(s2), in(app2,s2), unlocked(app2)]

我希望我的程序能够识别出如果X绑定到s1并且Y绑定到s2,则1可以是2的子集。

来自library(sets)的子集函数无法执行此操作,因为它无法生成子集。

我已经开始尝试实现我自己的子集函数,这将生成所有可能的绑定,但我在Prolog中没有太多经验,并且函数变得非常长且明显效率低。

2 个答案:

答案 0 :(得分:1)

您应该使用例如sort来订购这些集合。当您执行此操作时问题仍然存在,OrdSet1中的列表是否可以与OrdSet2中的子序列统一。这很简单:

is_subseq([], _).
is_subseq([X|Xs], [X|Ys]) :- is_subseq(Xs, Ys).
is_subseq([X|Xs], [Y|Ys]) :- X \= Y, is_subseq([X|Xs], Ys).

当你有这个谓词时,你可以这样做:

?- S1 = [stone(X), active(X), stone(Y), in(app2,Y), unlocked(app2)],
|    sort(S1, OrdS1),
|    S2 = [stone(s1), active(s1), stone(s2), in(app2,s2), unlocked(app2)],
|    sort(S2, OrdS2),
|    is_subseq(OrdS1, OrdS2).
S1 = S2, S2 = [stone(s1), active(s1), stone(s2), in(app2, s2), unlocked(app2)],
X = s1,
Y = s2,
OrdS1 = OrdS2, OrdS2 = [active(s1), stone(s1), stone(s2), unlocked(app2), in(app2, s2)]

如果您想查看必要的绑定,您必须从交互式解释器中调用它,如图所示。

答案 1 :(得分:1)

据我了解你的要求,我会写:

elements([], _).
elements([E|Es], S2) :-
    select(E, S2, SR),
    elements(Es, SR).

bindings(X, Y) :-
    S1 = [stone(X),  active(X),  stone(Y),  in(app2,Y),  unlocked(app2)],
    S2 = [stone(s1), active(s1), stone(s2), in(app2,s2), unlocked(app2)],
    elements(S1, S2).

产量

?- bindings(X,Y).
X = s1,
Y = s2 .

关于子集,我精心设计了这个迷你定义(实际上我需要它来解决project Euler中的一些问题)

subset(_, []).
subset(L, [F|T]) :-
    append(_, [F|R], L),
    subset(R, T).

但我看不出对你的任务有多大帮助...