我正在尝试从公式中提取符号。例如:
?- formula((p v q) & (q v r), U).
U = [p, q, v].
到目前为止我做了什么:
simbol_formula([],[]).
simbol_formula(negation X, [X]).
simbol_formula(X or Y, [X,Y]).
simbol_formula(X and Y, [X,Y]).
我相信我所做的是正确但不完整的。我被卡住了。它显然适用于简单的公式,但对于更复杂的公式则不然。我知道我必须将某些内容定义为simbol_formula(F,U) :-
。以某种方式使用递归或将给定的公式分解为“较小的”。
答案 0 :(得分:1)
您的案例中的核心问题是使用默认数据结构。
在您的陈述中,您不能仅通过模式匹配来区分:
为了克服这个缺点,我建议使用(任意)仿函数s/1
唯一标记符号。
例如,公式(p v q) & (q v r)
将表示为:
(s(p) ∨ s(q)) & (s(q) ∨ s(r))
然后,我们可以使用 DCG 将关联公式用于符号:
symbols(s(X)) --> [X]. symbols(negation(F)) --> symbols(F). symbols(X ∨ Y) --> symbols(X), symbols(Y). symbols(X & Y) --> symbols(X), symbols(Y).
示例查询:
?- phrase(symbols((s(p) ∨ s(q)) & (s(q) ∨ s(r))), Ls). Ls = [p, q, q, r].
我将合适的运算符定义为练习,以便上面编译。
上述内容也可用于枚举公式,尽管不公平:
?- phrase(symbols(Formula), Ls). Formula = s(_G1010), Ls = [_G1010] ; Formula = negation(s(_G1012)), Ls = [_G1012] ; Formula = negation(negation(s(_G1014))), Ls = [_G1014] .