Last active
September 24, 2022 14:48
-
-
Save Trebor-Huang/46a61cbd2427ea51901be7215a5280e5 to your computer and use it in GitHub Desktop.
General Recursive Functions in Agda
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module _ where | |
open import Data.Nat using (β; suc; _+_) | |
open import Data.Fin using (Fin) renaming (zero to π«; suc to π€_) | |
open import Data.Vec using (Vec; []; [_]; _β·_; tail; map; allFin) renaming (lookup to _!_) | |
open import Data.Vec.Relation.Binary.Pointwise.Inductive using (Pointwise; []; _β·_) | |
open import Data.Vec.Relation.Binary.Equality.Propositional using (_β_; βββ‘) | |
open import Relation.Binary.PropositionalEquality using (_β‘_; refl; cong) | |
variable | |
n m n' : β | |
i j : Fin n | |
data Rec : β β Set where | |
Z : Rec 0 | |
S : Rec 1 | |
Ο_ : Fin n β Rec n | |
_β_ : Rec n β Vec (Rec m) n β Rec m | |
-- 2 more arguments: (x-1) and f(x-1, xs) | |
Ο : Rec n β Rec (2 + n) β Rec (1 + n) | |
ΞΌ : Rec (1 + n) β Rec n | |
Id : Vec (Rec n) n | |
Id = map Ο_ (allFin _) | |
Add : Rec 2 | |
Add = Ο (Ο π«) (S β [ Ο π€ π« ]) | |
infix 3 [_]_β«_ -- Big step | |
data [_]_β«_ : Rec n β Vec β n β β β Set where | |
Z : [ Z ] [] β« 0 | |
S : [ S ] [ n ] β« 1 + n | |
Ο_ : β i {v : Vec β n} β [ Ο i ] v β« v ! i | |
_β_ : {f : Rec n} {gs : Vec (Rec m) n} | |
β {ms : Vec β m} {ns : Vec β n} {r : β} | |
β [ f ] ns β« r | |
β Pointwise ([_] ms β«_) gs ns | |
β [ f β gs ] ms β« r | |
ΟZ : {base : Rec n} {rec : Rec (2 + n)} | |
β {ns : Vec β n} {m : β} | |
β [ base ] ns β« m | |
β [ Ο base rec ] 0 β· ns β« m | |
ΟS : {base : Rec n} {rec : Rec (2 + n)} | |
β {ns : Vec β n} {n m r : β} -- note that n is shadowed | |
β [ Ο base rec ] n β· ns β« m | |
β [ rec ] n β· m β· ns β« r | |
β [ Ο base rec ] 1 + n β· ns β« r | |
ΞΌZ : {f : Rec (1 + n)} {ns : Vec β n} | |
β [ f ] 0 β· ns β« 0 | |
β [ ΞΌ f ] ns β« 0 | |
ΞΌS : {f : Rec (1 + n)} {ns : Vec β n} {m r : β} | |
β [ f ] 0 β· ns β« 1 + m | |
β [ ΞΌ (f β (S β [ Ο π« ] β· tail Id)) ] ns β« r | |
β [ ΞΌ f ] ns β« 1 + r | |
module General where | |
{-# TERMINATING #-} | |
minimize : (β β β) β β | |
minimize f with f 0 | |
... | 0 = 0 | |
... | suc n = suc (minimize Ξ» n β f (suc n)) | |
{-# TERMINATING #-} | |
exec : Rec n β Vec β n β β | |
exec Z ns = 0 | |
exec S (n β· []) = 1 + n | |
exec (Ο i) ns = ns ! i | |
exec (f β gs) ns = exec f (map (Ξ» g β exec g ns) gs) | |
exec (Ο f g) (0 β· ns) = exec f ns | |
exec (Ο f g) (suc n β· ns) = exec g (n β· exec (Ο f g) (n β· ns) β· ns) | |
exec (ΞΌ f) ns = minimize Ξ» n β exec f (n β· ns) | |
test : β -- 11 | |
test = exec Add (5 β· 6 β· []) | |
-- uniqueness of the results | |
unique : {f : Rec n} {ns : Vec β n} {m n : β} | |
β [ f ] ns β« m | |
β [ f ] ns β« n | |
β m β‘ n | |
PointwiseUnique : {fs : Vec (Rec n) m} {rs : Vec β n} {ms ns : Vec β m} | |
β Pointwise ([_] rs β«_) fs ms | |
β Pointwise ([_] rs β«_) fs ns | |
β ms β‘ ns | |
unique Z Z = refl | |
unique S S = refl | |
unique (Ο i) (Ο .i) = refl | |
unique (p β ps) (q β qs) rewrite PointwiseUnique ps qs = unique p q | |
unique (ΟZ p) (ΟZ q) = unique p q | |
unique (ΟS p r) (ΟS q s) rewrite unique p q = unique r s | |
unique (ΞΌZ p) (ΞΌZ q) = refl | |
unique (ΞΌZ p) (ΞΌS q _) with unique p q | |
... | () | |
unique (ΞΌS p _) (ΞΌZ q) with unique p q | |
... | () | |
unique (ΞΌS p r) (ΞΌS q s) = cong suc (unique r s) | |
PointwiseUnique [] [] = refl | |
PointwiseUnique (p β· ps) (q β· qs) | |
rewrite unique p q | PointwiseUnique ps qs = refl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment