我遇到了SBCL(在Linux上)可能与尾递归有关的问题(不是我完全相信那是什么)。我这次添加了代码(它看起来很长,但那是因为我把它全部展开了)。在SBCL递归
这笔交易是我有一个比较两个结构的函数'compare-pstructs'。但是,这些结构可能具有与组件相同结构的列表。自然,这需要一个递归解决方案。
当上述函数需要比较这些pstructs的列表时,会调用第二个函数'compare-parses'。自然地,比较分析功能必须再次对比较 - 结构函数进行吸引以比较单独的结构。
因此,它应该在构建堆栈帧的这些函数之间来回跳动,然后弹出它们,因为它发现单个pstruct匹配或不匹配,并且执行相同的操作,因为发现整个分析匹配或不。
实际发生的是第一次弹出堆栈帧时,不再发生递归调用。更奇怪的是,沿着pstructs列表循环(在比较分析函数中)的循环继续迭代,只执行比较 - pstructs函数回调以下的代码。
我会尝试将这些功能合并到一个功能中,但仍然不知道为什么它不能像两个功能一样工作。
该代码以及一个日志。感谢您向外看,每个人。
-Todd
(defstruct pstruct
syntactic-info ;; A list
dependents ;; A list of more pstructs
)
(defun compare-parses (p1t p2t)
(defparameter idx 0)
(defparameter max-idx (length p1t))
;; If they're not the same length, all bets are off.
(if (not
(equal
(length p1t)
(length p2t)
)
)
(return-from compare-parses NIL)
)
(loop
(print "idx before compare pstructs:")
(print idx)
(if
(null (compare-pstructs (nth idx p1t) (nth idx p2t)))
(return-from compare-parses NIL)
)
(setf idx (1+ idx))
(print "Added one to idx:")
(print idx)
(if (>= idx max-idx)
(return)
)
)
(return-from compare-parses T)
)
(defun compare-pstructs (p1 p2)
(print "P1")
(print p1)
(print "P2")
(print p2)
(if (not (equal (pstruct-syntactic-info p1) (pstruct-syntactic-info p2)))
(return-from compare-pstructs NIL)
)
(if (and
(null (pstruct-dependents p1))
(null (pstruct-dependents p2))
)
(return-from compare-pstructs T)
)
(if (and
(not (null (pstruct-dependents p1)))
(not (null (pstruct-dependents p2)))
)
(return-from compare-pstructs
(compare-parses
(pstruct-dependents p1) (pstruct-dependents p2)
)
)
)
;; If one or the other (not both) dependents is NIL then return NIL.
(return-from compare-pstructs NIL)
)
;; Two structures for test data (notice one has an "X" stuck in it
;; to make the two different.
(defparameter x2
'#S(PSTRUCT
:SYNTACTIC-INFO ("Sfin")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("Ext" "NP" "Pron_PRON" "Pers_PRON" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON"
"Pers_PRON" "Sin1" "S"
"Sin1" "1st" "Sin"
"NomC")
:DEPENDENTS NIL)))
#S(PSTRUCT
:SYNTACTIC-INFO ("Plu" "Sin2" "Sin3" "Sin1" "Pres" "V"
"Trans_V" "TransComp_V" "Intrans_V"
"Ditrans_V" "Inf")
:DEPENDENTS NIL)
#S(PSTRUCT
:SYNTACTIC-INFO ("DNI")
:DEPENDENTS NIL))))
(defparameter y2
'#S(PSTRUCT
:SYNTACTIC-INFO ("Sfin")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("Ext" "NP" "Pron_PRON" "Pers_PRON" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON"
"Pers_PRON" "Sin1" "S"
"Sin1" "1st" "Sin"
"NomC")
:DEPENDENTS NIL)))
#S(PSTRUCT
:SYNTACTIC-INFO ("Plu" "Sin2" "Sin3" "Sin1" "Pres" "V"
"Trans_V" "TransComp_V" "Intrans_V"
"Ditrans_V" "Inf" "X") ;; <=== "X" to make them different
:DEPENDENTS NIL)
#S(PSTRUCT
:SYNTACTIC-INFO ("DNI")
:DEPENDENTS NIL))))
;; Here's the log....
* (compare-pstructs x2 y2)
"P1"
#S(PSTRUCT
:SYNTACTIC-INFO ("Sfin")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("Ext" "NP" "Pron_PRON" "Pers_PRON" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON"
"Pers_PRON" "Sin1" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS NIL)))
#S(PSTRUCT
:SYNTACTIC-INFO ("Plu" "Sin2" "Sin3" "Sin1" "Pres" "V"
"Trans_V" "TransComp_V" "Intrans_V"
"Ditrans_V" "Inf")
:DEPENDENTS NIL)
#S(PSTRUCT :SYNTACTIC-INFO ("DNI") :DEPENDENTS NIL)))
"P2"
#S(PSTRUCT
:SYNTACTIC-INFO ("Sfin")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("Ext" "NP" "Pron_PRON" "Pers_PRON" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON"
"Pers_PRON" "Sin1" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS NIL)))
#S(PSTRUCT
:SYNTACTIC-INFO ("Plu" "Sin2" "Sin3" "Sin1" "Pres" "V"
"Trans_V" "TransComp_V" "Intrans_V"
"Ditrans_V" "Inf" "X")
:DEPENDENTS NIL)
#S(PSTRUCT :SYNTACTIC-INFO ("DNI") :DEPENDENTS NIL)))
"idx before compare pstructs:"
0
"P1"
#S(PSTRUCT
:SYNTACTIC-INFO ("Ext" "NP" "Pron_PRON" "Pers_PRON" "S" "Sin1" "1st" "Sin"
"NomC")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON" "Pers_PRON" "Sin1" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS NIL)))
"P2"
#S(PSTRUCT
:SYNTACTIC-INFO ("Ext" "NP" "Pron_PRON" "Pers_PRON" "S" "Sin1" "1st" "Sin"
"NomC")
:DEPENDENTS (#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON" "Pers_PRON" "Sin1" "S"
"Sin1" "1st" "Sin" "NomC")
:DEPENDENTS NIL)))
"idx before compare pstructs:"
0
"P1"
#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON" "Pers_PRON" "Sin1" "S" "Sin1" "1st"
"Sin" "NomC")
:DEPENDENTS NIL)
"P2"
#S(PSTRUCT
:SYNTACTIC-INFO ("PRON" "Pron_PRON" "Pers_PRON" "Sin1" "S" "Sin1" "1st"
"Sin" "NomC")
:DEPENDENTS NIL)
"Added one to idx:"
1
"Added one to idx:" <== See how the loop keeps iterating
2
T
*
您可能需要'(declaim(optimize(debug 0)(safety 0)(speed 3)))'根据[本页]获取TCO(https://0branch.com/notes/tco- cl.html#sec-2-2)如果这不起作用,请尝试减少代码,以便它能够显示错误,但没有其他所有内容并将其发布。 – Sylwester
这个人(似乎是一个天才)放在一起调整优化以允许在lisp的几个实现中进行尾递归:https://gitlab.common-lisp.net/frideau/ptc当然,它不会没有帮助,所以也许别的东西就起来了。我正在研究代码的蒸馏版本。 –
那么,只有SBCL和Clozure被支持,并且SBCL通过'(declaim(optimize(debug 0)(safety 0)(speed 3)))'来完成它。 – Sylwester