You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Racket自动机验证代码cddr合约违反问题求助

Racket自动机验证代码的cddr合约错误排查与修复

错误原因分析

你定义的自动机结构是'(estados alfabeto transiciones estado-inicial estados-finales),第5个元素是终态列表(4)。但原代码中获取终态的表达式(caddr (cddr (cddr (cddr automata))))逻辑完全错误:

  • 一步步拆解执行过程:
    1. (cddr automata) → 去掉前两个元素,得到'(((0 a 1) ...) 0 (4))
    2. 再执行(cddr ...) → 去掉前两个,得到'((4))
    3. 第三次执行(cddr ...) → 对'((4))调用cddr,而'((4))的cdr是空列表'(),对空列表调用cddr违反了该函数需要接收非空pair的合约,直接触发错误。

修复方案

直接通过正确的方式获取自动机结构中的第5个元素,有两种清晰的实现方式:

方式1:用cddddr配合car

cddddr automata会返回从第5个元素开始的子列表(即'((4))),取它的car就能拿到终态列表(4):

(define estados-finales (car (cddddr automata)))

方式2:用list-ref(更直观,推荐)

Racket列表索引从0开始,第5个元素对应的索引是4,直接通过索引访问:

(define estados-finales (list-ref automata 4))

修复后的完整代码

替换原代码中获取estados-finales的行,修复后的完整代码如下:

#lang racket

(define (validar-automata automata cadena)
  (define estados (car automata))
  (define alfabeto (cadr automata))
  (define transiciones (caddr automata))
  (define estado-inicial (cadddr automata))
  (define estados-finales (list-ref automata 4)) ; 修复后的行

  (define (transicion estado simbolo)
    (define (transicion-aux lista-transiciones)
      (cond
        [(null? lista-transiciones) #f]
        [(and (equal? (car (car lista-transiciones)) estado)
              (equal? (cadr (car lista-transiciones)) simbolo))
         (caddr (car lista-transiciones))]
        [else
         (transicion-aux (cdr lista-transiciones))]))
    (transicion-aux transiciones))

  (define (validar-cadena cadena estado-actual)
    (if (null? cadena)
        (member estado-actual estados-finales)
        (let ((siguiente-estado (transicion estado-actual (car cadena))))
          (if siguiente-estado
              (validar-cadena (cdr cadena) siguiente-estado)
              #f))))
  
  (validar-cadena cadena estado-inicial))

(define (validar-automata-lote automata cadenas)
  (map (lambda (cadena) (validar-automata automata cadena)) cadenas))

;; Prueba con el autómata y las cadenas proporcionadas
(define automata '((0 1 2 3 4) (a b) 
      ((0 a 1) (0 b 2) (1 a 1) (1 b 3) (2 b 2) (2 a 1)
       (3 a 1) (3 b 4) (4 a 1) (4 b 2)) 0 (4)))
(define cadenas '((a b a b a a b b) (a a a a a a b)
                  (a b a b a b b) (a b)))

(displayln (validar-automata-lote automata cadenas))

测试结果

运行修复后的代码,会输出'(#t #f #t #f),符合预期:

  • (a b a b a a b b) → 最终状态为4,属于终态,返回#t
  • (a a a a a a b) → 最终状态为3,不属于终态,返回#f
  • (a b a b a b b) → 最终状态为4,返回#t
  • (a b) → 最终状态为2,返回#f

内容的提问来源于stack exchange,提问作者Luis Martinez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:05:07