Data Structures

Lists : Working with Structured Data

From now on, we will see structured data, especially lists and pairs, which can contain elements of various types. In the type definition, we will already show them with polymorphic types, but don't worry, we will talk about it in the next chapter. For now, let's just ignore the type and follow the explanation. It will make more sense as we progress in our study.

Data Structures

In an inductive type definition, each constructor can receive any number of arguments -- none like Bool, Empty, or one like Nat -- and we have the Pair that receives two arguments (which can even be other two pairs) and returns a type:

record Pair (a) (b) 

The two received arguments are transformed into the first component, fst, and the second, snd.

record Pair (a) (b) {
  fst : a
  snd : b
} 

The way to construct a pair of Nat is as follows:

Pair.new Nat Nat a b  : (Pair a b)

Here are two simple functions to extract the first and second components of a pair. The definitions also illustrate how to pattern match on two constructor arguments.

Fst (pair: Pair Nat Nat) : Nat
Fst (Pair.new Nat Nat fst snd) = fst
Example 1: (Fst Nat (List Nat) (Pair 2n [1n,2n,3n])) ->  2n
Snd (pair: Pair Nat Nat) : Nat
Snd (Pair.new Nat Nat fst snd) = snd
Example 2: (Snd Nat (List Nat) (Pair 2n [1n,2n,3n])) -> [1n,2n,3n]

Some proofs

Let's try to prove some simple facts about pairs. If we declare things in a particular (and slightly peculiar) way, we can complete proofs with just reflexivity:

Surjective_pairing (p: Pair Nat Nat) : Equal (Pair Nat Nat) p (Pair.new (Fst p) (Snd p))
Surjective_pairing (Pair.new Nat Nat fst snd) = Equal.refl

But Equal.refl is not enough if the statement is:

Surjective_pairing (Pair.new Nat Nat fst snd) = Equal.refl

Since Kind expects

Equal (Pair Nat Nat) p (Pair.new (Fst p) (Snd p))

And received

Equal p p

We must "expose" the internal structure of the pair so that the Type Checker can verify whether p is really equal to Pair.new (Fst p) (Snd p).

Snd_fst_is_swap

Snd_fst_is_swap (p: Pair Nat Nat ) : Equal (Pair Nat Nat) (Pair.swap Nat Nat (Pair.swap Nat Nat p) p)
Snd_fst_is_swap (Pair.new Nat Nat fst snd) = ? 

Fst_swap_is_snd

Fst_swap_is_inverse (p: Pair Nat Nat) (a: Nat) (b: Nat) : Equal (Pair Nat Nat) (Pair.swap Nat Nat (Pair.new a b) (Pair.new b a))
Fst_swap_is_inverse p a b = ?