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.
68 lines
1.5 KiB
Text
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
|