{-# OPTIONS --allow-unsolved-metas #-}
{-
  Session 3

  Proposal for today:
  - equational reasoning
  - logical connectives: ¬, ∨, ∃, ∧
  - (perhaps) termination

  Proposal for tomorrow:
  - (perhaps) program verification
  - (perhaps) computational content of classical logic
-}

-- Shortcut to move to the next hole: C-c C-f

data  : Set where
  zero : 
  succ :   

_+_ :     
zero   + b = b
succ a + b = succ (a + b)

open import Padova2025.ProvingBasics.Equality.Base
open import Padova2025.ProvingBasics.Equality.Reasoning.Core

two : 
two = succ (succ zero)

four : 
four = succ (succ (succ (succ zero)))

grande-teorema : (two + two)  four
grande-teorema = refl

cong : {X Y : Set} {a b : X} (f : X  Y)  a  b  f a  f b
cong f refl = refl

sym : {X : Set} {a b : X}  a  b  b  a
sym refl = refl

+-zero : (y : )  (y + zero)  y
+-zero zero     = refl
+-zero (succ y) = cong succ (+-zero y)

+-succ : (x y : )  (x + succ y)  succ (x + y)
+-succ zero     y = refl
+-succ (succ x) y = cong succ (+-succ x y)

-- Agda is a calculator, but not for numbers, and instead for logic!

trans : {X : Set} {a b c : X}  a  b  b  c  a  c
trans = {!!}

+-comm : (x y : )  (x + y)  (y + x)
+-comm zero     y = sym (+-zero y)
+-comm (succ x) y = trans (sym (+-succ x y)) (trans (+-comm x (succ y)) (sym (+-succ y x)))

+-comm' : (x y : )  (x + y)  (y + x)
+-comm' zero     y = sym (+-zero y)
+-comm' (succ x) y = begin
  (succ x + y) ≡⟨⟩     -- \< \>
  succ (x + y) ≡˘⟨ +-succ x y   -- \u{}
  x + succ y   ≡⟨ +-comm' x (succ y) 
  succ (y + x) ≡˘⟨ +-succ y x 
  y + succ x                -- \qed
-- This style of proving is called "equational reasoning".

data Even :   Set where
  base-even : Even zero
  step-even : {n : }  Even n  Even (succ (succ n))

-- Logical reading: For all numbers x, for all numbers y, if x equals y, and if x is even, then y is even.
-- Computational reading: `lemma` is a function which inputs
-- 1. a number x
-- 2. a number y
-- 3. a witness that x equals y
-- 4. a witness that x is even
-- and outputs a witness that y is even.
lemma : {x y : }  x  y  Even x  Even y
lemma refl q = q

subst : {A : Set} {P : A  Set} {x y : A}  x  y  P x  P y
subst refl q = q
-- `lemma` is the special case of `subst` where `P` is instantiated with `Even`.

-- Option 1: Immediately proceed with the logical connectives ¬, ∨, ...
-- Option 2: Exercises with equational reasoning

-- In logic, we define ¬A as "A implies a contradiction".
-- Formally, we often write "⊥" instead of "contradiction".

-- There is a type of witnesses of contradiction.
data  : Set where   -- \bot
-- This type is manifestly empty, corresponding to the idea that a contradiction
-- should not have any witnesses.

one : 
one = succ zero

-- "one is not zero"
-- Logical reading: "If one is zero, then ⊥"
-- Computational reading: `theorem` is a function which inputs an (alleged)
-- witness that one equals zero and outputs a witness of ⊥.
theorem : one  zero  
theorem ()
-- "The empty pattern". This signifies that there are no cases.

one-not-even : Even one  
one-not-even ()

¬_ : Set  Set
¬ X = (X  )

one-not-even' : ¬ Even one
one-not-even' = one-not-even

-- Fermat's last theorem: For all positive natural numbers a, b, c, n with n ≥ 3, it is not the case that aⁿ + bⁿ = cⁿ.
-- Fermat's last theorem: For all positive natural numbers a, b, c, n with n ≥ 3, if aⁿ + bⁿ = cⁿ then ⊥.