Check if a Leo file has no function recursion.
We build the call graph of the file, by going through all the top-level declarations that form the file. Then we attempt to topologically sort the graph. If that succeeds, the graph has no circularities and therefore there is no function recursion. If that fails, there is a recursion.
Function:
(defun file-function-recursion-okp (file) (declare (xargs :guard (filep file))) (let ((__function__ 'file-function-recursion-okp)) (declare (ignorable __function__)) (b* ((graph (topdecl-list-call-graph (programdecl->items (file->program file)))) ((mv okp &) (depgraph::toposort graph))) okp)))
Theorem:
(defthm booleanp-of-file-function-recursion-okp (b* ((yes/no (file-function-recursion-okp file))) (booleanp yes/no)) :rule-classes :rewrite)
Theorem:
(defthm file-function-recursion-okp-of-file-fix-file (equal (file-function-recursion-okp (file-fix file)) (file-function-recursion-okp file)))
Theorem:
(defthm file-function-recursion-okp-file-equiv-congruence-on-file (implies (file-equiv file file-equiv) (equal (file-function-recursion-okp file) (file-function-recursion-okp file-equiv))) :rule-classes :congruence)