Let’s assume we have four programs:
c₁ : B → C
c₂ : A → D
id : ∀ {T} T → T
swap₊ : ∀ {X Y} X + Y → Y + X
And two ways to “compose” programs:
_⊕_ : (A → B) → (C → D) → (A + C → B + D)
_⊙_ : (A → B) → (B → C) → (A → C)
We can now form four programs that are in some sense “equivalent”:
p₁ p₂ p₃ p₄ : (A + B) → (C + D)
p₁ = (c₂ ⊕ c₁) ⊙ swap₊
p₂ = swap₊ ⊙ (c₁ ⊕ c₂)
p₃ = (id ⊕ c₁) ⊙ swap₊ ⊙ (id ⊕ c₂)
p₄ = (c₂ ⊕ id) ⊙ swap₊ ⊙ (c₁ ⊕ id)
It means we can build bridges among these four “islands”:

It’s much clearer if I draw four “wiring diagrams” representing p₁ to p₄:

Now I can tell you that 1 rule of diagrammatic reasoning is enough to prove these equivalences:
Circuits can freely slide along wires.
Imagining in you mind!
In order to prove that p₁ p₂ p₃ p₄ are all equivalent “formally”, we need more than just 1 rule.
First of all, we need a rule with which we can prove p₁ ⇔ p₂ with zero effort:
swapr = (c₂ ⊕ c₁) ⊙ swap₊ ⇔ swap₊ ⊙ (c₁ ⊕ c₂) -- it's called "double sliding"
Then we need a rule for “doing nothing”. It’s like a identity program transformation or identity proof:
_ = c ⇔ c
We also need two rules idl and idr, to “append” and “prepend” the identity program:
idl = c ⇔ id ⊙ c
idr = c ⇔ c ⊙ id
We need re-organize and associativity to perform “re-focusing” within proofs:
re-organize = (c₁ ⊙ c₂) ⊕ (c₃ ⊙ c₄) ⇔ (c₁ ⊕ c₃) ⊙ (c₂ ⊕ c₄)
associativity = (c₁ ⊙ c₂) ⊙ c₃ ⇔ c₁ ⊙ (c₂ ⊙ c₃)
Besides, we need two compositional rules _▣_ and _□₊_ to compose proofs of “sub-programs”.
_▣_ :
(c₁ ⇔ c₃) → (c₂ ⇔ c₄) →
---------------------------
(c₁ ⊙ c₂) ⇔ (c₃ ⊙ c₄)
_□₊_ :
(c₁ ⇔ c₃) → (c₂ ⇔ c₄) →
---------------------------
(c₁ ⊕ c₂) ⇔ (c₃ ⊕ c₄)
The formal proof of p₁ ⇔ p₃ is shown below:
p₁-p₃ : p₁ ⇔ p₃ -- it's called single sliding
p₁-p₃ =
begin₂
(c₂ ⊕ c₁) ⊙ swap₊
⇔⟨ (idl □₊ idr) ▣ _ ⟩
((id ⊙ c₂) ⊕ (c ⊙ id₁)) ⊙ swap₊
⇔⟨ re-organize ▣ _ ⟩
((id ⊕ c₁) ⊙ (c₂ ⊕ id)) ⊙ swap₊
⇔⟨ associativity ⟩
(id ⊕ c₁) ⊙ ((c₂ ⊕ id) ⊙ swap₊)
⇔⟨ _ ▣ swapr ⟩
(id ⊕ c₁) ⊙ (swap₊ ⊙ (id ⊕ c₂))
end₂
The formal proof of p₁ ⇔ p₃ can also be shown diagrammatically:

Step 0: preparation.

Step 1: apply idl and idr to c₂ and c₂ respectively with _□₊_, and leave swap₊ alone (_▣_ silently applied).

Step 2: re-organize the left part of the program, and leave swap₊ alone (_▣_ applied silently).

Step 3: apply associativity to the whole program.

Step 4: apply swapr to the right part of the program, and leave the left part alone (_▣_ applied silently).
↶ Home