[Agda] Proofs for enumerated types

Nils Anders Danielsson nad at Cs.Nott.AC.UK
Sat Sep 11 21:02:25 CEST 2010


On 2010-09-10 23:01, Gregory Crosswhite wrote:
> However, I feel like there should be a more elegant way of doing this.
> Since the type is a set that only contains a finite number of values,
> such properties as associativity, commutativity, existence of an inverse
> (I), etc. can be proven by performing a brute-force examination of all
> the possibilities. There is probably a way to do this somewhere in the
> standard libraries [...]

Indeed there is:

   module Pauli where

   import Algebra.FunctionProperties
   open import Data.Fin
   open import Data.Fin.Props using (eq?)
   open import Data.Fin.Dec using (all?)
   open import Function
   open import Function.LeftInverse
   open import Relation.Binary.PropositionalEquality as P
   open import Relation.Nullary

   data Pauli : Set where
     I X Y Z : Pauli

   infixl 7 _⋅_

   _⋅_ : Pauli → Pauli → Pauli
   _ ⋅ I = I
   I ⋅ _ = I
   X ⋅ X = I
   X ⋅ Y = Z
   X ⋅ Z = Y
   Y ⋅ X = Z
   Y ⋅ Y = I
   Y ⋅ Z = X
   Z ⋅ X = Y
   Z ⋅ Y = X
   Z ⋅ Z = I

   -- Injection into Fin 4.

   to : Pauli → Fin 4
   to I = # 0
   to X = # 1
   to Y = # 2
   to Z = # 3

   from : Fin 4 → Pauli
   from zero = I
   from (suc zero) = X
   from (suc (suc zero)) = Y
   from (suc (suc (suc zero))) = Z
   from (suc (suc (suc (suc ()))))

   finite : LeftInverse (P.setoid Pauli) (P.setoid (Fin 4))
   finite = record
     { to              = P.→-to-⟶ to
     ; from            = P.→-to-⟶ from
     ; left-inverse-of = from∘to
     }
     where
     from∘to : ∀ x → from (to x) ≡ x
     from∘to I = refl
     from∘to X = refl
     from∘to Y = refl
     from∘to Z = refl

   -- Deciding equality is easy for finite sets.

   infix 4 _≟_

   _≟_ : (p₁ p₂ : Pauli) → Dec (p₁ ≡ p₂)
   _≟_ = eq? (LeftInverse.injection finite)

   -- Proving that a commutative operation actually is commutative is
   -- also easy. We can start by deciding whether the operator, lifted to
   -- Fin 4, is commutative.

   private

     _○_ = _⋅_ on from

     ○-comm? : Dec (∀ x y → (x ○ y) ≡ (y ○ x))
     ○-comm? = all? λ x → all? λ y → (x ○ y) ≟ (y ○ x)

   -- If we evaluate ○-comm? we see that the answer is yes <something>.
   -- Let's extract this <something> and polish it a bit.

   fromYes : ∀ {P : Set} (x : Dec P) {p} → x ≡ yes p → P
   fromYes .(yes p) {p} refl = p

   open Algebra.FunctionProperties {A = Pauli} _≡_

   ⋅-comm : Commutative _⋅_
   ⋅-comm x y =
     P.subst (λ y → x ⋅ y ≡ y ⋅ x)
             (LeftInverse.left-inverse-of finite y) $
       P.subst (λ x → x ⋅ from (to y) ≡ from (to y) ⋅ x)
               (LeftInverse.left-inverse-of finite x) $
               fromYes ○-comm? refl (to x) (to y)

--
/NAD



More information about the Agda mailing list