Recursion 错误:方案中存在违反合同的情况

Recursion 错误:方案中存在违反合同的情况,recursion,scheme,Recursion,Scheme,我在Scheme中练习递归。下面的代码用于获取模式子句和语句,如果语句与模式匹配,则返回绑定列表,如果不匹配,则返回false: (define remove-question-mark (lambda (s1) (if (memq #\? (string->list (symbol->string s1))) (cdr (string->list (symbol->string s1))) '()))) (define ch

我在Scheme中练习递归。下面的代码用于获取模式子句和语句,如果语句与模式匹配,则返回绑定列表,如果不匹配,则返回false:

(define remove-question-mark
  (lambda (s1)
    (if (memq #\? (string->list (symbol->string s1)))
        (cdr (string->list (symbol->string s1)))
        '())))

(define check-two-symbol
  (lambda (symbol1 symbol2)
    (if (and (regexp-match #rx#"\\?attrs" (symbol->string symbol1)) (list? symbol2))
        (cons symbol1 (list symbol2))
        (if (equal? symbol1 symbol2)
            '()
            (if (equal? (remove-question-mark symbol1) (string->list (symbol->string symbol2)))
                (cons symbol1 symbol2)
                #f)))))

(define clause
  (lambda (state1 state2)
    (if (and (null? (car state1)) (null? (car state2)))
        '() 
        (list (check-two-symbol (car state1) (car state2)) (clause (cdr state1) (cdr state2))))))
这是我的意见:

(clause '(wasDerivedFrom ?der ?e1 ?e2 . ?attrs_derv) '(wasDerivedFrom der e1 e2 (prov:type "Revision")))
我从我的代码中得到了这个错误:

car: contract violation
  expected: pair?
  given: '()
预期产出:

((?der . der)
(?e1 . e1)
(?e2 . e2)
(?attrs_derv (prov:type "Revision")))
调试后,我发现当
(carstate1)
?attrs\u derv

如果我分别运行函数
检查两个符号
,比如
(检查两个符号“?attrs derv”(prov:type“Revision”)
,它会很好地打印出来:

(?attrs_derv (prov:type "Revision"))
但是对于main函数,我得到了一个错误。那么有人能帮我演示如何修复这个错误吗??我对递归不太熟悉


提前感谢

错误消息表示您正在使用非配对的东西呼叫
car
。您只在四个位置调用
car
,因此它是
子句中的一个。现在,
子句
只从
子句
调用,所以您不必走太远就可以找到它。应该用什么类型的值调用
子句
?当您递归调用
子句
时(以下代码的最后一行),您使用
(cdr state1)
(cdr state2)
调用它。是否有任何理由认为这些不是
”()

让我们看看从初始输入调用的
子句

(clause '(wasDerivedFrom ?der ?e1 ?e2 . ?attrs_derv) '(wasDerivedFrom der e1 e2 (prov:type "Revision")))
(clause '(?der ?e1 ?e2 . ?attrs_derv) '(der e1 e2 (prov:type "Revision")))
(clause '(?e1 ?e2 . ?attrs_derv) '(e1 e2 (prov:type "Revision")))
(clause '(?e2 . ?attrs_derv) '(e2 (prov:type "Revision")))
(clause '?attrs_derv '((prov:type "Revision")))
此时,您将尝试调用
上的
car
?attrs_derv
,这将导致错误,因为符号不是一对。实际上,如果我们将
子句
简化为以下内容(这样它就不会调用
检查两个符号

然后尝试调用您提到的代码,我们得到一个错误:

> (clause '(wasDerivedFrom ?der ?e1 ?e2 . ?attrs_derv) '(wasDerivedFrom der e1 e2 (prov:type "Revision")))
car: contract violation
  expected: pair?
  given: '?attrs_derv
事实上,您得到了一个不同的错误,这意味着调用
check two symbol
会调用
car
我们看不到的地方,或者您显示给我们的测试与您显示给我们的输出不一致。在任何一种情况下,看起来您都试图并行递归两个列表。只有当它们都是成对的时候,你才能这样做,所以你可能需要这样的代码

(if (not (and (pair? state1) (pair? state2)))
   <then-something>
   <else-something>)
(如果(不是(和(对状态1)(对状态2)))
)

看看用户在哪里遇到相同的错误消息。在
子句中
(和…(car(null?state2))
不应该是
(和…(null?(car state2))
?应该是
(和(null?state1)(null?state2))
,不是吗?我不知道你的代码应该是什么才能正常工作,但是
(car(null?…)
最终会导致错误(
短路,所以你还没有看到它们),因为
null?
返回
\t
\f
并且你不能把
(null?)
打错了。我真的很抱歉!!我想我不应该打电话给你(车辆状态1)和(车辆状态2)在if条件下,因为它在if语句返回false时被处理过,所以我是正确的吗???@trungbun不清楚代码应该做什么。
子句
不是一个特别有意义的名称,也没有注释。我们不能说什么会使它正确,因为我们不知道它应该做什么。也就是说,如果你去的话如果你想打电话给各州的
car
cdr
,你可以检查他们是否满足
pair?
。我修复了它并让它运行了!!!!:)问题出在
(car(null?…)
非常感谢你指出它!!真的!!
> (clause '(wasDerivedFrom ?der ?e1 ?e2 . ?attrs_derv) '(wasDerivedFrom der e1 e2 (prov:type "Revision")))
car: contract violation
  expected: pair?
  given: '?attrs_derv
(if (not (and (pair? state1) (pair? state2)))
   <then-something>
   <else-something>)