DrRackt在替换模型测试中为语言添加呼叫和乐趣不会通过



我为此使用 lang pl。我已经实现了语言"ROL",现在我正在尝试扩展该语言以支持使用替换模型的乐趣和调用。我的基本代码如下。在这里的一些帮助下,我设法做到了这一点并解决了我的编译问题。我现在拥有的兄弟是我添加的 3 个新测试来检查"乐趣"和"呼叫"。

这是我的代码:

(define-type RegE
[Reg Bit-List]
[And RegE RegE]
[Or RegE RegE]
[Shl RegE]
[Id Symbol]
[With Symbol RegE RegE]
[Bool Boolean]
[Geq RegE RegE]
[Maj RegE]
[If RegE RegE RegE]
[Fun Symbol RegE]
[Call RegE RegE])

(define-type RES
[RES_Bool Boolean]
[RegV Bit-List]
[FunV Symbol RegE])

我的子集函数

(define (subst expr from to)
  (cases expr
    [(Reg g) expr]
    [(Bool g) expr]
    [(And left right)(And (subst left from to)(subst right from to))]
    [(Or left right)(Or (subst left from to)(subst right from to))]
    [(If bool ifBody elseBody) (If (subst bool from to) (subst ifBody from to) (subst elseBody from to))]
    [(Maj left)(Maj (subst left from to))]
    [(Geq left right)(Geq (subst left from to)(subst right from to))]
    [(Shl left)(Shl (subst left from to))]
    [(Id name) (if (eq? name from) to expr)]
    [(With bound-id named-expr bound-body)
           (if (eq? bound-id from)
               expr
               (With bound-id
                     named-expr
               (subst bound-body from to)))]
        [(Call left right) (Call (subst left from to) (subst right from to))]
    [(Fun bound-id bound-body)
         (if (eq? bound-id from)
           expr
           (Fun bound-id (subst bound-body from to)))])
    )

我的评估函数:

(: eval : RegE -> RES)
;; evaluates RegE expressions by reducing them to bit-lists
(define (eval expr)
  (cases expr
    [(Reg right) (RegV right)]
    [(Bool b) (RES_Bool b)]
    [(Id name) (error 'eval "free identifier: ~s" name)]
    [(And left right) (reg-arith-op bit-and  (eval left ) (eval right) )]
    [(Or left right) (reg-arith-op bit-or (eval left )  (eval right) )]
    [(Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))]
    [(Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))]
    [(Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))]
    [(With bound-id named-expr bound-body)
       (eval (subst bound-body
                    bound-id
                    (Reg (RegV->bit-list(eval named-expr)))))]
    [(Fun bound-id bound-body) (FunV bound-id bound-body)]
    [(Call fun-expr arg-expr)
       (let ([fval (eval fun-expr)])
         (cases fval
           [(FunV bound-id bound-body)
            (eval (subst bound-body
                   bound-id
                   arg-expr))]
           [else (error 'eval "`call' expects a function, got: ~s"
                              fval)]))]
    [(If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))]

))   

以及无法通过的 3 项测试:

(test (run "{ reg-len = 3
 {with {identity {fun {x} x}}
 {with {foo {fun {x} {or x {1 1 0}}}}
 {call {call identity foo} {0 1 0}}}}}")
 => '(1 1 0))
 (test (run "{ reg-len = 3
 {with {x {0 0 1}}
 {with {f {fun {y} {and x y}}}
 {with {x {0 0 0}}
 {call f {1 1 1}}}}}}")
 => '(0 0 1))
(test (run "{ reg-len = 4
 {with {foo {fun {z} {if {maj? z} z {shl z}}}}
 {call foo {if {maj? {0 0 1 1}} {shl {1 0 1 1}} {1 1 0 1}}}}}")
 => '(0 1 1 1))

我收到错误:

RegV->bit-list: Given wrong type of RES (FunV x (Id x))

这是我的RegV->位列表函数:

(: RegV->bit-list : RES -> Bit-List)
;; extract a bit-list from RES type
(define (RegV->bit-list r)
  (cases r
    [(RegV bl) bl]
    [else (error 'RegV->bit-list "Given wrong type of RES ~s" r)]
    )
  )

和我的RegV->布尔值具有相同的原理:

(: RegV->boolean : RES -> Boolean)
;; extract a boolean from RES type
(define(RegV->boolean res)
  (cases res
    [(RES_Bool b) b]
    [else (error 'RegV->boolean "Given wrong type of RES ~s" res)]))

这两个函数曾经是:

(: RegV->bit-list : RES -> Bit-List)
;; extract a bit-list from RES type
(define(RegV->bit-list rest)
  (cases rest
    [(RES_Bool b) (error 'RegV->bit-list "Given wrong type of RES")]
    [(RegV bits) bits]))
(: RegV->boolean : RES -> Boolean)
;; extract a boolean from RES type
(define(RegV->boolean res)
  (cases res
    [(RES_Bool b) b]
    [(RegV bits) (error 'RegV->bit-list "Given wrong type of RES")]))

但后来我改变了它,因为我遇到了错误。任何帮助都会得到赞赏...

一个帮助你找到错误的想法。

eval输入时打印expr

(define (eval expr)
  (display "eval: ") (displayln expr)
  (cases 
     ...))

评估三个违规表达式之一。检查评估中的哪个步骤出错。

如果您需要更多详细信息,请subst打印其参数。

最新更新