This implements the `termination_by structural` syntax proposed in #3909. I went with `termination_by structural` over, say, `termination_by (config := {method := .structural})` mainly because it was easier to get going (otherwise I’d have to look into how to define recursive parsers, as `Parser.config` depends on `term` and `termination_by` is part of term. But also because I find it more ergonomic and aesthetic as a user. But syntax can still change. The `termination_by?` syntax will no longer force well-founded recursion, and instead the inferred `termination_by structurally` annotation will be shown if structural termination is possible. While I was it, this fixes #4546 the easy way (log errors about but otherwise ignore incomplete `termination_by` sets for mutual recursion). Maybe we get multiple replacements (#4551), but even then this this good behavior. Involves a bit of shuffling around `TerimationHints` (now validated for a clique already by `PreDefinition.main`) and `TerminationArguments` (now lifted out of the `WF` namespace, and a bit simplified). Fixes #3909 --------- Co-authored-by: Richard Kiss <him@richardkiss.com>
24 lines
2.3 KiB
Text
24 lines
2.3 KiB
Text
termination_by.lean:9:2-9:18: error: unused `termination_by`, function is not recursive
|
|
termination_by.lean:12:2-12:21: error: unused `decreasing_by`, function is not recursive
|
|
termination_by.lean:15:2-16:21: error: unused termination hints, function is not recursive
|
|
termination_by.lean:19:2-19:18: error: unused `termination_by`, function is partial
|
|
termination_by.lean:22:2-22:21: error: unused `decreasing_by`, function is partial
|
|
termination_by.lean:25:2-26:21: error: unused termination hints, function is partial
|
|
termination_by.lean:29:0-29:16: error: unused `termination_by`, function is unsafe
|
|
termination_by.lean:32:2-32:21: error: unused `decreasing_by`, function is unsafe
|
|
termination_by.lean:35:2-36:21: error: unused termination hints, function is unsafe
|
|
termination_by.lean:40:4-40:20: error: unused `termination_by`, function is not recursive
|
|
termination_by.lean:44:4-44:20: error: unused `termination_by`, function is not recursive
|
|
termination_by.lean:54:2-54:18: error: unused `termination_by`, function is not recursive
|
|
termination_by.lean:62:2-62:23: error: Incomplete set of `termination_by` annotations:
|
|
This function is mutually with isOdd, which does not have a `termination_by` clause.
|
|
The present clause is ignored.
|
|
Try this: termination_by x1 => x1
|
|
termination_by.lean:79:2-79:27: error: Incomplete set of `termination_by` annotations:
|
|
This function is mutually with Test.f, Test.h and Test.i, which do not have a `termination_by` clause.
|
|
The present clause is ignored.
|
|
termination_by.lean:101:2-101:27: error: Invalid `termination_by`; this function is mutually recursive with Test2.f, which is marked as `termination_by structural` so this one also needs to be marked `structural`.
|
|
termination_by.lean:120:2-120:38: error: Invalid `termination_by`; this function is mutually recursive with Test3.f, which is not marked as `structural` so this one cannot be `structural` either.
|
|
termination_by.lean:144:2-144:38: error: Invalid `termination_by`; this function is mutually recursive with Test4.f, which is not marked as `structural` so this one cannot be `structural` either.
|
|
termination_by.lean:159:2-159:21: error: Invalid `decreasing_by`; this function is marked as structurally recursive, so no explicit termination proof is needed.
|
|
termination_by.lean:149:0-165:3: error: structural recursion does not handle mutually recursive functions
|