我正在开发一个反向链接引擎作为学校项目。到目前为止,我主要是用 C 语言完成项目,所以我决定为那个项目尝试 Haskell。我阅读 LYAH 是为了开始并开始在我的推理引擎中实现规则和事实的表示。到目前为止,这就是我得到的
module Inference () where
type Op = Bool -> Bool -> Bool
type Label = String
type Fact = (Label, [Rule])
data Rule = Operation Rule Op Rule
| Fact Fact
eval_fact:: [Label] -> Fact -> Bool
eval_fact proved (label,rules) = label `elem` proved || any (eval_rule proved) rules
eval_rule:: [Label] -> Rule -> Bool
eval_rule proved (Fact x) = eval_fact proved x
eval_rule proved (Operation r op r') = eval_rule proved r `op` eval_rule proved r'
这个想法是要有某种图表,其中事实节点指向规则节点,除非事实已经在已知事实的列表中。
但是,在这里我遇到了定义我的实际事实和规则的问题。
做类似的事情
let fact_e = ("E", [Fact ("C", [(Operation (Fact ("A", [])) (||) (Fact ("B", [])))])])
在 ghci 中以表示规则
C => E
A || B => C
这样可行。但是我真的不知道以编程方式构建这些规则的方向。此外,我看不到如何使用该方案处理循环规则(E => A
例如添加规则)。
我已经看到有一些方法可以在 Haskell 中定义自引用数据结构,在 Haskell wiki 上使用名为“Tying the knot”的技巧,但我不知道如何(或什至)在当前情况下应用它。
我的问题本质上是,我是朝着正确的方向前进,还是用这种方法完全倒退了?
PS:在我看来,我的代码并不像它应该的那样简洁(传递 [Label] 列表,重复eVal_rule proved
很多次......),但我也不知道如何以另一种方式做到这一点.