lean4-htt/tests/lean/guessLexDiff.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

98 lines
2.5 KiB
Text

Inferred termination argument:
termination_by n - i
Inferred termination argument:
termination_by xs.size - i
Inferred termination argument:
termination_by xs.size - i
Inferred termination argument:
termination_by (xs.size - i, ys.size - j)
Inferred termination argument:
termination_by (xs.size - i, i - j)
Inferred termination argument:
termination_by (xs.size - i, i)
guessLexDiff.lean:84:4-84:11: error: fail to show termination for
failure
with errors
structural recursion cannot be used:
argument #1 cannot be used for structural recursion
it is unchanged in the recursive calls
argument #2 cannot be used for structural recursion
failed to eliminate recursive application
_root_.failure xs i
Could not find a decreasing measure.
The arguments relate at each recursive call as follows:
(<, ≤, =: relation proved, ? all proofs failed, _: no proof attempted)
i #1 #2 i + i
1) 85:26-38 = = = =
2) 85:58-76 ? < _ _
3) 85:26-38 = = = =
4) 88:26-42 _ < _ _
5) 88:26-42 ? ≤ ≤ ?
6) 88:26-42 _ < _ _
7) 88:26-42 _ < _ _
8) 88:26-42 _ < _ _
9) 97:8-20 _ < _ _
#1: xs.size - i
#2: xs.size - (i + 1)
Please use `termination_by` to specify a decreasing measure.
guessLexDiff.lean:102:4-102:18: error: fail to show termination for
mutual_failure
mutual_failure2
with errors
mutual structural recursion requires explicit `termination_by` clauses
Could not find a decreasing measure.
The arguments relate at each recursive call as follows:
(<, ≤, =: relation proved, ? all proofs failed, _: no proof attempted)
Call from mutual_failure to mutual_failure2 at 104:4-24:
i #1 #2
i = ? ?
#3 ? = ?
Call from mutual_failure to mutual_failure2 at 104:52-78:
i #1 #2
i ? _ _
#3 _ < _
Call from mutual_failure to mutual_failure2 at 104:4-24:
i #1 #2
i _ _ _
#3 _ = _
Call from mutual_failure to mutual_failure2 at 111:4-28:
i #1 #2
i _ _ _
#3 _ < _
Call from mutual_failure to mutual_failure2 at 117:8-28:
i #1 #2
i _ _ _
#3 _ ? _
Call from mutual_failure2 to mutual_failure at 123:4-23:
i #3
i _ _
#1 _ _
#2 _ _
Call from mutual_failure2 to mutual_failure at 123:50-75:
i #3
i _ _
#1 _ _
#2 _ _
Call from mutual_failure2 to mutual_failure at 127:4-27:
i #3
i _ _
#1 _ _
#2 _ _
Call from mutual_failure2 to mutual_failure at 133:8-27:
i #3
i _ _
#1 _ _
#2 _ _
#1: xs.size - i
#2: xs.size - (i + 1)
#3: xs.size - i
Please use `termination_by` to specify a decreasing measure.