【发布时间】:2017-10-31 07:59:06
【问题描述】:
对于 SWI-Prolog 的 CLP(B) 库, 我想实现一个加权版本的sat_count/2
sat_count(Sat0, N) :-
catch((parse_sat(Sat0, Sat),
sat_bdd(Sat, BDD),
sat_roots(Sat, Roots),
roots_and(Roots, _-BDD, _-BDD1),
% we mark variables that occur in Sat0 as visited ...
term_variables(Sat0, Vs),
maplist(put_visited, Vs),
% ... so that they do not appear in Vs1 ...
bdd_variables(BDD1, Vs1),
partition(universal_var, Vs1, Univs, Exis),
% ... and then remove remaining variables:
foldl(universal, Univs, BDD1, BDD2),
foldl(existential, Exis, BDD2, BDD3),
variables_in_index_order(Vs, IVs),
foldl(renumber_variable, IVs, 1, VNum),
bdd_count(BDD3, VNum, Count0),
var_u(BDD3, VNum, P),
% Do not unify N directly, because we are not prepared
% for propagation here in case N is a CLP(B) variable.
N0 is 2^(P - 1)*Count0,
% reset all attributes and Aux variables
throw(count(N0))),
count(N0),
N = N0).
我没有找到用于修改代码的库的详细文档。 如何实现 sat_count/2 的加权版本?
编辑 1(2017 年 1 月 11 日):
感谢@mat 的回复,因为我的声望不够,我无法添加 cmets。
weighted_sat_count/3 应该采用一对权重列表,每个变量一个权重(True 的权重和 False 状态的权重),然后其他两个参数与 sat_count/2 相同。
计数是每个可接受分配的权重之和。每个可接受分配的权重是每个变量权重的乘积。
计算结果的算法是:
bdd_weight(BDD_node)
if BDD_node is 1-terminal return 1
if BDD_node is 0-terminal return 0
t_child <- 1-child of BDD_node
f_child <- 0-child of BDD_node
return (weight[BDD_node, 1] * bdd_weight(t_child) + weight[BDD_node, 0] * bdd_weight(f_child))
使用与计算的权重相关的访问节点地图,该算法可以更有效。
weight[,] 是权重对的列表,1 代表真,0 代表假。
编辑 2(2017 年 3 月 11 日):
例如:
A+B+C,一个简单的SAT公式
权重对列表:[(0.7, 0.3), (0.9, 0.1), (0.5, 0.5)],每个变量一个
?- weighted_sat_count([(0.7, 0.3), (0.9, 0.1), (0.5, 0.5)], +([A, B, C]), Count).
Count =
0.7*0.9*0.5 +
0.3*0.9*0.5 +
0.7*0.1*0.5 +
...
【问题讨论】:
-
您能否添加一个简短的描述和您期望从加权计数得到的结果的示例?输入等是什么?是否有参考资料,例如使用这种方法的论文?如果可能,请将其添加到问题中。
-
根据要求,我编辑了带有输入和输出的主要问题。
-
@mat 在我选择 clp(b) 作为 prolog 考试的兴趣区域后,我必须开发它。
标签: prolog swi-prolog sat clp clpb