Skip to content

Commit

Permalink
test: timeout in Mathlib.Computability.PartrecCode
Browse files Browse the repository at this point in the history
  • Loading branch information
kim-em authored and leodemoura committed Jan 8, 2024
1 parent e6ed385 commit 9b2b4aa
Showing 1 changed file with 342 additions and 0 deletions.
342 changes: 342 additions & 0 deletions tests/lean/run/simproc_timeout.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
-- Minimisation of a timeout triggered by leanprover/lean4#3124
-- in Mathlib.Computability.PartrecCode

set_option autoImplicit true

section Std.Data.Nat.Basic

def sqrt (n : Nat) : Nat :=
if n ≤ 1 then n else
iter n (n / 2)
where
iter (n guess : Nat) : Nat :=
let next := (guess + n / guess) / 2
if _h : next < guess then
iter n next
else
guess
termination_by iter guess => guess

end Std.Data.Nat.Basic

section Mathlib.Logic.Equiv.Defs

structure Equiv (α : Sort _) (β : Sort _) where
protected toFun : α → β
protected invFun : β → α

infixl:25 "" => Equiv

namespace Equiv

protected def symm (e : α ≃ β) : β ≃ α := ⟨e.invFun, e.toFun⟩

def sigmaEquivProd (α β : Type _) : (Σ _ : α, β) ≃ α × β :=
⟨fun a => ⟨a.1, a.2⟩, fun a => ⟨a.1, a.2⟩⟩

end Equiv

end Mathlib.Logic.Equiv.Defs

section Mathlib.Data.Nat.Pairing

namespace Nat

def pair (a b : Nat) : Nat :=
if a < b then b * b + a else a * a + a + b

def unpair (n : Nat) : Nat × Nat :=
let s := sqrt n
if n - s * s < s then (n - s * s, s) else (s, n - s * s - s)

theorem unpair_right_le (n : Nat) : (unpair n).2 ≤ n := sorry

end Nat

end Mathlib.Data.Nat.Pairing

section Mathlib.Logic.Encodable.Basic

open Nat

class Encodable (α : Type _) where
encode : α → Nat
decode : Nat → Option α
encodek : ∀ a, decode (encode a) = some a

namespace Encodable

def ofLeftInjection [Encodable α] (f : β → α) (finv : α → Option β)
(linv : ∀ b, finv (f b) = some b) : Encodable β :=
⟨fun b => encode (f b), fun n => (decode n).bind finv, fun b => sorry

def ofLeftInverse [Encodable α] (f : β → α) (finv : α → β) (linv : ∀ b, finv (f b) = b) :
Encodable β :=
ofLeftInjection f (some ∘ finv) sorry

def ofEquiv (α) [Encodable α] (e : β ≃ α) : Encodable β :=
ofLeftInverse e.toFun e.invFun sorry

instance _root_.Nat.encodable : Encodable Nat :=
⟨id, some, fun _ => rfl⟩

instance _root_.Option.encodable {α : Type _} [h : Encodable α] : Encodable (Option α) :=
⟨fun o => Option.casesOn o Nat.zero fun a => succ (encode a), fun n =>
Nat.casesOn n (some none) fun m => (decode m).map some, sorry

section Sigma

variable {γ : α → Type _} [Encodable α] [∀ a, Encodable (γ a)]

def encodeSigma : Sigma γ → Nat
| ⟨a, b⟩ => pair (encode a) (encode b)

def decodeSigma (n : Nat) : Option (Sigma γ) :=
let (n₁, n₂) := unpair n
(decode n₁).bind fun a => (decode n₂).map <| Sigma.mk a

instance _root_.Sigma.encodable : Encodable (Sigma γ) :=
⟨encodeSigma, decodeSigma, sorry

end Sigma

instance Prod.encodable [Encodable α] [Encodable β] : Encodable (α × β) :=
ofEquiv _ (Equiv.sigmaEquivProd α β).symm

end Encodable

end Mathlib.Logic.Encodable.Basic

section Mathlib.Logic.Denumerable

class Denumerable (α : Type _) extends Encodable α where

namespace Denumerable

def mk' {α} (e : α ≃ Nat) : Denumerable α where
encode := e.toFun
decode := some ∘ e.invFun
encodek _ := sorry

instance nat : Denumerable Nat := ⟨⟩

end Denumerable

end Mathlib.Logic.Denumerable

section Mathlib.Logic.Equiv.List

open Nat List

namespace Encodable

variable [Encodable α]

def encodeList : List α → Nat
| [] => 0
| a :: l => succ (pair (encode a) (encodeList l))

def decodeList : Nat → Option (List α)
| 0 => some []
| succ v =>
match unpair v, unpair_right_le v with
| (v₁, v₂), h =>
have : v₂ < succ v := lt_succ_of_le h
(· :: ·) <$> decode (α := α) v₁ <*> decodeList v₂

instance _root_.List.encodable : Encodable (List α) :=
⟨encodeList, decodeList, sorry

end Encodable

end Mathlib.Logic.Equiv.List

section Mathlib.Computability.Primrec

open Denumerable Encodable Function

namespace Nat

@[simp, reducible]
def unpaired {α} (f : Nat → Nat → α) (n : Nat) : α :=
f n.unpair.1 n.unpair.2

protected inductive Primrec : (Nat → Nat) → Prop
| zero : Nat.Primrec fun _ => 0
| protected succ : Nat.Primrec succ
| left : Nat.Primrec fun n => n.unpair.1
| right : Nat.Primrec fun n => n.unpair.2
| pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
| comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
| prec {f g} :
Nat.Primrec f →
Nat.Primrec g →
Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)

end Nat

class Primcodable (α : Type _) extends Encodable α where
prim : Nat.Primrec fun n => Encodable.encode (decode n)

namespace Primcodable

instance (priority := 10) ofDenumerable (α) [Denumerable α] : Primcodable α := ⟨sorry

instance option {α : Type _} [h : Primcodable α] : Primcodable (Option α) := ⟨sorry

end Primcodable

def Primrec {α β} [Primcodable α] [Primcodable β] (f : α → β) : Prop :=
Nat.Primrec fun n => encode ((@decode α _ n).map f)

namespace Primrec

variable {α : Type _} {β : Type _} {σ : Type _}

variable [Primcodable α] [Primcodable β] [Primcodable σ]

protected theorem encode : Primrec (@encode α _) := sorry

theorem comp {f : β → σ} {g : α → β} (hf : Primrec f) (hg : Primrec g) : Primrec fun a => f (g a) :=
sorry

end Primrec

namespace Primcodable

open Nat.Primrec

instance prod {α β} [Primcodable α] [Primcodable β] : Primcodable (α × β) :=
sorry

end Primcodable

namespace Primrec

variable {α : Type _} {σ : Type _} [Primcodable α] [Primcodable σ]

open Nat.Primrec

theorem fst {α β} [Primcodable α] [Primcodable β] : Primrec (@Prod.fst α β) := sorry

theorem snd {α β} [Primcodable α] [Primcodable β] : Primrec (@Prod.snd α β) := sorry

end Primrec

def Primrec₂ {α β σ} [Primcodable α] [Primcodable β] [Primcodable σ] (f : α → β → σ) :=
Primrec fun p : α × β => f p.1 p.2

section Comp

variable {α : Type _} {β : Type _} {γ : Type _} {σ : Type _}

variable [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable σ]

theorem Primrec₂.comp {f : β → γ → σ} {g : α → β} {h : α → γ} (hf : Primrec₂ f) (hg : Primrec g)
(hh : Primrec h) : Primrec fun a => f (g a) (h a) := sorry

end Comp

namespace Primrec

variable {α : Type _} {β : Type _} {σ : Type _}

variable [Primcodable α] [Primcodable β] [Primcodable σ]

theorem option_bind {f : α → Option β} {g : α → β → Option σ} (hf : Primrec f) (hg : Primrec₂ g) :
Primrec fun a => (f a).bind (g a) := sorry

end Primrec

section

variable {α : Type _} {β : Type _} {σ : Type _}

variable [Primcodable α] [Primcodable β] [Primcodable σ]

variable (H : Nat.Primrec fun n => Encodable.encode (@decode (List β) _ n))

open Primrec

private def prim : Primcodable (List β) := ⟨H⟩

end

namespace Primcodable

variable {α : Type _} {β : Type _}

variable [Primcodable α] [Primcodable β]

open Primrec

instance list : Primcodable (List α) := ⟨sorry

end Primcodable

namespace Primrec

variable {α : Type _}

variable [Primcodable α]

theorem list_get? : Primrec₂ (@List.get? α) := sorry

end Primrec

end Mathlib.Computability.Primrec

section Mathlib.Computability.PartrecCode

open Encodable Denumerable Primrec

namespace Nat.Partrec

inductive Code : Type
| zero : Code
| succ : Code
| left : Code
| right : Code
| pair : Code → Code → Code
| comp : Code → Code → Code
| prec : Code → Code → Code
| rfind' : Code → Code

end Nat.Partrec

namespace Nat.Partrec.Code

def encodeCode : Code → Nat
| zero => 0
| succ => 1
| left => 2
| right => 3
| pair cf cg => 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 4
| comp cf cg => 2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg) + 1) + 4
| prec cf cg => (2 * (2 * Nat.pair (encodeCode cf) (encodeCode cg)) + 1) + 4
| rfind' cf => (2 * (2 * encodeCode cf + 1) + 1) + 4

def ofNatCode : Nat → Code
| 0 => zero
| 1 => succ
| 2 => left
| 3 => right
| _ => zero -- garbage value!

instance instDenumerable : Denumerable Code :=
mk' ⟨encodeCode, ofNatCode⟩

open Primrec

private def lup (L : List (List (Option Nat))) (p : Nat × Code) (n : Nat) := do
let l ← L.get? (encode p)
let o ← l.get? n
o

-- This used to work in under 20000, but need over 6 million after leanprover/lean4#3124
set_option maxHeartbeats 40000 in
private theorem hlup : Primrec fun p : _ × (_ × _) × _ => lup p.1 p.2.1 p.2.2 :=
Primrec.option_bind
(Primrec.list_get?.comp Primrec.fst (Primrec.encode.comp <| Primrec.fst.comp Primrec.snd))
(Primrec.option_bind (Primrec.list_get?.comp Primrec.snd <| Primrec.snd.comp <|
Primrec.snd.comp Primrec.fst) Primrec.snd)

0 comments on commit 9b2b4aa

Please sign in to comment.