Skip to content

Instantly share code, notes, and snippets.

@aztek
Created April 6, 2014 14:09
Show Gist options
  • Save aztek/10006634 to your computer and use it in GitHub Desktop.
Save aztek/10006634 to your computer and use it in GitHub Desktop.
Syntax of Roman numerals, checked on type level with Agda's dependent types and instance arguments
module RomanNumerals where
open import Data.List
open import Data.Unit using (⊀; tt)
open import Data.Empty using (βŠ₯)
data Literal : Set where
𝐼 𝑉 𝑋 𝐿 𝐢 𝐷 𝑀 : Literal
infix 4 ones_
ones_ : List Literal β†’ Set
ones [] = ⊀
ones 𝐼 ∷ [] = ⊀
ones 𝐼 ∷ 𝐼 ∷ [] = ⊀
ones 𝐼 ∷ 𝐼 ∷ 𝐼 ∷ [] = ⊀
ones 𝐼 ∷ 𝑉 ∷ [] = ⊀
ones 𝑉 ∷ [] = ⊀
ones 𝑉 ∷ 𝐼 ∷ [] = ⊀
ones 𝑉 ∷ 𝐼 ∷ 𝐼 ∷ [] = ⊀
ones 𝑉 ∷ 𝐼 ∷ 𝐼 ∷ 𝐼 ∷ [] = ⊀
ones 𝐼 ∷ 𝑋 ∷ [] = ⊀
ones _ = βŠ₯
infix 4 tens_
tens_ : List Literal β†’ Set
tens 𝐿 ∷ 𝑋 ∷ 𝑋 ∷ 𝑋 ∷ β„“ = ones β„“
tens 𝑋 ∷ 𝑋 ∷ 𝑋 ∷ β„“ = ones β„“
tens 𝐿 ∷ 𝑋 ∷ 𝑋 ∷ β„“ = ones β„“
tens 𝑋 ∷ 𝑋 ∷ β„“ = ones β„“
tens 𝑋 ∷ 𝐿 ∷ β„“ = ones β„“
tens 𝐿 ∷ 𝑋 ∷ β„“ = ones β„“
tens 𝑋 ∷ 𝐢 ∷ β„“ = ones β„“
tens 𝑋 ∷ β„“ = ones β„“
tens 𝐿 ∷ β„“ = ones β„“
tens ls = ones ls
infix 4 hundreds_
hundreds_ : List Literal β†’ Set
hundreds 𝐷 ∷ 𝐢 ∷ 𝐢 ∷ 𝐢 ∷ β„“ = tens β„“
hundreds 𝐢 ∷ 𝐢 ∷ 𝐢 ∷ β„“ = tens β„“
hundreds 𝐷 ∷ 𝐢 ∷ 𝐢 ∷ β„“ = tens β„“
hundreds 𝐢 ∷ 𝐢 ∷ β„“ = tens β„“
hundreds 𝐢 ∷ 𝐷 ∷ β„“ = tens β„“
hundreds 𝐷 ∷ 𝐢 ∷ β„“ = tens β„“
hundreds 𝐢 ∷ 𝑀 ∷ β„“ = tens β„“
hundreds 𝐢 ∷ β„“ = tens β„“
hundreds 𝐷 ∷ β„“ = tens β„“
hundreds β„“ = tens β„“
infix 4 thousands_
thousands_ : List Literal β†’ Set
thousands 𝑀 ∷ 𝑀 ∷ 𝑀 ∷ β„“ = hundreds β„“
thousands 𝑀 ∷ 𝑀 ∷ β„“ = hundreds β„“
thousands 𝑀 ∷ β„“ = hundreds β„“
thousands β„“ = hundreds β„“
infix 4 validRoman_
validRoman_ : List Literal β†’ Set
validRoman β„“ = thousands β„“
infixl 5 _I _V _X _L _C _D _M
data Numeral : {r : List Literal} β†’ Set where
_I : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝐼 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝐼 }
_V : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝑉 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝑉 }
_X : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝑋 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝑋 }
_L : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝐿 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝐿 }
_C : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝐢 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝐢 }
_D : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝐷 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝐷 }
_M : βˆ€ {r} {{ _ : validRoman r ∷ʳ 𝑀 }} β†’ Numeral {r} β†’ Numeral { r ∷ʳ 𝑀 }
α΅£ : Numeral {[]}
-- 112
cvii : Numeral
cvii = α΅£ C V I I
-- 3054
mmmciv : Numeral
mmmciv = α΅£ M M M C I V
-- 999
cmxcix : Numeral
cmxcix = α΅£ C M X C I X
-- Will not typecheck - I before M
-- im : Numeral
-- im = α΅£ I M
-- Will not type typecheck - more than three I in a row
-- iiii : Numeral
-- iiii = α΅£ I I I I
-- Will not typecheck - additives after substractive
-- ivii : Numeral
-- ivii = α΅£ I V I I
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment