-
Notifications
You must be signed in to change notification settings - Fork 509
Formalize integer division and CIntegers in the metatheory #7864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 5 commits
c0a2e4e
c78d595
84f807f
fcc95e2
1e87f26
0d9f487
9937f81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| evaluation failure |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ### Added | ||
|
|
||
| - Formalized `CInteger` and all of the `BuiltinInteger` functions which depend on it. | ||
| - Removed the postulates for `divideInteger`, `modInteger`, `quotientInteger` and `remainderInteger`, they are now implemented in the metatheory. | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,9 @@ open Sig | |
| open Builtin.Signature.FromSig _⊢Nf⋆_ _⊢Ne⋆_ ne ` _·_ ^ con _⇒_ Π | ||
| using (sig2type;⊢♯2TyNe♯;SigTy;sig2SigTy;saturatedSigTy;convSigTy) | ||
| open SigTy | ||
|
|
||
| import Builtin.CInteger as CInt | ||
| open CInt using (CInteger; cInt) | ||
| ``` | ||
|
|
||
| ```` | ||
|
|
@@ -186,6 +189,11 @@ discharge (V-con c) = con c refl | |
| discharge (V-I⇒ b bt) = dischargeB bt | ||
| discharge (V-IΠ b bt) = dischargeB bt | ||
| discharge (V-constr i Tss s refl) = constr i Tss refl (dischargeStack s) | ||
|
|
||
| mkCInteger : ℤ → Either (∅ ⊢Nf⋆ *) CInteger | ||
| mkCInteger i with CInt.minBound ≤? i | i ≤? CInt.maxBound | ||
| mkCInteger i | yes p | yes q = return (cInt i p q) | ||
| mkCInteger i | _ | _ = inj₁ (con (ne (^ (atomic aInteger)))) | ||
| ``` | ||
|
|
||
| ## Builtin Semantics | ||
|
|
@@ -194,28 +202,48 @@ If a builtin returns a value, then this function produces a `Value`, otherwise i | |
| a type that could be used in constructing the error term. | ||
| ``` | ||
| BUILTIN : ∀ b {A} → {Ab : saturatedSigTy (signature b) A} → BApp b A Ab → Either (∅ ⊢Nf⋆ *) (Value A) | ||
| BUILTIN addInteger (base $ V-con i $ V-con i') = inj₂ (V-con (i + i')) | ||
| BUILTIN subtractInteger (base $ V-con i $ V-con i') = inj₂ (V-con (i - i')) | ||
| BUILTIN multiplyInteger (base $ V-con i $ V-con i') = inj₂ (V-con (i ** i')) | ||
| BUILTIN divideInteger (base $ V-con i $ V-con i') = decIf | ||
| (i' ≟ ℤ.pos 0) | ||
| (inj₁ (con (ne (^ (atomic aInteger))))) | ||
| (inj₂ (V-con (div i i'))) | ||
| BUILTIN quotientInteger (base $ V-con i $ V-con i') = decIf | ||
| (i' ≟ ℤ.pos 0) | ||
| (inj₁ (con (ne (^ (atomic aInteger))))) | ||
| (inj₂ (V-con (quot i i'))) | ||
| BUILTIN remainderInteger (base $ V-con i $ V-con i') = decIf | ||
| (i' ≟ ℤ.pos 0) | ||
| (inj₁ (con (ne (^ (atomic aInteger))))) | ||
| (inj₂ (V-con (rem i i'))) | ||
| BUILTIN modInteger (base $ V-con i $ V-con i') = decIf | ||
| (i' ≟ ℤ.pos 0) | ||
| (inj₁ (con (ne (^ (atomic aInteger))))) | ||
| (inj₂ (V-con (mod i i'))) | ||
| BUILTIN lessThanInteger (base $ V-con i $ V-con i') = decIf (i <? i') (inj₂ (V-con true)) (inj₂ (V-con false)) | ||
| BUILTIN lessThanEqualsInteger (base $ V-con i $ V-con i') = decIf (i ≤? i') (inj₂ (V-con true)) (inj₂ (V-con false)) | ||
| BUILTIN equalsInteger (base $ V-con i $ V-con i') = decIf (i ≟ i') (inj₂ (V-con true)) (inj₂ (V-con false)) | ||
| BUILTIN addInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| return (V-con (CInt.add i₁ i₂)) | ||
| BUILTIN subtractInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| return (V-con (CInt.subtract i₁ i₂)) | ||
| BUILTIN multiplyInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| return (V-con (CInt.multiply i₁ i₂)) | ||
| BUILTIN divideInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| i₁/i₂ ← maybeToEither (con (ne (^ (atomic aInteger)))) (CInt.div i₁ i₂) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe using a name like that looks like an operation could lead to confusion, especially where |
||
| return (V-con i₁/i₂) | ||
| BUILTIN quotientInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| i₁/i₂ ← maybeToEither (con (ne (^ (atomic aInteger)))) (CInt.quot i₁ i₂) | ||
| return (V-con i₁/i₂) | ||
| BUILTIN remainderInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| i₁%i₂ ← maybeToEither (con (ne (^ (atomic aInteger)))) (CInt.rem i₁ i₂) | ||
| return (V-con i₁%i₂) | ||
| BUILTIN modInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| i₁%i₂ ← maybeToEither (con (ne (^ (atomic aInteger)))) (CInt.mod i₁ i₂) | ||
| return (V-con i₁%i₂) | ||
| BUILTIN lessThanInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| return (V-con (CInt.lessThan i₁ i₂)) | ||
| BUILTIN lessThanEqualsInteger (base $ V-con i $ V-con i') = do | ||
| i₁ ← mkCInteger i | ||
| i₂ ← mkCInteger i' | ||
| return (V-con (CInt.lessThanEquals i₁ i₂)) | ||
| BUILTIN equalsInteger (base $ V-con i $ V-con i') = | ||
| decIf (i ≟ i') (inj₂ (V-con true)) (inj₂ (V-con false)) | ||
| BUILTIN appendByteString (base $ V-con b $ V-con b') = inj₂ (V-con (concat b b')) | ||
| BUILTIN lessThanByteString (base $ V-con b $ V-con b') = inj₂ (V-con (B< b b')) | ||
| BUILTIN lessThanEqualsByteString (base $ V-con b $ V-con b') = inj₂ (V-con (B<= b b')) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| --- | ||
| title: CInteger | ||
| layout: page | ||
| --- | ||
|
|
||
| This module contains the formalisation of Cardano Integers. | ||
|
|
||
| ``` | ||
| module Builtin.CInteger where | ||
| ``` | ||
|
|
||
| ## Imports | ||
|
|
||
| ``` | ||
| open import Data.Integer.Properties using (_≟_; _<?_; _≤?_) | ||
| open import Relation.Nullary using (Dec; yes; no; isYes) | ||
| open import Data.Integer.Base | ||
| open import Data.Nat.Base as ℕ using (ℕ) | ||
| open import Data.Sign.Base as S using (Sign) | ||
| open import Data.Product.Base using (_×_; _,_; proj₁; proj₂) | ||
| open import Data.Maybe using (Maybe; just; nothing; map) | ||
| import Data.Maybe.Effectful as MaybeEff | ||
| open import Effect.Monad using (RawMonad) | ||
| import Agda.Primitive as Level | ||
| open RawMonad {f = Level.lzero} MaybeEff.monad | ||
| open import Relation.Binary.PropositionalEquality | ||
| open import Data.Maybe.Properties using (≡-dec) | ||
| import Builtin.Integer.Base as Bℤ | ||
| open import Data.Bool using (Bool) | ||
|
|
||
| ``` | ||
|
|
||
| ## The CInteger type | ||
|
|
||
| The `CInteger` type is a restriction of the `ℤ` type to the range of integers specified by `minBound` and `maxBound`. | ||
|
|
||
| This type constitutes the denotational semantics of the Cardano `BuiltinInteger` type for all of the inputs to the `BuiltinInteger` builtin functions, except `equalsInteger` and `expModInteger`. | ||
|
|
||
| The inputs to `equalsInteger` are of the unrestricted `ℤ` type. The `expModInteger` function is not yet formalised and is left as future work. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| ``` | ||
| minBound : ℤ | ||
| minBound = - ((+ 2) ^ 262143) | ||
| maxBound : ℤ | ||
| maxBound = ((+ 2) ^ 262143) - (+ 1) | ||
|
|
||
| data CInteger : Set where | ||
| cInt | ||
| : (i : ℤ) | ||
| → i ≥ minBound | ||
| → i ≤ maxBound | ||
| → CInteger | ||
| ``` | ||
|
|
||
| ## CInteger operations | ||
|
|
||
| ``` | ||
| add : CInteger → CInteger → ℤ | ||
| add (cInt i _ _) (cInt j _ _) = i + j | ||
|
|
||
| subtract : CInteger → CInteger → ℤ | ||
| subtract (cInt i _ _) (cInt j _ _) = i - j | ||
|
|
||
| multiply : CInteger → CInteger → ℤ | ||
| multiply (cInt i _ _) (cInt j _ _) = i * j | ||
|
|
||
| quot : CInteger → CInteger → Maybe ℤ | ||
| quot (cInt n _ _) (cInt d _ _) with d ≟ + 0 | ||
| ... | yes _ = nothing | ||
| ... | no d≢0 = just (Bℤ.quot n d) | ||
| where instance | ||
| _ = ≢-nonZero d≢0 | ||
|
|
||
| rem : CInteger → CInteger → Maybe ℤ | ||
| rem (cInt n _ _) (cInt d _ _) with d ≟ + 0 | ||
| ... | yes _ = nothing | ||
| ... | no d≢0 = just (Bℤ.rem n d) | ||
| where instance | ||
| _ = ≢-nonZero d≢0 | ||
|
|
||
| divMod : CInteger → CInteger → Maybe (ℤ × ℤ) | ||
| divMod (cInt n _ _) (cInt d _ _) with d ≟ + 0 | ||
| ... | yes _ = nothing | ||
| ... | no d≢0 = just (Bℤ.divMod n d) | ||
| where instance | ||
| _ = ≢-nonZero d≢0 | ||
|
|
||
| div : CInteger → CInteger → Maybe ℤ | ||
| div n d = map proj₁ (divMod n d) | ||
|
|
||
| mod : CInteger → CInteger → Maybe ℤ | ||
| mod n d = map proj₂ (divMod n d) | ||
|
|
||
| lessThan : CInteger → CInteger → Bool | ||
| lessThan (cInt i _ _) (cInt j _ _) = isYes (i <? j) | ||
|
|
||
| lessThanEquals : CInteger → CInteger → Bool | ||
| lessThanEquals (cInt i _ _) (cInt j _ _) = isYes (i ≤? j) | ||
| ``` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(con (ne (^ (atomic aInteger))))shows up multiple times. Would it be worth defining some shorthand form, or is that against the spirit of Agda?