2014-02-06 03:48:51 +00:00
|
|
|
|
-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
|
-- Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
-- Author: Leonardo de Moura
|
2014-02-12 01:15:12 +00:00
|
|
|
|
import macros subtype
|
2014-02-06 01:33:06 +00:00
|
|
|
|
using subtype
|
|
|
|
|
-- We are encoding the (optional A) as a subset of A → Bool where
|
|
|
|
|
-- none is the predicate that is false everywhere
|
|
|
|
|
-- some(a) is the predicate that is true only at a
|
|
|
|
|
definition optional_pred (A : (Type U)) := (λ p : A → Bool, (∀ x, ¬ p x) ∨ exists_unique p)
|
|
|
|
|
definition optional (A : (Type U)) := subtype (A → Bool) (optional_pred A)
|
|
|
|
|
|
|
|
|
|
namespace optional
|
|
|
|
|
theorem some_pred {A : (Type U)} (a : A) : optional_pred A (λ x, x = a)
|
|
|
|
|
:= or_intror
|
|
|
|
|
(∀ x, ¬ x = a)
|
|
|
|
|
(exists_intro a
|
|
|
|
|
(and_intro (refl a) (take y, assume H : y ≠ a, H)))
|
|
|
|
|
|
|
|
|
|
theorem none_pred (A : (Type U)) : optional_pred A (λ x, false)
|
|
|
|
|
:= or_introl (take x, not_false_trivial) (exists_unique (λ x, false))
|
|
|
|
|
|
2014-02-06 07:04:44 +00:00
|
|
|
|
theorem inhab (A : (Type U)) : inhabited (optional A)
|
2014-02-06 01:33:06 +00:00
|
|
|
|
:= subtype_inhabited (exists_intro (λ x, false) (none_pred A))
|
|
|
|
|
|
|
|
|
|
definition none {A : (Type U)} : optional A
|
2014-02-06 07:04:44 +00:00
|
|
|
|
:= abst (λ x, false) (inhab A)
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
|
|
|
|
definition some {A : (Type U)} (a : A) : optional A
|
2014-02-06 07:04:44 +00:00
|
|
|
|
:= abst (λ x, x = a) (inhab A)
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
|
|
|
|
definition is_some {A : (Type U)} (n : optional A) := ∃ x : A, some x = n
|
|
|
|
|
|
|
|
|
|
theorem injectivity {A : (Type U)} {a a' : A} : some a = some a' → a = a'
|
2014-02-06 17:15:12 +00:00
|
|
|
|
:= assume Heq : some a = some a',
|
|
|
|
|
have eq_reps : (λ x, x = a) = (λ x, x = a'),
|
|
|
|
|
from abst_inj (inhab A) (some_pred a) (some_pred a') Heq,
|
|
|
|
|
show a = a',
|
2014-02-10 00:15:44 +00:00
|
|
|
|
from (congr1 eq_reps a) ◂ (refl a)
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
|
|
|
|
theorem distinct {A : (Type U)} (a : A) : some a ≠ none
|
2014-02-09 19:30:49 +00:00
|
|
|
|
:= not_intro (assume N : some a = none,
|
2014-02-06 17:15:12 +00:00
|
|
|
|
have eq_reps : (λ x, x = a) = (λ x, false),
|
|
|
|
|
from abst_inj (inhab A) (some_pred a) (none_pred A) N,
|
|
|
|
|
show false,
|
2014-02-10 00:15:44 +00:00
|
|
|
|
from (congr1 eq_reps a) ◂ (refl a))
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
|
|
|
|
definition value {A : (Type U)} (n : optional A) (H : is_some n) : A
|
|
|
|
|
:= ε (inhabited_ex_intro H) (λ x, some x = n)
|
|
|
|
|
|
|
|
|
|
theorem is_some_some {A : (Type U)} (a : A) : is_some (some a)
|
|
|
|
|
:= exists_intro a (refl (some a))
|
|
|
|
|
|
|
|
|
|
theorem not_is_some_none {A : (Type U)} : ¬ is_some (@none A)
|
2014-02-09 19:30:49 +00:00
|
|
|
|
:= not_intro (assume N : is_some (@none A),
|
2014-02-06 17:15:12 +00:00
|
|
|
|
obtain (w : A) (Hw : some w = @none A),
|
|
|
|
|
from N,
|
|
|
|
|
show false,
|
2014-02-09 19:30:49 +00:00
|
|
|
|
from absurd Hw (distinct w))
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
|
|
|
|
theorem value_some {A : (Type U)} (a : A) (H : is_some (some a)) : value (some a) H = a
|
2014-02-06 17:15:12 +00:00
|
|
|
|
:= have eq1 : some (value (some a) H) = some a,
|
|
|
|
|
from eps_ax (inhabited_ex_intro H) a (refl (some a)),
|
|
|
|
|
show value (some a) H = a,
|
|
|
|
|
from injectivity eq1
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
2014-02-06 03:48:51 +00:00
|
|
|
|
theorem false_pred {A : (Type U)} {p : A → Bool} (H : ∀ x, ¬ p x) : p = λ x, false
|
|
|
|
|
:= funext (λ x, eqf_intro (H x))
|
|
|
|
|
|
|
|
|
|
theorem singleton_pred {A : (Type U)} {p : A → Bool} {w : A} (H : p w ∧ ∀ y, y ≠ w → ¬ p y) : p = (λ x, x = w)
|
2014-02-06 17:15:12 +00:00
|
|
|
|
:= funext (take x, iff_intro
|
|
|
|
|
(assume Hpx : p x,
|
|
|
|
|
show x = w,
|
2014-02-12 16:49:19 +00:00
|
|
|
|
from by_contradiction (assume N : x ≠ w,
|
|
|
|
|
show false, from absurd Hpx (and_elimr H x N)))
|
2014-02-06 17:15:12 +00:00
|
|
|
|
(assume Heq : x = w,
|
|
|
|
|
show p x,
|
|
|
|
|
from subst (and_eliml H) (symm Heq)))
|
2014-02-06 03:48:51 +00:00
|
|
|
|
|
|
|
|
|
theorem dichotomy {A : (Type U)} (n : optional A) : n = none ∨ ∃ a, n = some a
|
2014-02-06 17:15:12 +00:00
|
|
|
|
:= have pred : optional_pred A (rep n),
|
|
|
|
|
from P_rep n,
|
|
|
|
|
show n = none ∨ ∃ a, n = some a,
|
|
|
|
|
from or_elim pred
|
|
|
|
|
(assume Hl : ∀ x : A, ¬ rep n x,
|
|
|
|
|
have rep_n_eq : rep n = λ x, false,
|
|
|
|
|
from false_pred Hl,
|
|
|
|
|
have rep_none_eq : rep none = λ x, false,
|
|
|
|
|
from rep_abst (inhab A) (λ x, false) (none_pred A),
|
|
|
|
|
show n = none ∨ ∃ a, n = some a,
|
|
|
|
|
from or_introl (rep_inj (trans rep_n_eq (symm rep_none_eq)))
|
|
|
|
|
(∃ a, n = some a))
|
|
|
|
|
(assume Hr : ∃ x, rep n x ∧ ∀ y, y ≠ x → ¬ rep n y,
|
|
|
|
|
obtain (w : A) (Hw : rep n w ∧ ∀ y, y ≠ w → ¬ rep n y),
|
|
|
|
|
from Hr,
|
|
|
|
|
have rep_n_eq : rep n = λ x, x = w,
|
|
|
|
|
from singleton_pred Hw,
|
|
|
|
|
have rep_some_eq : rep (some w) = λ x, x = w,
|
|
|
|
|
from rep_abst (inhab A) (λ x, x = w) (some_pred w),
|
|
|
|
|
have n_eq_some : n = some w,
|
|
|
|
|
from rep_inj (trans rep_n_eq (symm rep_some_eq)),
|
|
|
|
|
show n = none ∨ ∃ a, n = some a,
|
|
|
|
|
from or_intror (n = none)
|
2014-02-06 03:48:51 +00:00
|
|
|
|
(exists_intro w n_eq_some))
|
|
|
|
|
|
|
|
|
|
theorem induction {A : (Type U)} {P : optional A → Bool} (H1 : P none) (H2 : ∀ x, P (some x)) : ∀ n, P n
|
|
|
|
|
:= take n, or_elim (dichotomy n)
|
2014-02-06 17:15:12 +00:00
|
|
|
|
(assume Heq : n = none,
|
|
|
|
|
show P n,
|
|
|
|
|
from subst H1 (symm Heq))
|
|
|
|
|
(assume Hex : ∃ a, n = some a,
|
|
|
|
|
obtain (w : A) (Hw : n = some w),
|
|
|
|
|
from Hex,
|
|
|
|
|
show P n,
|
|
|
|
|
from subst (H2 w) (symm Hw))
|
2014-02-06 01:33:06 +00:00
|
|
|
|
|
|
|
|
|
set_opaque some true
|
|
|
|
|
set_opaque none true
|
|
|
|
|
set_opaque is_some true
|
|
|
|
|
set_opaque value true
|
|
|
|
|
end
|
2014-02-06 03:48:51 +00:00
|
|
|
|
|
2014-02-06 01:33:06 +00:00
|
|
|
|
set_opaque optional true
|
|
|
|
|
set_opaque optional_pred true
|
2014-02-06 07:04:44 +00:00
|
|
|
|
definition optional_inhabited := optional::inhab
|
2014-02-06 01:33:06 +00:00
|
|
|
|
add_rewrite optional::is_some_some optional::not_is_some_none optional::distinct optional::value_some
|