在Mozart / Oz中检查是否无法进一步约束变量元组

时间:2011-05-08 16:33:37

标签: constraints oz mozart

问候,

这个想法最好用一个例子给出:

假设我们有一个向量vec(a:{FD.int 1#100} b:{FD.int 1#100} c:{FD.int 1#100})。 我希望能够向此向量添加约束,直到我添加的每个附加约束为止 它不会添加更多信息,例如不再限制vec.avec.bvec.c

是否可以在莫扎特/奥兹进行?

我想这么想。

循环:

  1. 访问约束存储
  2. 检查是否已更改
  3. 如果没有变化则终止。

1 个答案:

答案 0 :(得分:2)

您可以使用FD.reflect模块中的函数检查有限域变量的状态。在这种情况下,FD.reflect.dom函数似乎特别有用。

要获取记录中每个字段的当前域,可以将此函数映射到记录:

declare

fun {GetDomains Vec}
   {Record.map Vec FD.reflect.dom}
end

您的示例中的初始结果将是:

vec(a:[1#100] b:[1#100] c:[1#100])

现在,您可以在添加约束之前和之后比较此函数的结果,以查看是否发生了任何事情。

两个限制:

  1. 这仅适用于实际更改至少一个变量的域的约束。某些约束会更改约束存储,但不会更改任何域,例如带有未绑定变量的等式约束。
  2. 使用这样的反射并不适用于并发,即如果从多个线程添加约束,这将引入竞争条件。
  3. 如果您需要有关如何在循环中使用GetDomains函数的示例,请告诉我......

    编辑:在old mailing list message的提示下,我提出了这个通用解决方案,它应该适用于所有类型的约束。它通过在下级计算空间中推测性地执行约束来工作。

    declare
    
    Vec = vec(a:{FD.int 1#100} b:{FD.int 1#100} c:{FD.int 1#100})
    
    %% A number of constraints as a list of procedures
    Constraints =
    [proc {$} Vec.a <: 50 end
     proc {$} Vec.b =: Vec.a end
     proc {$} Vec.b <: 50 end
     proc {$} Vec.a =: Vec.b end
    ]
    
    
    %% Tentatively executes a constraint C (represented as a procedure).
    %% If it is already entailed by the current constraint store, returns false.
    %% Otherwise merges the space (and thereby finally executes the constraint)
    %% and returns true.
    fun {ExecuteConstraint C}
       %% create a compuation space which tentatively executes C
       S = {Space.new
            proc {$ Root}
               {C}
               Root = unit
            end
           }
    in
       %% check whether the computation space is entailed
       case {Space.askVerbose S}
       of succeeded(entailed) then false
       else
          {Wait {Space.merge S}}
          true
       end
    end
    
    
    for C in Constraints I in 1..4 break:Break do
       {System.showInfo "Trying constraint "#I#" ..."}
       if {Not {ExecuteConstraint C}} then
          {System.showInfo "Constraint "#I#" is already entailed. Stopping."}
          {Break}
       end
       {Show Vec}
    end
    
    {Show Vec}