text‹We can represent the unboxed naturals as a discrete domain (every
is equal to itself and unequal to everything else, and there is no
). Think of these functions as the machine operations.
could actually lift all HOL types and classes in this way; indeed
HOLCF theory "Lift" does something similar, but is not as
-grained as this development.
: we default to just CPOs (not pointed CPOs) in this theory. We
bothg the Isabelle syntax for overloaded arithmetic and the
for unboxed operators of 🍋‹"SPJ-JL:1991"›.›
default_sort predomain
type_synonym UNat = "nat discr"
instantiation discr :: (zero) zero begin definition zero_discr_def: "0 ≡ Discr 0" instance .. end
lemma zero_discr[simp]: "undiscr 0 = 0"unfolding zero_discr_def by simp
instantiation discr :: (one) one begin definition one_discr_def: "1 ≡ Discr 1" instance .. end
lemma one_discr[simp]: "undiscr 1 = 1"unfolding one_discr_def by simp
instantiation discr :: (ord) ord begin definition less_def[simp]: "m < n ≡ (undiscr m) < (undiscr n)" definition le_def[simp]: "m ≤ n ≡ (undiscr m) ≤ (undiscr n)" instance .. end
definition
uPlus :: "UNat → UNat → UNat"where "uPlus ≡ Λ x y. Discr (undiscr x + undiscr y)"
abbreviation
uPlus_syn :: "UNat ==> UNat ==> UNat" (infixl‹+#›65) where "x +# y ≡ uPlus⋅x⋅y"
instantiation discr :: (plus) plus begin definition plus_discr_def[simp]: "x + y ≡ Discr (undiscr x + undiscr y)" instance .. end
definition
uMinus :: "UNat → UNat → UNat"where "uMinus ≡ Λ x y. Discr (undiscr x - undiscr y)"
abbreviation
uMinus_syn :: "UNat ==> UNat ==> UNat" (infixl‹-#›65) where "x -# y ≡ uMinus⋅x⋅y"
instantiation discr :: (minus) minus begin definition minus_discr_def[simp]: "x - y ≡ Discr (undiscr x - undiscr y)" instance .. end
definition
uMult :: "UNat → UNat → UNat"where "uMult ≡ Λ x y. Discr (undiscr x * undiscr y)"
abbreviation
uMult_syn :: "UNat ==> UNat ==> UNat" (infixl‹*#›65) where "x *# y ≡ uMult⋅x⋅y"
instantiation discr :: (times) times begin definition times_discr_def[simp]: "x * y ≡ Discr (undiscr x * undiscr y)" instance .. end
Brian Huffman helpfully observed, the "@{term "⊥"}" type
supports the monadic operations; it's isomorphic to
's @{term "Maybe a"}, or ML's @{typ "'a option"}.
that @{term "return"} is @{term "up"}.
›
definition
bbind :: "('a::cpo)\<bottom> → ('a → ('b::pcpo)) → 'b"where "bbind ≡ Λ b g. fup⋅g⋅b"
abbreviation
bbind_syn :: "('a::cpo)\<bottom> ==> ('a → ('b::pcpo)) ==> 'b" (infixl‹>>=›65) where "b >>= g ≡ bbind⋅b⋅g"
lemma bbind_leftID[simp]: "up⋅a >>= f = f⋅a"by (simp add: bbind_def) lemma bbind_rightID[simp]: "m >>= up = m"by (cases m, simp_all)
lemma bbind_assoc[simp]: "f >>= g >>= h = f >>= (Λ x. g⋅x >>= h)" by (cases f, simp_all)
lemma bbind_case_distr_strict: "f⋅⊥ = ⊥==> f⋅(g >>= h) = g >>= (Λ x. f⋅(h⋅x))" unfolding bbind_def by (cases g, simp_all)
text‹
composition is sometimes helpful. It forms a monad too,
has many useful algebraic properties. Unfortunately it is more
than is useful to write the lemmas in a way that makes the
-order unifier in the simplifier happy. Seems easier just to
the definition and go from there.
lemma bKleisli_bbind: "(f >>= g) >=> h = f >>= (Λ x. g⋅x >=> h)" by (cases f, simp_all)
text‹
"Box" type denotes computations that, when demanded, yield
@{term "⊥"} or an unboxed value. Note that the @{term "Box"}
is strict, and so merely tags the lifted computation @{typ
'a\⊥"}. @{typ "'a"} can be pointed or unpointed. This approach enables
to distinguish the boxed values from the lifted-function-space that
recursive functions with unboxed codomains.
we suceed in @{term "box"}ing something, then clearly that
was not @{term "⊥"}.
›
lemma box_casedist[case_names bottom Box, cases type: Box]: assumes xbot: "x = ⊥==> P" and xbox: "∧u. x = box⋅u ==> P" shows"P" proof(cases x) case bottom with xbot show ?thesis by simp next case (Box u) with xbox show ?thesis by (cases u, simp_all add: box_def up_def cont_Iup bottomI[OF minimal_up]) qed
the arithmetic operations. We need extra continuity lemmas as
're using the full function space, so we can re-use the conventional
. The goal is to work at this level.
›
instantiation Box :: ("{predomain,plus}") plus begin definition plus_Box_def: "x + y ≡ bliftM2 (Λ a b. a + b)⋅x⋅y" instance .. end
lemma plus_Box_cont[simp, cont2cont]: "[cont g; cont h]==> cont (λx. (g x :: 'a :: {predomain, plus} Box) + h x)" unfolding plus_Box_def by simp
definition
bpred :: "('a::countable discr ==> 'a discr ==> bool) ==> 'a discr Box → 'a discr Box → tr"where "bpred p ≡ Λ x y. unbox⋅x >>= (Λ x'. unbox⋅y >>= (Λ y'. if p x' y' then TT else FF))"
lemma Nat_case_add_1[simp]: assumes ndef: "n ≠⊥" shows"Nat_case⋅z⋅s⋅(n + 1) = s⋅n" proof - from ndef obtain nu where nu: "n = box⋅nu" unfolding box_def apply (cases "n" rule: Box.exhaust) apply simp apply (case_tac "u") apply simp_all done thenobtain u where"nu = Discr u" unfolding box_def apply (cases nu) apply simp done with nu show ?thesis unfolding one_Nat_def by simp qed
lemma Nat_case_case_nat: "Nat_case⋅z⋅s⋅(box⋅(Discr n)) = case_nat z (λn'. s⋅(box⋅(Discr n'))) n" by (simp add: Nat_case_def)
lemma Nat_casedist[case_names bottom zero Suc]: fixes x :: Nat assumes xbot: "x = ⊥==> P" and xzero: "x = 0 ==> P" and xsuc: "∧n. x = n + 1 ==> P" shows"P" proof(cases x rule: Box.exhaust) case bottom with xbot show ?thesis by simp next case (Box u) hence xu: "x = Box⋅u"and ubottom: "u ≠⊥" . from ubottom obtain n where ndn: "u = up⋅(Discr n)"apply (cases u) apply simp_all apply (case_tac x) apply simp done show ?thesis proof(cases n) case0with ndn xu xzero show ?thesis unfolding zero_Nat_def by (simp add: boxI zero_discr_def) next case (Suc m) with ndn xu xsuc[where n="box⋅(Discr m)"] show ?thesis unfolding plus_Box_def unfolding one_Nat_def by (simp add: boxI one_discr_def) qed qed
lemma cont_Nat_case[simp]: "[cont (λx. f x); ∧n. cont (λx. g x⋅n) ]==> cont (λx. Nat_case⋅(f x)⋅(g x)⋅n)" apply (cases n rule: Nat_casedist) apply simp_all apply (case_tac na rule: Box.exhaust) apply simp_all done
lemma Nat_induct[case_names bottom zero Suc]: fixes P :: "Nat ==> bool" assumes xbot: "P ⊥" and xzero: "P 0" and xsuc: "∧n. [n ≠⊥; P n ]==> P (n + 1)" shows"P x" proof(cases x rule: box_casedist) case bottom with xbot show ?thesis by simp next case (Box u) thenobtain n where un: "u = Discr n"by (cases u, simp)
{ fix n have"∧x. x = box⋅(Discr n) ==> P x" proof(induct n) case0with xzero show ?caseunfolding zero_Nat_def zero_discr_def by simp next case (Suc n) hence"P (box⋅(Discr n))"by simp with xsuc[where n="box⋅(Discr n)"] have"P (box⋅(Discr n) + 1)"unfolding box_def by simp with Suc show ?caseunfolding one_Nat_def one_discr_def plus_Box_def by simp qed
} with un Box show ?thesis by simp qed
lemma plus_commute: "(x :: Nat) + y = y + x" proof - have dc: "∧u v. (undiscr (u::nat discr) + undiscr v) = (undiscr v + undiscr u)" by simp thus ?thesis apply (cases x) apply simp apply (cases y) by (simp_all add: dc plus_Box_def) qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.