CLP 中变量的暂定绑定
Posted
技术标签:
【中文标题】CLP 中变量的暂定绑定【英文标题】:Tentative binding of variables in CLP 【发布时间】:2020-12-26 12:16:02 【问题描述】:我正在尝试使用 SWI Prolog CLP(FD) 解决调度问题。当试图解决更大的问题时,我会应用更高级的标记策略,在这里更好地了解程序在什么时候失败和回溯是有益的。因此,我喜欢记录哪些变量绑定导致失败,并使用这些信息来更好地调整我的标签启发式方法。 为了说明,我生成了一个示例。我生成了一个谓词,它将变量列表绑定到一系列值。我想知道序列的哪一部分使解决方案变得无效,并将这些变量记录在谓词的第三个参数中。
vars_assign_fail(_, [], []).
vars_assign_fail([S|Vs], [S|Ss], Fs ) :-
!,
vars_assign_fail(Vs, Ss, Fs).
vars_assign_fail([_|Vs], [S|Ss], [S|Fs]) :-
vars_assign_fail(Vs, Ss, Fs).
我现在可以测试这个谓词,只使用非常简单的约束。
?- length(Vs, 6), As=[1, 2, 6, 9, 11, 3], Vs ins 1..5\/8..22, chain(Vs, #<), vars_assign_fail(Vs, As, Fs).
Vs = [1, 2, _51574, 9, 11, _51592],
As = [1, 2, 6, 9, 11, 3],
Fs = [6, 3],
_51574 in 3..5\/8,
_51592 in 12..22.
它告诉我值 6 和 3 导致该程序失败。所以我想使用这些信息来修改我的测试序列,使用有限数量的替代值。最后,我想达到以下目标:
solution_valueSeq_alternatives(Vs, Seq, []) :-
!,
fail.
solution_valueSeq_alternatives(Vs, Seq, Alt) :-
vars_assign_fail(Vs, Seq, []).
solution_valueSeq_alternatives(Vs, Seq, [A|Alt]) :-
vars_assign_fail(Vs, Seq, [F|Fs]),
sequence_fail_alternative_rearrange(Seq, [F|Fs], A, Reseq),
solution_valueSeq_alternatives(Vs, Reseq, Alt).
问题是在第三个子句中 vars_assign_fail 已经将 Seq 的值部分绑定到 Vs。然而,我想“撤消”这个(=backtrack)并且只保留有关失败的绑定的信息(F|Fs)。此信息位于谓词 sequence_fail_alternative_rearrange 中,用于创建具有替代值输入的新序列,并且“测试”再次运行,直到 找到了有效的解决方案 - 或者当用完备选方案列表时整个迭代失败。
有人可以就如何在 Prolog 中最好地实现这一点给我建议吗?是否有可能再次取消绑定 Vs 中的变量或只是暂时执行 vars_assign_fail?您会推荐什么解决方案?
【问题讨论】:
【参考方案1】:提示:not 谓词可以应用两次(双重否定),您只对 Goal 是成功还是失败以及应该丢弃任何绑定感兴趣。检查Why double negation doesn't bind in Prolog。 在 vars_assign_fail/3 的第二个子句中使用它,例如:
vars_assign_fail(_, [], []).
vars_assign_fail([V|Vs], [S|Ss], Fs ) :-
\+ \+ V=S,
!,
vars_assign_fail(Vs, Ss, Fs).
vars_assign_fail([_|Vs], [S|Ss], [S|Fs]) :-
vars_assign_fail(Vs, Ss, Fs).
【讨论】:
以上是关于CLP 中变量的暂定绑定的主要内容,如果未能解决你的问题,请参考以下文章