使用约束修剪ECLiPSe Prolog中的对称解

使用约束修剪ECLiPSe Prolog中的对称解,prolog,eclipse-clp,constraint-satisfaction,Prolog,Eclipse Clp,Constraint Satisfaction,这是我目前正在研究的约束满足问题的一个子问题,因此,我省略了应用于变量的额外约束 假设我们有一个5个变量的列表,并且所说的变量可以取1到3的值。对称性是这样定义的:假设我们对所有变量进行两次完整赋值。我们还假设,对于每一个完整赋值,我们计算具有相同值的变量集。如果我们能找到一种方法,使第一个赋值的每个集合在第二个赋值中都有一个相等/相同的集合,那么这两个赋值将是对称的 下面是一个小例子,让事情更清楚一些: 让我们做以下两项作业: L1 = [ 1, 2, 1, 1, 3 ] L2 = [ 2,

这是我目前正在研究的约束满足问题的一个子问题,因此,我省略了应用于变量的额外约束

假设我们有一个5个变量的列表,并且所说的变量可以取1到3的值。对称性是这样定义的:假设我们对所有变量进行两次完整赋值。我们还假设,对于每一个完整赋值,我们计算具有相同值的变量集。如果我们能找到一种方法,使第一个赋值的每个集合在第二个赋值中都有一个相等/相同的集合,那么这两个赋值将是对称的

下面是一个小例子,让事情更清楚一些: 让我们做以下两项作业:

L1 = [ 1, 2, 1, 1, 3 ]
L2 = [ 2, 1, 2, 2, 3 ]
这两个是对称的。 我们也来看看下面的例子:

L3 = [3, 1, 3, 3, 2]
这也与L1和L2对称

我试图删减所有对称的作业。我如何在约束中表达这一点

到目前为止,我已经尝试使用约束来查找没有赋值的第一个变量,并基本上用#=/2锁定它的值;对于每个可能的域值,这种情况都会发生一次。我的代码出现了一个实例化错误,但我不确定我的努力是否是解决这个问题的有效方法

:-lib(ic).

getNth(0, [ H | T], H, T).
getNth(Count, [ _ | T], Target, Others):-
    NewCount is Count - 1,
    getNth(NewCount, T, Target, Others).

assigned(_, [], TruthVal, TruthVal).
assigned(Var, [Val | OtherVals], CurTruthVal, TruthVal):-
    UpdatedTruthVal #= (CurTruthVal and (Var #\= Val)),
    assigned(Var, OtherVals, UpdatedTruthVal, TruthVal).

firstUnassigned(_, [], _, _, _, _).
firstUnassigned( CurP, [Var | OtherVars], PrevVals, Found, CurCount, Index):-
    assigned(Var, PrevVals, 1, TruthVal),
    (TruthVal and (Found #\= 1)) => ((Index #= CurCount) and (Var #= CurP) and (NewFound #= 1)),
    Found => (NewFound #= Found),
    NewCount is CurCount + 1,
    firstUnassigned(CurP, OtherVars, PrevVals, NewFound, NewCount, Index).

symmetryConstraints(CurP, NP, _, _):-
    CurP > NP.

symmetryConstraints(CurP, NP, L, PrevVals):-
    CurP =< NP,
    firstUnassigned(CurP, L, PrevVals, 0, 0, Index),
    getNth(Index, L, _, NextL),
    NewP is CurP + 1,
    symmetryConstraints(NewP, NP, NextL, [CurP | PrevVals]).

start(L):-
    L = [ Var1, Var2, Var3 ],
    L #:: 1..2,
    length(L, N),
    symmetryConstraints(1, N, L, []),
    search(L, 0, most_constrained, indomain, complete, []).
:-lib(ic)。
getNth(0[H | T],H,T)。
getNth(计数,[| T],目标,其他):-
NewCount是Count-1,
getNth(NewCount、T、Target、Others)。
已分配(u,[],TruthVal,TruthVal)。
分配(Var、[Val | OtherVals]、CurTruthVal、TruthVal):-
更新的truthVal#=(CurTruthVal和(Var#\=Val)),
已分配(Var、OtherVAL、UpdatedTruthVal、TruthVal)。
第一次未分配(,[],,,,,,,,)。
firstUnassigned(CurP,[Var | OtherVars],prevals,Found,CurCount,Index):-
已分配(Var、Prevals、1、TruthVal),
(TruthVal和(Found#\=1))=>((Index#=CurCount)和(Var#=CurP)和(NewFound#=1)),
发现=>(新发现#=发现),
NewCount是CurCount+1,
firstUnassigned(CurP、OtherVars、prevals、NewFound、NewCount、Index)。
对称约束(CurP,NP,u,u):-
CurP>NP。
对称约束(CurP、NP、L、prevals):-
CurP=
您使用的库是什么?L1和L2是如何对称的?L1有3个1,L2有1个?在eclipse中,您可以使用循环而不是递归,递归提供了一个干净的代码。@LuaiGhunim我使用的是ic和ic_global。由于这是我课程作业的一部分,我不允许使用for循环和if/else语句。至于对称性,让我们这样想:变量列表是必须分配的作业,值是指示已分配作业的个人ID。L1和L2在某种意义上是对称的,即无论1人获得工作1、3和4(按顺序),2人获得工作2,还是相反,都是一样的。真正重要的不是哪一个人得到哪一组作业,而是作业本身。以下是一个相关的答案,可能有助于了解您使用的库以及L1和L2是如何对称的?L1有3个1,L2有1个?在eclipse中,您可以使用循环而不是递归,递归提供了一个干净的代码。@LuaiGhunim我使用的是ic和ic_global。由于这是我课程作业的一部分,我不允许使用for循环和if/else语句。至于对称性,让我们这样想:变量列表是必须分配的作业,值是指示已分配作业的个人ID。L1和L2在某种意义上是对称的,即无论1人获得工作1、3和4(按顺序),2人获得工作2,还是相反,都是一样的。真正重要的不是哪一个人得到哪一组作业,而是作业本身