Racket自动机验证代码cddr合约违反问题求助
Racket自动机验证代码的cddr合约错误排查与修复
错误原因分析
你定义的自动机结构是'(estados alfabeto transiciones estado-inicial estados-finales),第5个元素是终态列表(4)。但原代码中获取终态的表达式(caddr (cddr (cddr (cddr automata))))逻辑完全错误:
- 一步步拆解执行过程:
(cddr automata)→ 去掉前两个元素,得到'(((0 a 1) ...) 0 (4))- 再执行
(cddr ...)→ 去掉前两个,得到'((4)) - 第三次执行
(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
相关产品推荐
相关产品推荐

