This PR sets up the new integrated test/bench suite. It then migrates all benchmarks and some related tests to the new suite. There's also some documentation and some linting. For now, a lot of the old tests are left alone so this PR doesn't become even larger than it already is. Eventually, all tests should be migrated to the new suite though so there isn't a confusing mix of two systems.
204 lines
6.2 KiB
Text
204 lines
6.2 KiB
Text
import Lean.Elab
|
||
open Nat
|
||
|
||
structure ProvedSkip(n m: Nat) where
|
||
result : Nat
|
||
lt : m < n → result = m
|
||
ge : n ≤ m → result = m + 1
|
||
|
||
def provedSkip (n m : Nat) : ProvedSkip n m :=
|
||
if c : m < n then
|
||
⟨m, fun _ => rfl, fun hyp => False.elim (Nat.lt_irrefl m (Nat.lt_of_lt_of_le c hyp))⟩
|
||
else
|
||
⟨m + 1, fun hyp => absurd hyp c, fun _ => rfl⟩
|
||
|
||
def skip: Nat → Nat → Nat :=
|
||
fun n m => (provedSkip n m).result
|
||
|
||
theorem skip_below_eq(n m : Nat) : m < n → (skip n m = m) :=
|
||
fun hyp => (provedSkip n m).lt hyp
|
||
|
||
theorem skip_above_eq(n m : Nat) : n ≤ m → (skip n m = m + 1) :=
|
||
fun hyp => (provedSkip n m).ge hyp
|
||
|
||
theorem skip_not_below_eq(n m : Nat) : Not (m < n) → (skip n m = m + 1) :=
|
||
fun hyp =>
|
||
let lem : n ≤ m :=
|
||
match Nat.lt_or_ge m n with
|
||
| Or.inl lt => absurd lt hyp
|
||
| Or.inr ge => ge
|
||
skip_above_eq n m lem
|
||
|
||
theorem skip_lt: (k j: Nat) → skip k j < j + 2 :=
|
||
fun k j =>
|
||
if c : j < k then
|
||
let eqn := skip_below_eq k j c
|
||
by
|
||
rw [eqn]
|
||
apply Nat.le_step
|
||
apply Nat.le_refl
|
||
done
|
||
else
|
||
let eqn := skip_not_below_eq k j c
|
||
by
|
||
rw [eqn]
|
||
apply Nat.le_refl
|
||
done
|
||
|
||
theorem skip_le_succ {n k j : Nat} : j < n → skip k j < n + 1 :=
|
||
by
|
||
intro hyp
|
||
apply Nat.le_trans (skip_lt k j)
|
||
apply Nat.succ_lt_succ
|
||
exact hyp
|
||
|
||
def FinSeq (n: Nat) (α : Type) : Type := (k : Nat) → k < n → α
|
||
|
||
theorem witness_independent{α : Type}{n : Nat}(seq: FinSeq n α) :
|
||
(i : Nat)→ (j : Nat) → (iw : i < n) → (jw : j < n) →
|
||
(i = j) → seq i iw = seq j jw :=
|
||
fun i j iw jw eqn =>
|
||
match j, eqn, jw with
|
||
| .(i), rfl, ijw =>
|
||
rfl
|
||
|
||
namespace FinSeq
|
||
def init {α : Type}{n: Nat}(seq : FinSeq (n + 1) α): FinSeq n α :=
|
||
fun k w =>
|
||
seq k (Nat.le_step w)
|
||
|
||
def last{α : Type}{n: Nat}(seq : FinSeq (n + 1) α): α :=
|
||
seq n (Nat.le_refl _)
|
||
|
||
def delete{α : Type}{n: Nat}(k : Nat) (kw : k < (n + 1)) (seq : FinSeq (n + 1) α): FinSeq n α :=
|
||
fun j w =>
|
||
seq (skip k j) (skip_le_succ w)
|
||
|
||
end FinSeq
|
||
|
||
inductive Vector' (α : Type) : Nat → Type where
|
||
| nil : Vector' α zero
|
||
| cons{n: Nat}(head: α) (tail: Vector' α n) : Vector' α (n + 1)
|
||
|
||
infixr:66 "+:" => Vector'.cons
|
||
|
||
open Vector'
|
||
|
||
def Vector'.coords {α : Type}{n : Nat}(v: Vector' α n) : FinSeq n α :=
|
||
fun j jw =>
|
||
match n, v, j, jw with
|
||
| .(zero), nil, k, lt => nomatch lt
|
||
| m + 1, cons head tail, zero, lt => head
|
||
| m + 1, cons head tail, j + 1, w => tail.coords j (Nat.le_of_succ_le_succ w)
|
||
|
||
def seqVecAux {α: Type}{n m l: Nat}: (s : n + m = l) →
|
||
(seq1 : FinSeq n α) → (accum : Vector' α m) →
|
||
Vector' α l:=
|
||
match n with
|
||
| zero => fun s => fun _ => fun seq2 =>
|
||
by
|
||
have ss : l = m := by
|
||
rw [← s]
|
||
apply Nat.zero_add
|
||
done
|
||
have sf : Vector' α l = Vector' α m := by
|
||
rw [ss]
|
||
exact Eq.mpr sf seq2
|
||
done
|
||
| k + 1 => fun s seq1 seq2 =>
|
||
let ss : k + (m + 1) = l :=
|
||
by
|
||
rw [← s]
|
||
rw [(Nat.add_comm m 1)]
|
||
rw [(Nat.add_assoc k 1 m)]
|
||
done
|
||
seqVecAux ss (seq1.init) ((seq1.last) +: seq2)
|
||
|
||
def FinSeq.vec {α : Type}{n: Nat} : FinSeq n α → Vector' α n :=
|
||
fun seq => seqVecAux (Nat.add_zero n) seq Vector'.nil
|
||
|
||
def Clause(n : Nat) : Type := Vector' (Option Bool) n
|
||
|
||
def Valuation(n: Nat) : Type := Vector' Bool n
|
||
|
||
inductive SatAnswer{dom n: Nat}(clauses : Vector' (Clause n) dom) where
|
||
| unsat : SatAnswer clauses
|
||
| sat : SatAnswer clauses
|
||
|
||
structure SimpleRestrictionClauses{dom n: Nat}
|
||
(clauses: Vector' (Clause (n + 1)) dom) where
|
||
codom : Nat
|
||
restClauses : Vector' (Clause n) codom
|
||
|
||
def prependRes{dom n: Nat}(branch: Bool)(focus: Nat)(focusLt : focus < n + 1)
|
||
(clauses: Vector' (Clause (n + 1)) dom):
|
||
(rd : SimpleRestrictionClauses clauses) →
|
||
(head : Clause (n + 1)) →
|
||
SimpleRestrictionClauses (head +: clauses) :=
|
||
fun rd head =>
|
||
if c : head.coords focus focusLt = some branch then
|
||
⟨rd.codom, rd.restClauses⟩
|
||
else
|
||
⟨rd.codom + 1, (FinSeq.vec (FinSeq.delete focus focusLt head.coords)) +: rd.restClauses⟩
|
||
|
||
def restClauses{dom n: Nat}(branch: Bool)(focus: Nat)(focusLt : focus < n + 1)
|
||
(clauses: Vector' (Clause (n + 1)) dom) :
|
||
SimpleRestrictionClauses clauses :=
|
||
match dom, clauses with
|
||
| 0, _ => ⟨0, Vector'.nil⟩
|
||
| m + 1, Vector'.cons head clauses =>
|
||
prependRes branch focus focusLt clauses
|
||
(restClauses branch focus focusLt clauses) head
|
||
|
||
def answerSAT{n dom : Nat}: (clauses : Vector' (Clause n) dom) → SatAnswer clauses :=
|
||
match n with
|
||
| zero =>
|
||
match dom with
|
||
| zero => fun cls => SatAnswer.sat
|
||
| l + 1 => fun _ => SatAnswer.unsat
|
||
| m + 1 =>
|
||
fun clauses =>
|
||
let cls := clauses
|
||
let bd := zero_lt_succ m
|
||
let rd :=
|
||
restClauses false zero bd clauses
|
||
let subCls := rd.restClauses
|
||
let subSol: SatAnswer subCls := answerSAT subCls
|
||
match subSol with
|
||
| SatAnswer.sat =>
|
||
SatAnswer.sat
|
||
| SatAnswer.unsat =>
|
||
let rd := restClauses true zero bd cls -- replacing cls by clauses fixes this
|
||
let subCls := rd.restClauses
|
||
let subSol : SatAnswer subCls := answerSAT subCls
|
||
match subSol with
|
||
| SatAnswer.sat =>
|
||
SatAnswer.sat
|
||
| SatAnswer.unsat =>
|
||
SatAnswer.unsat
|
||
|
||
open Lean.Meta
|
||
open Lean.Elab.Term
|
||
|
||
syntax (name:= nrmlform)"whnf!" term : term
|
||
@[term_elab nrmlform] def normalformImpl : TermElab :=
|
||
fun stx expectedType? =>
|
||
match stx with
|
||
| `(whnf! $s) =>
|
||
do
|
||
let t ← elabTerm s none
|
||
let e ← whnf t
|
||
return e
|
||
| _ => Lean.Elab.throwIllFormedSyntax
|
||
|
||
|
||
def cls1 : Clause 2 := -- ¬P
|
||
(some false) +: (none) +: Vector'.nil
|
||
|
||
def cls2 : Clause 2 := (some true) +: none +: Vector'.nil -- P
|
||
|
||
def egStatement := cls1 +: cls2 +: Vector'.nil
|
||
|
||
def egAnswer : SatAnswer egStatement := answerSAT egStatement
|
||
|
||
def egAnswerNorm : SatAnswer egStatement := whnf! egAnswer
|