Skip to content

Commit

Permalink
add list splitat theorem
Browse files Browse the repository at this point in the history
Also move extra Nat theorems into their own file
  • Loading branch information
awalterschulze committed Dec 19, 2024
1 parent 52b919e commit 78a3f33
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 90 deletions.
1 change: 1 addition & 0 deletions Katydid.lean
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Katydid.Std.Ordering
import Katydid.Std.Decidable
import Katydid.Std.OrderingThunk
import Katydid.Std.Nat
import Katydid.Std.Lists
import Katydid.Std.Ltac
import Katydid.Std.Balistic
Expand Down
20 changes: 10 additions & 10 deletions Katydid/Expr/Desc.lean
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ We want to represent some nested function calls for a very restricted language,
We represent the description (including AST) of the expr, or as we call it the Descriptor here:
-/

namespace Desc

inductive Desc where
| intro
(name: String)
Expand All @@ -16,11 +14,13 @@ inductive Desc where
(reader: Bool)
deriving Repr

def Desc.name (desc: Desc): String :=
namespace Desc

def name (desc: Desc): String :=
match desc with
| ⟨ name, _, _, _ ⟩ => name

def Desc.params (desc: Desc): List Desc :=
def params (desc: Desc): List Desc :=
match desc with
| ⟨ _, params, _, _⟩ => params

Expand All @@ -30,24 +30,24 @@ The `hash` field is important, because it is used to efficiently compare functio
* and(lt(3, 5), lt(3, 5)) => lt(3, 5)
* or(and(lt(3, 5), contains("abcd", "bc")), and(contains("abcd", "bc"), lt(3, 5))) => and(contains("abcd", "bc"), lt(3, 5))
-/
def hash_list (innit: UInt64) (list: List UInt64): UInt64 :=
private def hash_list (innit: UInt64) (list: List UInt64): UInt64 :=
List.foldl (fun acc h => 31 * acc + h) innit list

def hash_string (s: String): UInt64 :=
private def hash_string (s: String): UInt64 :=
hash_list 0 (List.map (Nat.toUInt64 ∘ Char.toNat) (String.toList s))

def hash_desc (desc: Desc): UInt64 :=
private def hash_desc (desc: Desc): UInt64 :=
match desc with
| ⟨ name, params, _, _⟩ => hash_list (31 * 17 + hash_string name) (hash_params params)
where hash_params (params: List Desc): List UInt64 :=
match params with
| [] => []
| param::params => hash_desc param :: hash_params params

def Desc.hash (desc: Desc): UInt64 :=
def hash (desc: Desc): UInt64 :=
hash_desc desc

def any_reader (d: Desc): Bool :=
private def any_reader (d: Desc): Bool :=
match d with
| ⟨ _, params, _, _⟩ => any_params params
where any_params (params: List Desc): Bool :=
Expand All @@ -56,7 +56,7 @@ where any_params (params: List Desc): Bool :=
| param::params => any_reader param || any_params params

/- The reader field tells us whether the function has any variables or can be evaluated at compile time. -/
def Desc.reader (desc: Desc): Bool :=
def reader (desc: Desc): Bool :=
any_reader desc

inductive IsSmart : Desc → Prop
Expand Down
2 changes: 1 addition & 1 deletion Katydid/Regex/Language.lean
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def derive_char {α: Type} [DecidableEq α] {a: α} {c: α}:
funext
rw [derive_iff_char]

def derive_iff_pred {α: Type} {p: α -> Prop} [dp: DecidablePred p] {x: α} {xs: List α}:
def derive_iff_pred {α: Type} {p: α -> Prop} {x: α} {xs: List α}:
(derive (pred p) x) xs <-> (onlyif (p x) emptystr) xs := by
simp only [derive, derives, singleton_append]
simp only [onlyif, emptystr]
Expand Down
97 changes: 18 additions & 79 deletions Katydid/Std/Lists.lean
Original file line number Diff line number Diff line change
Expand Up @@ -9,74 +9,11 @@

import Mathlib.Tactic.Linarith

import Katydid.Std.Nat

open Nat
open List

theorem nat_succ_le_succ_iff (x y: Nat):
succ x ≤ succ y <-> x ≤ y := by
apply Iff.intro
case mp =>
apply Nat.le_of_succ_le_succ
case mpr =>
apply Nat.succ_le_succ

theorem nat_succ_eq_plus_one : succ n = n + 1 := by
simp only

theorem nat_pred_le_succ : {n m : Nat} -> Nat.le n (succ m) -> Nat.le (pred n) m
| zero, zero, _ => Nat.le.refl
| _, _, Nat.le.refl => Nat.le.refl
| zero, succ _, Nat.le.step h => h
| succ _, succ _, Nat.le.step h => Nat.le_trans (le_succ _) h

theorem nat_pred_le_succ' : {n m : Nat} -> Nat.le n (succ m) -> Nat.le (pred n) m := by
intro n m h
cases h with
| refl =>
constructor
| step h =>
cases n with
| zero =>
dsimp only [zero_eq, Nat.pred_zero, le_eq]
exact h
| succ n =>
dsimp only [Nat.pred_succ, le_eq]
have h_n_le_succ_n := Nat.le_succ n
exact (Nat.le_trans h_n_le_succ_n h)


theorem nat_min_zero {n: Nat}: min 0 n = 0 :=
Nat.min_eq_left (Nat.zero_le _)

theorem nat_zero_min {n: Nat}: min n 0 = 0 :=
Nat.min_eq_right (Nat.zero_le _)

theorem nat_add_succ_is_succ_add (n m: Nat): succ n + m = succ (n + m) := by
cases n with
| zero =>
rewrite [Nat.add_comm]
simp only [zero_eq, zero_add]
| succ n =>
rewrite [Nat.add_comm]
rewrite [Nat.add_comm (succ n)]
repeat rewrite [Nat.add_succ]
rfl

theorem nat_pred_le_pred : {n m : Nat} → LE.le n m → LE.le (pred n) (pred m) := by
intro n m h
cases h with
| refl => constructor
| step h =>
rename_i m
cases n with
| zero =>
dsimp
exact h
| succ n =>
dsimp
have h_n_le_succ_n := Nat.le_succ n
exact (Nat.le_trans h_n_le_succ_n h)

theorem list_cons_ne_nil (x : α) (xs : List α):
x :: xs ≠ [] := by
intro h'
Expand Down Expand Up @@ -648,20 +585,6 @@ theorem list_take_drop (n: Nat) (xs: List α):
apply (congrArg (cons x))
apply ih

theorem nat_succ_gt_succ {n m: Nat}:
succ n > succ m -> n > m := by
intro h
cases h with
| refl =>
constructor
| step s =>
apply Nat.le_of_succ_le_succ
exact (Nat.le_succ_of_le s)

theorem nat_succ_gt_succ' {n m: Nat}:
succ n > succ m -> n > m := by
apply Nat.le_of_succ_le_succ

theorem list_take_large_length {n: Nat} {xs: List α}:
n > length xs -> length (take n xs) = length xs := by
revert xs
Expand Down Expand Up @@ -990,3 +913,19 @@ theorem list_split_flatten {α: Type} (zs: List α):
| cons x ys => by
exists [[x], ys]
simp

theorem list_splitAt_eq (n: Nat) (xs: List α):
splitAt n xs = (xs.take n, xs.drop n) :=
splitAt_eq n xs

theorem list_splitAt_length {α: Type} (n: Nat) (xs: List α) (hn: n ≤ length xs):
∃ xs1 xs2, (xs1, xs2) = splitAt n xs
/\ xs1.length = n
/\ xs2.length = xs.length - n := by
have h := splitAt_eq n xs
exists take n xs
exists drop n xs
split_ands
· exact (symm (list_splitAt_eq n xs))
· exact (list_take_length_le n xs hn)
· exact (list_drop_length n xs)
81 changes: 81 additions & 0 deletions Katydid/Std/Nat.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Mathlib.Tactic.Linarith

open Nat

theorem nat_succ_le_succ_iff (x y: Nat):
succ x ≤ succ y <-> x ≤ y := by
apply Iff.intro
case mp =>
apply Nat.le_of_succ_le_succ
case mpr =>
apply Nat.succ_le_succ

theorem nat_succ_eq_plus_one : succ n = n + 1 := by
simp only

theorem nat_pred_le_succ : {n m : Nat} -> Nat.le n (succ m) -> Nat.le (pred n) m
| zero, zero, _ => Nat.le.refl
| _, _, Nat.le.refl => Nat.le.refl
| zero, succ _, Nat.le.step h => h
| succ _, succ _, Nat.le.step h => Nat.le_trans (le_succ _) h

theorem nat_pred_le_succ' : {n m : Nat} -> Nat.le n (succ m) -> Nat.le (pred n) m := by
intro n m h
cases h with
| refl =>
constructor
| step h =>
cases n with
| zero =>
dsimp only [zero_eq, Nat.pred_zero, le_eq]
exact h
| succ n =>
dsimp only [Nat.pred_succ, le_eq]
have h_n_le_succ_n := Nat.le_succ n
exact (Nat.le_trans h_n_le_succ_n h)

theorem nat_min_zero {n: Nat}: min 0 n = 0 :=
Nat.min_eq_left (Nat.zero_le _)

theorem nat_zero_min {n: Nat}: min n 0 = 0 :=
Nat.min_eq_right (Nat.zero_le _)

theorem nat_add_succ_is_succ_add (n m: Nat): succ n + m = succ (n + m) := by
cases n with
| zero =>
rewrite [Nat.add_comm]
simp only [zero_eq, zero_add]
| succ n =>
rewrite [Nat.add_comm]
rewrite [Nat.add_comm (succ n)]
repeat rewrite [Nat.add_succ]
rfl

theorem nat_pred_le_pred : {n m : Nat} → LE.le n m → LE.le (pred n) (pred m) := by
intro n m h
cases h with
| refl => constructor
| step h =>
rename_i m
cases n with
| zero =>
dsimp
exact h
| succ n =>
dsimp
have h_n_le_succ_n := Nat.le_succ n
exact (Nat.le_trans h_n_le_succ_n h)

theorem nat_succ_gt_succ {n m: Nat}:
succ n > succ m -> n > m := by
intro h
cases h with
| refl =>
constructor
| step s =>
apply Nat.le_of_succ_le_succ
exact (Nat.le_succ_of_le s)

theorem nat_succ_gt_succ' {n m: Nat}:
succ n > succ m -> n > m := by
apply Nat.le_of_succ_le_succ

0 comments on commit 78a3f33

Please sign in to comment.