使用 PLT-Redex 测试语义时仅生成类型正确的术语

Generating only well-typed terms when testing semantics using PLT-Redex

我是球拍新手,我对使用 redex 特别感兴趣。我已经为 Pierce 的类型和编程语言一书中找到的类型化算术表达式做了一个小模型。代码的要点如下:https://gist.github.com/rodrigogribeiro/e0fd3e1e3ff017b614dcfeee9f9154e0

当我尝试测试进度和保存等属性时,我想检查测试覆盖了多少代码,所以我 运行 以下内容,如 amb 教程中所示:

(let ([c (make-coverage red)])
     (parameterize ([relation-coverage (list c)])
     (check-reduction-relation
      red
      (λ (E) (progress-holds? E)))
      (covered-cases c)))

但是,它 returns

'(("E-if-false" . 0) ("E-if-true" . 0) ("E-iszero-suc" . 0) 
  ("E-iszero-zero" . 0) ("E-pred-suc" . 0) ("E-pred-zero" . 0))

这意味着没有任何语义规则被执行,对吧?我认为问题在于球拍生成的 运行dom 术语不一定类型正确。

我的问题:有没有办法指定如何只生成类型正确的术语?

经过一些尝试并重做了几个类型的这个小练习后,我得到了一个合理的解决方案(完整的代码在下面gist)。仅生成类型正确的术语的要点是使用 #:satisfying 子句来约束 redex 生成器,例如下面的 progress 属性 测试:

(define (progress)
  (let ([c (make-coverage eval-tyexp)])
    (parameterize ([relation-coverage (list c)])
        (redex-check TyExp 
               #:satisfying (types e t) 
               (progress-holds? (term e)))
        (covered-cases c))))

#:satisfying (types e t) 行说只有表达式 e 判断 types e t 成立才应该被考虑。