\import Category.Adjoint
\import Category.CartesianClosed
\import Category.Functor
\import Function.Meta
\import Order.Lattice
\import Order.PartialOrder
\import Paths
\lemma \infixr 9 =<= {E : Preorder} {x y z : E}
(p : x = y) (q : y <= z) : x <= z => transport (__ <= z) (inv p) q
\class HeytingAlebra \extends BoundedDistributiveLattice, CartesianClosedPrecat (\lp, \lp) {
| implies \alias \infixr 5 --> : E -> E -> E
| exponent-left {x a b : E} : x ∧ a <= b -> x <= a --> b
| exponent-right {x a b : E} : x <= a --> b -> x ∧ a <= b
\default top \as top-impl => bottom --> bottom
\default top-univ {x : E} : x <= top-impl => exponent-left meet-right
\default ldistr>= {x y z : E} : x ∧ (y ∨ z) <= (x ∧ y) ∨ (x ∧ z) => meet-comm =<= exponent-right (join-univ (exponent-left (meet-comm =<= join-left)) (exponent-left (meet-comm =<= join-right)))
\use \lemma eval {x y : E} : (x --> y) ∧ x <= y
=> exponent-right <=-refl
\lemma modus-ponens {x y : E} : x ∧ (x --> y) <= y
=> meet-comm =<= eval
\lemma composition-law {x y z : E} : (x --> y) ∧ (y --> z) <= x --> z
=> exponent-left $ (meet-assoc *> meet-comm *> meet-assoc) =<= meet-monotone <=-refl modus-ponens <=∘ eval
\func continuation (y : E) (x : E) => (x --> y) --> y
\func neg (x : E) => x --> bottom
\lemma neg_bottom : neg bottom = top
=> <=-antisymmetric TopMeetSemilattice.top-univ (exponent-left meet-right)
\lemma neg_top : neg top = bottom
=> <=-antisymmetric (meet-univ <=-refl TopMeetSemilattice.top-univ <=∘ eval) bottom-univ
\lemma id<=neg_neg {x : E} : x <= neg (neg x)
=> double-->-increasing
\lemma neg_join {x y : E} : neg (x ∨ y) = neg x ∧ neg y
=> -->_join
\func IsNegated (x : E) : \Prop
=> neg (neg x) <= x
\lemma bottom-negated : IsNegated bottom
=> =_<= $ pmap neg neg_bottom *> neg_top
\lemma meet-negated {x y : E} (xn : IsNegated x) (yn : IsNegated y) : IsNegated (x ∧ y)
=> meet-univ (double-->-monotone meet-left <=∘ xn) (double-->-monotone meet-right <=∘ yn)
\lemma neg-negated {x : E} : IsNegated (neg x)
=> _-->-antimonotone double-->-increasing
\func double-neg => continuation bottom
\func curry {x y z : E} : x ∧ y --> z <= x --> (y --> z) =>
exponent-left (exponent-left (meet-assoc =<= eval))
\use \func -->-monotone {x y z : E} (p : y <= z) : x --> y <= x --> z => exponent-left (eval <=∘ p)
\func -->-increasing {x y : E} : y <= x --> y => exponent-left meet-left
\use \lemma meet-monotone-partial {x y z : E} (p : y <= z) : x ∧ y <= x ∧ z => meet-monotone <=-refl p
\use \lemma meet-monotone-partial' {x y z : E} (p : x <= y) : x ∧ z <= y ∧ z =>
meet-comm =<= meet-monotone-partial p <=∘ (=_<= meet-comm)
\lemma _-->-antimonotone {x y z : E} (p : y <= z) : z --> x <= y --> x
=> exponent-left (meet-monotone-partial p <=∘ eval)
\lemma -->_join {x y z : E} : x ∨ y --> z = (x --> z) ∧ (y --> z)
=> <=-antisymmetric (meet-univ (_-->-antimonotone join-left) (_-->-antimonotone join-right)) $ exponent-left $
ldistr>= <=∘ join-univ (meet-monotone meet-left <=-refl <=∘ eval) (meet-monotone meet-right <=-refl <=∘ eval)
\lemma double-->-increasing {x y : E} : x <= (x --> y) --> y => exponent-left modus-ponens
\lemma double-->-idempotent {x y : E} : (((x --> y) --> y) --> y) --> y <= (x --> y) --> y
=> exponent-left (meet-monotone-partial double-->-increasing <=∘ eval)
\lemma double-->-monotone {x y z : E} (p : y <= z) : continuation x y <= continuation x z
=> exponent-left (meet-monotone-partial (_-->-antimonotone p) <=∘ eval)
\use \lemma exponent-adj-unit {x y : E} : x <= y --> x ∧ y => exponent-left <=-refl
\use \lemma adj-lemma {x y z : E} (f : x <= z --> y) : x ∧ z <= y => meet-monotone-partial' f <=∘ eval
\use \func exponent-functor (X : E) : Functor \this \this \cowith
| F Y => X --> Y
| Func f => -->-monotone f
| Func-id => idp
| Func-o => idp
\default exp (Y : E) : RightAdjoint \this \this \cowith
| LAdj => bprodFunctorRight Y
| Functor => exponent-functor Y
| eta {
| trans X => exponent-adj-unit
| natural f => idp
}
| epsilon {
| trans X => eval
| natural f => idp
}
| eta_epsilon-left => idp
| eta_epsilon-right => idp
}