问题描述
我的逻辑老师顺便说了Quines algorithm 也可以用来计算估值。不幸的是,我 无法了解在Prolog中是如何完成的?
例如,程序会使用
给出
Quines算法中答案的语法:
?- sat_count(X+Y,C).
C = 3
因为相加X + Y的真值表
有3行评估为true:
X Y X+Y
0 0 0
0 1 1
1 0 1
1 1 1
解决方法
出发点是Quines算法,其核心谓词eval / 2具有以下规范。可以找到here。找到Quine算法的源代码和问题的解决方案。
/**
* eval(A,R):
* The predicate succeeds in R with a partial evaluated
* Boolean formula. The predicate starts with the leaves
* and calls simp after forming new nodes.
*/
% eval(+Formula,-Formula)
我们首先对标签谓词进行了实验, 将列出所有估值,而不计算它们。谓词 如果部分评估公式,则具有快速失败功能 为假(0),则无需继续标记,否则我们 只需探测布尔值:
/**
* labeling(L,A):
* The predicate labels the variables from the list L in the formula A.
*/
% labeling(+List,+Formula)
labeling(_,A) :- A == 0,!,fail.
labeling([X|L],A) :- value(X),eval(A,B),labeling(L,B).
labeling([],A) :- A == 1.
这是一个示例运行:
?- labeling([X,Y],X+Y).
X = 0,Y = 1 ;
X = 1,Y = 0 ;
X = 1,Y = 1
从标签谓词中我们得出计数谓词 使用ISO核心标准中的findall / 3。代替 最后,我们返回1,在此之间我们对计数求和。 这可以完成工作,并且还可以从快速失败中受益:
/**
* count(L,A,N):
* The predicate silently labels the variables from the list L in the
* formula A and succeeds in N with the count of the solutions.
*/
% count(+List,+Formula,-Integer)
count(_,C) :- A == 0,C = 0.
count([X|L],D) :-
findall(C,(value(X),count(L,B,C)),R),sum(R,D).
count([],1) :- A == 1.
这是一个示例运行:
?- count([X,X+Y,C).
C = 3
该实现可能会受益于我们未实现的一些优化。例如,可以优化将值分配给公式中不再存在的变量。