Scheme minikanren中的特征结构统一

Scheme minikanren中的特征结构统一,scheme,racket,unification,minikanren,Scheme,Racket,Unification,Minikanren,如果我们用列表表示,如何定义minikanren中的a 一般的行为是这样的(我认为): 以下代码可以正常工作,但在使用run*运行时,向后统一会受阻: ;; unifies f1 with l2 (define unify-f-with-list° (lambda (f1 l2 out) (conde [(== '() l2) (== `(,f1) out)] [(fresh (la ld a2 d2 a1 d1 res) (=/= '() l

如果我们用列表表示,如何定义minikanren中的a

一般的行为是这样的(我认为):


以下代码可以正常工作,但在使用run*运行时,向后统一会受阻:

;; unifies f1 with l2
(define unify-f-with-list°
  (lambda (f1 l2 out)
    (conde
     [(== '() l2) (== `(,f1) out)]
     [(fresh (la ld a2 d2 a1 d1 res)
         (=/= '() l2)
         (== `(,la . ,ld) l2)
         (== `(,a2 . ,d2) la)
         (== `(,a1 . ,d1) f1)
         (conde
          [(== a2 a1)
           (== `(,res . ,ld) out)
           (unify° f1 la res)]
          [(fresh ()
              (=/= a2 a1) ;; if not
              (== `(,la . ,res) out)
              (unify-f-with-list° f1 ld res))]))])))

(define unify-list-with-list°
  (lambda (l1 l2 out)
    (conde
     [(== '() l1) (== l2 out)]
     [(== '() l2) (== l1 out)]
     [(fresh (a1 d1 res)
         (=/= '() l1)
         (== `(,a1 . ,d1) l1)
         (unify-f-with-list° a1 l2 res)
         (unify-list-with-list° d1 res out))])))

(define unify°
  (lambda (f1 f2 out)
    (conde
     [(== f1 f2) (== f1 out)]
     [(fresh (a1 d1 a2 d2)
         (=/= f1 f2)        
         (== `(,a1 . ,d1) f1)
         (== `(,a2 . ,d2) f2)
         (== a1 a2)
         (fresh (res)
            (unify-list-with-list° d1 d2 res)
            (== `(,a1 . ,res) out)))])))

您可以通过在minikanren实现中修改统一代码来实现这一点

我建议不要使用列表来表示功能结构,相反,您可以定义一个新的记录类型,而不是保存一个始终以新变量结尾的列表,其中一个将表示功能结构。然后,您仍然可以使用列表和其他对象,也可以使用这些新对象


当统一代码看到两个特征结构时,它需要递归地统一所有匹配的键,并扩展每个键的“其余”部分,以包含另一个特征结构特有的字段(无破坏性突变)。

什么是fts?123456特征结构,我改变了。你能更准确地阐明这三个输入的含义吗?特别是第三个论点的形式是什么还不清楚。还有,什么是“变量”,什么是“原子”?为什么第二个示例中的
(a b)
(c d)
兼容,而第三个示例中的
(a b)
(a d)
不兼容?您能否解释每个示例调用的上下文和含义?是否包含一些链接来定义您使用的所有术语?至少有一些指向相关页面或其他内容的链接?有关可能的Prolog实现,请参阅。有了它,13.5.1中的最后一个例子是通过
attr(X,[cat-s,head-head])、attr(head,[agr-agr,subc-subc])、attr(subc,[agr-agr])、attr(agr,[num sg,pers-3])实现的。
。或者
maplist(attr[X,Head,subc,Agr],[cat-s,Head],[Agr-Agr,subc-subc],[Agr-Agr],[num-sg,pers-3]。
。我已经成功地编写了一个几乎可以工作的解决方案,但它在向后查询时遇到了问题,因为它无法确定解决方案的数量是有限的。有没有办法解决这个问题?(我已经在我的问题中添加了代码)。@MatíasGuzmánNaranjo您正试图在minikanren中实现这一点。我不建议这样做。(它不会很好地工作,因为mk没有prolog具有的类似cut的非逻辑控制结构)而是在scheme中实现它,作为minikanren系统的一个附加功能。您认为为什么需要“cut”才能工作?这一点的关键是要有一个统一的关系,它可以在任何方向上运行。我认为你不应该使用cut。您在问题中链接的序言代码使用cut。这种特性结构不能用纯粹的逻辑mk代码表示。这就是为什么您需要下拉到统一的方案实现来写这篇文章的原因。如果执行正确,它将是双向的,就像统一一样。mk程序没有终止的事实是一个线索,它需要削减。我同意@rain1,我认为必须在计划中实施。
;; unifies f1 with l2
(define unify-f-with-list°
  (lambda (f1 l2 out)
    (conde
     [(== '() l2) (== `(,f1) out)]
     [(fresh (la ld a2 d2 a1 d1 res)
         (=/= '() l2)
         (== `(,la . ,ld) l2)
         (== `(,a2 . ,d2) la)
         (== `(,a1 . ,d1) f1)
         (conde
          [(== a2 a1)
           (== `(,res . ,ld) out)
           (unify° f1 la res)]
          [(fresh ()
              (=/= a2 a1) ;; if not
              (== `(,la . ,res) out)
              (unify-f-with-list° f1 ld res))]))])))

(define unify-list-with-list°
  (lambda (l1 l2 out)
    (conde
     [(== '() l1) (== l2 out)]
     [(== '() l2) (== l1 out)]
     [(fresh (a1 d1 res)
         (=/= '() l1)
         (== `(,a1 . ,d1) l1)
         (unify-f-with-list° a1 l2 res)
         (unify-list-with-list° d1 res out))])))

(define unify°
  (lambda (f1 f2 out)
    (conde
     [(== f1 f2) (== f1 out)]
     [(fresh (a1 d1 a2 d2)
         (=/= f1 f2)        
         (== `(,a1 . ,d1) f1)
         (== `(,a2 . ,d2) f2)
         (== a1 a2)
         (fresh (res)
            (unify-list-with-list° d1 d2 res)
            (== `(,a1 . ,res) out)))])))