lean4-htt/tests/lean/termination_by.lean.expected.out
Joachim Breitner 1311e36a98
feat: structural mutual recursion (#4575)
This adds support for mutual structural recursive functions.

For now this is opt-in: The functions must have a `termination_by
structural …` annotation (new since #4542) for this to work:

```lean
mutual
inductive A
  | self : A → A
  | other : B → A
  | empty
inductive B
  | self : B → B
  | other : A → B
  | empty
end

mutual
def A.size : A → Nat
  | .self a => a.size + 1
  | .other b => b.size + 1
  | .empty => 0
termination_by structural x => x
def B.size : B → Nat
  | .self b => b.size + 1
  | .other a => a.size + 1
  | .empty => 0
termination_by structural x => x
end
```

The recursive functions don’t have to be in a one-to-one relation to a
set of mutually recursive inductive data types. It is possible to ignore
some of the types:

```lean
def A.self_size : A → Nat
  | .self a => a.self_size + 1
  | .other _ => 0
  | .empty => 0
termination_by structural x => x
```

or have more than one function per argument type:

```lean
  def isEven : Nat → Prop
    | 0 => True
    | n+1 => ¬ isOdd n
  termination_by structural x => x

  def isOdd : Nat → Prop
    | 0 => False
    | n+1 => ¬ isEven n
  termination_by structural x => x
```


This does not include

 * Support for nested inductive data types or nested recursion
* Inferring mutual structural recursion in the absence of
`termination_by`.
 * Functional induction principles for these.
* Mutually recursive functions that live in different universes. This
may be possible,
maybe after beefing up the `.below` and `.brecOn` functions; we can look
into this some
   other time, maybe when there are concrete use cases.

---------

Co-authored-by: Richard Kiss <him@richardkiss.com>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
2024-07-08 14:39:50 +00:00

23 lines
2.2 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.