lean4-htt/tests/lean/termination_by.lean
Wojciech Rozowski 96fcc94acb
feat: add support for lattice-theoretic (co)inductive predicates (#8097)
This PR adds support for inductive and coinductive predicates defined
using lattice theoretic structures on `Prop`. These are syntactically
defined using `greatest_fixpoint` or `least_fixpoint` termination
clauses for recursive `Prop`-valued functions. The functionality relies
on `partial_fixpoint` machinery and requires function definitions to be
monotone. For non-mutually recursive predicates, an appropriate
(co)induction proof principle (given by Park induction) is generated.

Summary of changes:
- `Interal.Order.Basic` now contains `CompleteLattice` class, as well as
version of Knaster-Tarski fixpoint theorem (with an associated Park
induction principle) for the internal use for defining (co)inductive
predicates. `Prop` is shown to have two complete lattice structures (one
given by implication order for defining inductive predicates, and one
given by reverse implication for defining coinductive predicates).
Additionally, proofs that lattices are closed under products and
function spaces are included.
- Partial fixpoint's `EqnInfo` now additionally carries an information
whether something is defined as a lattice-theoretic fixpoint or via
CCPOs.
- When constructing a (co)inductive predicate,`PartialFixpoint/Main`
builds an appropriate lattice structure on the type of the predicate
using product lattice, function space lattice and an appropriate lattice
instance on `Prop`.
- `PartialFixpoint/Eqns` is modified to be able to perform rewrite under
lattice-theoretic fixpoint construction
- `PartialFixpoint/Induction`contains a case split for handling of the
(co)inductive predicates. In the case of lattice-theoretic fixpoints, it
appropriately desugars the Park induction principle.
2025-04-30 15:48:58 +00:00

68 lines
1.5 KiB
Text

/-!
This module tests various mis-uses of termination_by and decreasing_by:
* use in non-recursive functions
* that all or none of a recursive group have termination_by.
* mismatched structural/non-structural
-/
def nonRecursive1 (n : Nat) : Nat := n
termination_by n -- Error
def nonRecursive2 (n : Nat) : Nat := n
decreasing_by sorry -- Error
def nonRecursive3 (n : Nat) : Nat := n
termination_by n -- Error
decreasing_by sorry
partial def partial1 (n : Nat) : Nat := partial1 n
termination_by n -- Error
partial def partial2 (n : Nat) : Nat := partial2 n
decreasing_by sorry -- Error
partial def partial3 (n : Nat) : Nat := partial3 n
termination_by n -- Error
decreasing_by sorry
unsafe def unsafe1 (n : Nat) : Nat := unsafe1 n
termination_by n -- Error
unsafe def unsafe2 (n : Nat) : Nat := unsafe2 n
decreasing_by sorry -- Error
unsafe def unsafe3 (n : Nat) : Nat := unsafe3 n
termination_by x -- Error
decreasing_by sorry
unsafe def withWhere (n : Nat) : Nat := foo n
where foo (n : Nat) := n
termination_by n -- Error
unsafe def withLetRec (n : Nat) : Nat :=
let rec foo (n : Nat) := n
termination_by n -- Error
foo n
mutual
def rec : Nat → Nat
| 0 => 0
| n+1 => rec n + notrec n
termination_by x => x
def notrec (n : Nat) : Nat := n
termination_by n -- Error
end
mutual
def isEven : Nat → Bool
| 0 => true
| n+1 => isOdd n
termination_by x => x -- Error
def isOdd : Nat → Bool
| 0 => false
| n+1 => isEven n
termination_by? -- still works
end