module BoveReloaded where
open import Level renaming (zero to zeroL ; suc to sucL)
open import Function
open import Data.Empty
open import Data.Unit hiding (_≤?_ ; decTotalOrder ; _≤_ )
open import Data.Product
open import Data.Sum
open import Data.Nat hiding (_≤_)
open import Data.Nat.Properties
open import Data.List
open import Data.List.All
open import Relation.Nullary
open import Relation.Unary
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open import Induction
open import Induction.Nat as IndNat
open import Induction.Lexicographic
open import Category.Applicative
open import Category.Monad
universe of datatypes
data CDesc (I : Set) : Set₁ where
`0 : CDesc I
`1 : CDesc I
`X : (i : I) → CDesc I
_`×_ : (A B : CDesc I) → CDesc I
`Π : (S : Set)(T : S → CDesc I) → CDesc I
⟦_⟧ : {I : Set} → CDesc I → (I → Set) → Set
⟦ `0 ⟧ X = ⊥
⟦ `1 ⟧ X = ⊤
⟦ `X i ⟧ X = X i
⟦ A `× B ⟧ X = ⟦ A ⟧ X × ⟦ B ⟧ X
⟦ `Π S T ⟧ X = (s : S) → ⟦ T s ⟧ X
record CFunc (I : Set) : Set₁ where
constructor mk
field
func : I → CDesc I
data μ {I : Set}(R : CFunc I)(i : I) : Set where
con : ⟦ CFunc.func R i ⟧ (μ R) → μ R i
module RecMonad (A : Set)(B : A → Set) where
data RecMon (X : Set) : Set where
callRec : (a : A)(rec : B a → RecMon X) → RecMon X
returnRec : (x : X) → RecMon X
recMon : RawMonad RecMon
recMon = record { return = returnRec
; _>>=_ = _>>=_ }
where _>>=_ : ∀{X Y : Set} → RecMon X → (X → RecMon Y) → RecMon Y
returnRec x >>= f = f x
callRec a rec >>= f = callRec a (λ b → (rec b) >>= f)
recProg : (A : Set)(B : A → Set) → Set
recProg A B = (a : A) → RecMonad.RecMon A B (B a)
call⟨_⟩ : {A : Set}{B : A → Set} → recProg A B
call⟨ a ⟩ = RecMonad.callRec a return
where open RawMonad (RecMonad.recMon _ _)
module Gcd where
open RawMonad (RecMonad.recMon (ℕ × ℕ) (λ _ → ℕ))
gcd : recProg (ℕ × ℕ) (λ _ → ℕ)
gcd (0 , n) = return n
gcd (m , 0) = return m
gcd (suc m , suc n) with m ≤? n
... | yes _ = call⟨ suc m , n ∸ m ⟩
... | no _ = call⟨ m ∸ n , suc n ⟩
open Gcd
module Fib where
open RawMonad (RecMonad.recMon ℕ (λ _ → ℕ))
fib : recProg ℕ (λ _ → ℕ)
fib zero = return 0
fib (suc zero) = return 1
fib (suc (suc n)) = call⟨ suc n ⟩ >>= λ r₁ →
call⟨ n ⟩ >>= λ r₂ →
return (r₁ + r₂)
open Fib
Bove-Capretta predicate
module BC
{A : Set}
{B : A → Set}
(prog : recProg A B)
where
open RecMonad A B
dom : ∀{a} → RecMon (B a) → CDesc A
dom (returnRec z) = `1
dom (callRec a rec) = `X a `× `Π (B a) λ b → dom (rec b)
Dom : CFunc A
Dom = CFunc.mk λ a → dom (prog a)
mutual
run : (a : A) → μ Dom a → B a
run a (con domS) = run1 (prog a) (mapRun {p = prog a} domS)
mapRun : ∀{a}{p : RecMon (B a)} → ⟦ dom p ⟧ (μ Dom) → ⟦ dom p ⟧ B
mapRun {p = returnRec x} tt = tt
mapRun {p = callRec a rec} (domA , domRec) =
run a domA , λ b → mapRun {p = rec b} (domRec b)
run1 : ∀{a} → (p : RecMon (B a)) → ⟦ dom p ⟧ B → B a
run1 (returnRec b) tt = b
run1 (callRec a rec) (b , domRec) = run1 (rec b) (domRec b)
Data.Nat.GCD'Djinn, monotonic'
DomGCD : ℕ × ℕ → Set
DomGCD (m , n) = μ (BC.Dom gcd) (m , n)
gcd-bove : (m n : ℕ) → DomGCD (m , n) → ℕ
gcd-bove m n xs = BC.run gcd (m , n) xs
gcd-wf : (m n : ℕ) → DomGCD (m , n)
gcd-wf m n = build ([_⊗_] IndNat.<-rec-builder IndNat.<-rec-builder)
(λ { (m , n) → DomGCD (m , n) })
(λ { (m , n) rec → con (ih m n rec) })
(m , n)
where ih : ∀ x y → (IndNat.<-Rec ⊗ IndNat.<-Rec) DomGCD (x , y) → ⟦ BC.dom gcd (gcd (x , y)) ⟧ DomGCD
ih zero y rec = tt
ih (suc x) zero rec = tt
ih (suc x) (suc y) rec with x ≤? y
ih (suc x) (suc y) (rec-x , rec-y) | yes p = (rec-x (y ∸ x) (s≤′s (≤⇒≤′ (n∸m≤n x y)))) , (λ _ → tt)
ih (suc x) (suc y) (rec-x , rec-y) | no ¬p = rec-y ((x ∸ y)) ((s≤′s (≤⇒≤′ (n∸m≤n y x)))) (suc y) , (λ _ → tt)
gcd' : (m n : ℕ) → ℕ
gcd' m n = gcd-bove m n (gcd-wf m n)
module TestGcd where
test0 : gcd' 0 5 ≡ 5
test0 = refl
test0' : gcd' 4 0 ≡ 4
test0' = refl
test1 : gcd' 4 5 ≡ 1
test1 = refl
test2 : gcd' 30 35 ≡ 5
test2 = refl
test3 : gcd' 70 105 ≡ 35
test3 = refl
DomFib : ℕ → Set
DomFib m = μ (BC.Dom fib) m
fib-wf : (n : ℕ) → DomFib n
fib-wf a = cRec (λ n → DomFib n) (λ n r → con (ih {n} r)) a
where ih : ∀{n} → IndNat.CRec DomFib n → ⟦ BC.dom fib (fib n) ⟧ DomFib
ih {zero} ih = tt
ih {suc zero} ih = tt
ih {suc (suc n)} (fib-sn , fib-n , xs) = fib-sn , λ n' → fib-n , λ _ → tt
fib' : ℕ → ℕ
fib' n = BC.run fib n (fib-wf n)
module TestFib where
fib'0 : fib' 0 ≡ 0
fib'0 = refl
fib'1 : fib' 1 ≡ 1
fib'1 = refl
fib'2 : fib' 2 ≡ 1
fib'2 = refl
fib'3 : fib' 3 ≡ 2
fib'3 = refl
fib'4 : fib' 4 ≡ 3
fib'4 = refl
fib'5 : fib' 5 ≡ 5
fib'5 = refl
"Inductive Families Need Not Store Their Indices"h-propositions
data _≤`_ : ℕ → ℕ → Set where
le0 : ∀{n} → 0 ≤` n
leS : ∀{m n} → m ≤` n → suc m ≤` suc n
≤-collapsible : ∀{m n} → (a b : m ≤` n) → a ≡ b
≤-collapsible {zero} le0 le0 = refl
≤-collapsible {suc m} {zero} () b
≤-collapsible {suc m} {suc n} (leS a) (leS b) rewrite ≤-collapsible a b = refl
infixr 1 ⊢_
data ⊢_ {l : Level}(X : Set l) : Set l where
pf : .X → ⊢ X
Applicative⊢ : RawApplicative ⊢_
Applicative⊢ = record { pure = pf
; _⊛_ = _⊛_ }
where _⊛_ : {A B : Set} → ⊢ (A → B) → ⊢ A → ⊢ B
(pf f) ⊛ (pf a) = pf (f a)
postulate
extensionality : {A : Set}{B : A → Set}{f g : (a : A) → B a} →
((x : A) → ⊢ (f x ≡ g x)) → ⊢ (f ≡ g)
CDesc-collapse : ∀{I i}{R} → (xs ys : μ R i) → ⊢ xs ≡ ys
CDesc-collapse {I}{R = R} (con xs) (con ys) = cong con <$> help (CFunc.func R _) xs ys
where open RawApplicative Applicative⊢
help : (D : CDesc I) → (xs ys : ⟦ D ⟧ (μ R)) → ⊢ xs ≡ ys
help `0 () _
help `1 tt tt = pf refl
help (`X i) (con xs₁) (con ys₁) = cong con <$> help (CFunc.func R i) xs₁ ys₁
help (D₁ `× D₂) (xs₁ , xs₂) (ys₁ , ys₂) = cong₂ _,_ <$> help D₁ xs₁ ys₁ ⊛ help D₂ xs₂ ys₂
help (`Π S T) f g = extensionality λ s → help (T s) (f s) (g s)
compiler