Scheme中的绑定变量不知道你有多少变量

时间:2013-03-18 17:34:20

标签: scheme

我正在寻找一种使用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到处。问题是,我不知道我有多少变量,有没有办法做到这一点或者我的想法是完全错误的?

2 个答案:

答案 0 :(得分:4)

如果您需要一个未知数量的变量,使用association listhash 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)]))

full code in a gist

希望这能为您提供一个起点,让我知道您有什么问题。