📥 Download raw
module Padova2025.ProvingBasics.Equality.Booleans where

Results on Booleans

open import Padova2025.ProgrammingBasics.Booleans
open import Padova2025.ProgrammingBasics.Operators
open import Padova2025.ProvingBasics.Equality.Base
open import Padova2025.ProvingBasics.Equality.General

Exercise: Double negation

not² : (x : Bool)  not (not x)  x
not² = {!!}

Exercise: Commutativity of logical AND

&&-comm : (x y : Bool)  (x && y)  (y && x)
&&-comm = {!!}

Tautologies

Before we have discussed a function is-tautology₁ : (Bool → Bool) → Bool with the purpose of returning true if and only if the first argument is constantly true. A straightforward implementation is the following:

is-tautology₁ : (Bool → Bool) → Bool
is-tautology₁ f = f false && f true

However, a more cryptic implementation is also possible.

is-tautology₁' : (Bool  Bool)  Bool
is-tautology₁' f = f (f false)

Let us verify that this alternatively works correctly. To this end, we first formalize what it means for a function to be constantly true:

ConstantlyTrue : (Bool  Bool)  Set
ConstantlyTrue f = (x : Bool)  f x  true

In other words, an element of the type ConstantlyTrue f is a function which maps every input x : Bool to a witness that f x ≡ true. We are then ready to state and prove that is-tautology₁' f correctly returns true if f is constantly true:

part₁ : (f : Bool  Bool)  ConstantlyTrue f  is-tautology₁' f  true
part₁ = {!!}

The converse direction is more involved. One way to structure the argument is to first verify an auxiliary lemma.

γ : (f : Bool  Bool)  (a : Bool)  f false  a  f a  true  ConstantlyTrue f
γ = {!!}
part₂ : (f : Bool  Bool)  is-tautology₁' f  true  ConstantlyTrue f
part₂ f = {!!}

This way of structuring the argument is due to Martín Escardó, who has explored this topic in great detail.