我正在寻找一种使用Scheme中的模式进行搜索的方法。就像,如果我有搜索模式
'((x likes y) (y is a hard sport) (x is rich))
和输入
'((Mike likes rugby) (Rachel likes tennis)
(rugby is a hard sport ) ( tennis is easy)
(Mike is rich) (Rachel is rich))
我只能得到迈克,因为他是唯一有资格获得每项限制的人。
我一直试图这样做几个小时。我一直在尝试将x绑定到Mike,然后使用Mike代替x到处。问题是,我不知道我有多少变量,有没有办法做到这一点或者我的想法是完全错误的?
答案 0 :(得分:4)
如果您需要一个未知数量的变量,使用association list或hash table来存储名称 - 值绑定,Scheme提供了处理这两个数据结构的内置过程。
问题描述和所需的匹配类型看起来很像Prolog或类似logic programming系统的作业。如果您使用Scheme,请考虑实施unification算法(如SICP所示),或使用嵌入在Scheme中的逻辑编程系统,例如KANREN或{{3} }。我们在此时,您还应该查看miniKANREN以供参考。
答案 1 :(得分:2)
你在这里尝试做的事情相当经典logic programming。我一直用于Scheme的方法是amb
运算符的一些变体。
amb
的工作原理如下:
(let ((x (amb 1 2 3 4))
(y (amb 5 6 7 8))
(rule (= 10 (+ x y))
(list x y))
将返回一些x y
,以便它们的总和为10.现在使用这个和其他一些巫术我们可以制作你的系统。
首先,模式将是我们的规则"。所以,让我们说我们格式化这样的模式:
'((list-of-vars) (rule 1) (rule 2) (rule 3))
现在,对于我们的输入数据,我们说它的结构如下:
'((list-of-values) (fact 1) (fact 2) (fact 3))
现在我们的生活变得相当容易,我们只想让我们的方案宏/程序/巫术做这样的事情:
(define-syntax resolve
(syntax-rules ()
[(_ ((v1 vs ...)
r1 rs ...)
((ps ...)
f1 fs ...))
(let* ((v1 (amb ps ...))
(vs (amb ps ...))
...
(sym-table (list (cons (quote v1) v1)
(cons (quote vs) vs)
...))
(facts '(f1 fs ...))
(rules '(r1 rs ...)))
(map rule (map
(lambda (rule)
(member (substitute rule sym-table)
facts))
rules))
sym-table)]))
希望这能为您提供一个起点,让我知道您有什么问题。