[Agda] Help with proofs
Ulf Norell
ulfn at cs.chalmers.se
Tue Apr 29 13:11:36 CEST 2008
Many of your problems come from the clunky proof objects you're passing
around
everywhere. It's often a better idea to represent these kind of constraints
using indexing. Here's how I would do it:
module Octet where
data Nat : Set where
zero : Nat
suc : Nat -> Nat
_+_ : Nat -> Nat -> Nat
zero + m = m
suc n + m = suc (n + m)
{-# BUILTIN NATURAL Nat #-}
{-# BUILTIN ZERO zero #-}
{-# BUILTIN SUC suc #-}
{-# BUILTIN NATPLUS _+_ #-}
-- The first thing we want to keep track of is 'zeroness'. We could use a
-- boolean here, but I find that things get clearer if you give them
-- appopriate names.
data IsZero : Set where
nonZero : IsZero
isZero : IsZero
-- This function will be used to compute the zeroness of an 'or'.
bothZero : IsZero -> IsZero -> IsZero
bothZero nonZero _ = nonZero
bothZero isZero z = z
-- We also want to know whether the least significant bit is set or not.
-- This can be represented by the parity of the number.
data Parity : Set where
even : Parity
odd : Parity
-- The parity of an 'or'.
bothEven : Parity -> Parity -> Parity
bothEven odd _ = odd
bothEven even p = p
-- The final thing we need to track is the width (or an upper bound on the
-- width) of a bit vector. We can model that as a natural number.
Width = Nat
-- Now a bit vector is datatype indexed by its width, whether it's zero, and
-- its parity. Note that this type encodes bit vectors of arbitrary length.
-- We'll get to octets later.
data Bits : Width -> IsZero -> Parity -> Set where
zero : forall {n} -> Bits n isZero even
setLow : forall {n z} -> Bits (suc n) z even -> Bits (suc n) nonZero odd
shift : forall {n p} -> Bits n nonZero p -> Bits (suc n) nonZero even
-- Turning a bit vector to a natural number looks the same as before.
toNat : forall {n z p} -> Bits n z p -> Nat
toNat zero = 0
toNat (setLow a) = suc (toNat a)
toNat (shift a) = toNat a + toNat a
-- The difference is that 'or' is defined just as you would like to define
-- it, without any annoying proof objects obscuring the definition, an there
-- are no lemmas to prove.
_or_ : forall {n z₁ z₂ p₁ p₂} -> Bits n z₁ p₁ -> Bits n z₂ p₂ ->
Bits n (bothZero z₁ z₂) (bothEven p₁ p₂)
zero or b = b
setLow a or zero = setLow a
setLow a or setLow b = setLow (a or b)
setLow a or shift b = setLow (a or shift b)
shift a or zero = shift a
shift a or setLow b = setLow (shift a or b)
shift a or shift b = shift (a or b)
-- Finally an Octet is a bit vector of width 8 with arbitrary zeroness and
-- parity.
data Octet : Set where
octet : forall {z p} -> Bits 8 z p -> Octet
-- 'or' on octets is defined using 'or' on the underlying bit vector.
_or₈_ : Octet -> Octet -> Octet
octet a or₈ octet b = octet (a or b)
I hope this helps.
/ Ulf
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.chalmers.se/mailman/private/agda/attachments/20080429/623a19ef/attachment.html
More information about the Agda
mailing list