为什么 miniKanren 中的“disj”在 Scheme 中有效,而在 Racket 中无效?

问题描述

我正在使用 Racket 的 minikanren 库,但想使用“disj”和“conj”运算符。为了清晰起见,我希望能够更明确地声明我是使用 disj 还是 conj,而不是必须通过 conde 表达式进行解析,尤其是在表达式变得更加复杂时。我从“The Reasoned Schemer”复制了源代码

(define (append∞ s∞ t∞)
  (cond
    ((null? s∞) t∞)
    ((pair? s∞)
     (cons (car s∞)
           (append∞ (cdr s∞) t∞)))
    (else (λ ()
            (append∞ t∞ (s∞))))))

(define (disj2 g1 g2)
  (λ (s)
    (append∞ (g1 s) (g2 s))))

(define-Syntax disj
  (Syntax-rules ()
    [(disj) '()]
    [(disj g) g]
    [(disj g0 g ...) (disj2 g0 (disj g ...))]))

这适用于前两种情况

> (run* (x) (disj (== 'foo x)))
'(foo)

但只在使用多个目标时返回第一个结果:

> (run* (x) (disj (== 'foo x) (== 'bar x) (== 'foobar x)))
'(foo)

这是为什么?

解决方法

哼。我似乎无法重现这种行为。

当我克隆 TRS/2e repo 时,添加两个

#lang racket
(provide (all-defined-out))

trs2-impl.scm 的顶部,运行该文件,然后尝试您的测试程序,我看到了预期的结果:

; 
; Welcome to Racket v7.9.0.3 [cs].
; 
trs2-impl.scm> (run* (x) (disj (== 'foo x) (== 'bar x) (== 'foobar x)))
'((foo) (bar) (foobar))

你看到不同的行为了吗?如果是这样,那么我们可以更深入地研究。您知道您使用的是哪个版本的 Racket 吗?我认为这无关紧要,但以防万一。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...