abbreviation Times :: "[t,t]==>t" (infixr‹×› 50) where"A × B ≡∑_:A. B"
text‹ Reduction: a weaker notion than equality; a hack for simplification. ‹Reduce[a,b]›means either that ‹a = b : A› for some ‹A› or else that ‹a›and ‹b› are textually identical. Does not verify ‹a:A›! Sound because only ‹trans_red› uses a ‹Reduce› premise. No new theorems can be proved about the standard judgments. › axiomatization where
refl_red: "∧a. Reduce[a,a]"and
red_if_equal: "∧a b A. a = b : A ==> Reduce[a,b]"and
trans_red: "∧a b c A. [a = b : A; Reduce[b,c]]==> a = c : A"and
🍋‹Reflexivity›
refl_type: "∧A. A type ==> A = A"and
refl_elem: "∧a A. a : A ==> a = a : A"and
🍋‹Symmetry›
sym_type: "∧A B. A = B ==> B = A"and
sym_elem: "∧a b A. a = b : A ==> b = a : A"and
🍋‹Transitivity›
trans_type: "∧A B C. [A = B; B = C]==> A = C"and
trans_elem: "∧a b c A. [a = b : A; b = c : A]==> a = c : A"and
equal_types: "∧a A B. [a : A; A = B]==> a : B"and
equal_typesL: "∧a b A B. [a = b : A; A = B]==> a = b : B"and
🍋‹Substitution›
subst_type: "∧a A B. [a : A; ∧z. z:A ==> B(z) type]==> B(a) type"and
subst_typeL: "∧a c A B D. [a = c : A; ∧z. z:A ==> B(z) = D(z)]==> B(a) = D(c)"and
subst_elem: "∧a b A B. [a : A; ∧z. z:A ==> b(z):B(z)]==> b(a):B(a)"and
subst_elemL: "∧a b c d A B. [a = c : A; ∧z. z:A ==> b(z)=d(z) : B(z)]==> b(a)=d(c) : B(a)"and
🍋‹The type ‹N›-- natural numbers›
NF: "N type"and
NI0: "0 : N"and
NI_succ: "∧a. a : N ==> succ(a) : N"and
NI_succL: "∧a b. a = b : N ==> succ(a) = succ(b) : N"and
NE: "∧p a b C. [p: N; a: C(0); ∧u v. [u: N; v: C(u)]==> b(u,v): C(succ(u))] ==> rec(p, a, λu v. b(u,v)) : C(p)"and
NEL: "∧p q a b c d C. [p = q : N; a = c : C(0); ∧u v. [u: N; v: C(u)]==> b(u,v) = d(u,v): C(succ(u))] ==> rec(p, a, λu v. b(u,v)) = rec(q,c,d) : C(p)"and
NC0: "∧a b C. [a: C(0); ∧u v. [u: N; v: C(u)]==> b(u,v): C(succ(u))] ==> rec(0, a, λu v. b(u,v)) = a : C(0)"and
NC_succ: "∧p a b C. [p: N; a: C(0); ∧u v. [u: N; v: C(u)]==> b(u,v): C(succ(u))]==> rec(succ(p), a, λu v. b(u,v)) = b(p, rec(p, a, λu v. b(u,v))) : C(succ(p))"and
fst_def: "∧a. fst(a) ≡ split(a, λx y. x)"and
snd_def: "∧a. snd(a) ≡ split(a, λx y. y)"and
🍋‹The sum of two types›
PlusF: "∧A B. [A type; B type]==> A+B type"and
PlusFL: "∧A B C D. [A = C; B = D]==> A+B = C+D"and
PlusI_inl: "∧a A B. [a : A; B type]==> inl(a) : A+B"and
PlusI_inlL: "∧a c A B. [a = c : A; B type]==> inl(a) = inl(c) : A+B"and
PlusI_inr: "∧b A B. [A type; b : B]==> inr(b) : A+B"and
PlusI_inrL: "∧b d A B. [A type; b = d : B]==> inr(b) = inr(d) : A+B"and
PlusE: "∧p c d A B C. [p: A+B; ∧x. x:A ==> c(x): C(inl(x)); ∧y. y:B ==> d(y): C(inr(y)) ]==> when(p, λx. c(x), λy. d(y)) : C(p)"and
PlusEL: "∧p q c d e f A B C. [p = q : A+B; ∧x. x: A ==> c(x) = e(x) : C(inl(x)); ∧y. y: B ==> d(y) = f(y) : C(inr(y))] ==> when(p, λx. c(x), λy. d(y)) = when(q, λx. e(x), λy. f(y)) : C(p)"and
PlusC_inl: "∧a c d A B C. [a: A; ∧x. x:A ==> c(x): C(inl(x)); ∧y. y:B ==> d(y): C(inr(y)) ] ==> when(inl(a), λx. c(x), λy. d(y)) = c(a) : C(inl(a))"and
PlusC_inr: "∧b c d A B C. [b: B; ∧x. x:A ==> c(x): C(inl(x)); ∧y. y:B ==> d(y): C(inr(y))] ==> when(inr(b), λx. c(x), λy. d(y)) = d(b) : C(inr(b))"and
🍋‹The type ‹Eq›\›
EqF: "∧a b A. [A type; a : A; b : A]==> Eq(A,a,b) type"and
EqFL: "∧a b c d A B. [A = B; a = c : A; b = d : A]==> Eq(A,a,b) = Eq(B,c,d)"and
EqI: "∧a b A. a = b : A ==> eq : Eq(A,a,b)"and
EqE: "∧p a b A. p : Eq(A,a,b) ==> a = b : A"and
🍋‹By equality of types, can prove ‹C(p)›from ‹C(eq)›, an elimination rule›
EqC: "∧p a b A. p : Eq(A,a,b) ==> p = eq : Eq(A,a,b)"and
🍋‹The type ‹F›\›
FF: "F type"and
FE: "∧p C. [p: F; C type]==> contr(p) : C"and
FEL: "∧p q C. [p = q : F; C type]==> contr(p) = contr(q) : C"and
🍋‹The type T› 🍋‹Martin-Löf's book (page 68) discusses elimination and computation. Elimination can be derived by computation and equality of types, but with an extra premise ‹C(x)›type ‹x:T›. Also computation can be derived from elimination.›
TF: "T type"and
TI: "tt : T"and
TE: "∧p c C. [p : T; c : C(tt)]==> c : C(p)"and
TEL: "∧p q c d C. [p = q : T; c = d : C(tt)]==> c = d : C(p)"and
TC: "∧p. p : T ==> p = tt : T"
subsection"Tactics and derived rules for Constructive Type Theory"
text‹ Introduction rules. OMITTED: 🪙‹EqI›, because its premise is an ‹eqelem›, not an ‹elem›. › lemmas intr_rls = NI0 NI_succ ProdI SumI PlusI_inl PlusI_inr TI and intrL_rls = NI_succL ProdIL SumIL PlusI_inlL PlusI_inrL
text‹ Elimination rules. OMITTED: 🪙‹EqE›, because its conclusion is an ‹eqelem›, not an ‹elem› 🪙‹TE›, because it does not involve a constructor. › lemmas elim_rls = NE ProdE SumE PlusE FE and elimL_rls = NEL ProdEL SumEL PlusEL FEL
text‹OMITTED: ‹eqC›are ‹TC› because they make rewriting loop: ‹p = un = un = …›\› lemmas comp_rls = NC0 NC_succ ProdC SumC PlusC_inl PlusC_inr
text‹Rules with conclusion ‹a:A›, an elem judgment.› lemmas element_rls = intr_rls elim_rls
text‹Definitions are (meta)equality axioms.› lemmas basic_defs = fst_def snd_def
text‹Compare with standard version: ‹B›is applied to UNSIMPLIFIED expression!› lemma SumIL2: "[c = a : A; d = b : B(a)]==> = : Sum(A,B)" by (rule sym_elem) (rule SumIL; rule sym_elem)
text‹ Exploit ‹p:Prod(A,B)›to create the assumption ‹z:B(a)›. A more natural form of product elimination. › lemma subst_prodE: assumes"p: Prod(A,B)" and"a: A" and"∧z. z: B(a) ==> c(z): C(z)" shows"c(p`a): C(p`a)" by (rule assms ProdE)+
subsection‹Tactics for type checking›
ML ‹ local fun is_rigid_elem 🍋‹Elem for a _›= not(is_Var (head_of a)) | is_rigid_elem 🍋‹Eqelem for a _ _›= not(is_Var (head_of a)) | is_rigid_elem 🍋‹Type for a›= not(is_Var (head_of a)) | is_rigid_elem _ = false in (*Try solving a:A or a=b:A by assumption provided a is rigid!*) fun test_assume_tac ctxt = SUBGOAL (fn (prem, i) => if is_rigid_elem (Logic.strip_assums_concl prem) then assume_tac ctxt i else no_tac)
funASSUME ctxt tf i = test_assume_tac ctxt i ORELSE tf i
end ›
text‹ For simplification: type formation and checking, but no equalities between terms. › lemmas routine_rls = form_rls formL_rls refl_type element_rls
ML ‹ fun routine_tac rls ctxt prems = ASSUME ctxt (Bires.filt_resolve_from_net_tac ctxt 4 (Bires.build_net (prems @ rls))); (*Solve all subgoals "A type" using formation rules. *)
val form_net = Bires.build_net @{thms form_rls}; fun form_tac ctxt =
REPEAT_FIRST (ASSUME ctxt (Bires.filt_resolve_from_net_tac ctxt 1 form_net));
(*Type checking: solve a:A (a rigid, A flexible) by intro and elim rules. *) fun typechk_tac ctxt thms = let val tac =
Bires.filt_resolve_from_net_tac ctxt 3
(Bires.build_net (thms @ @{thms form_rls} @ @{thms element_rls})) in REPEAT_FIRST (ASSUME ctxt tac) end
(*Solve a:A (a flexible, A rigid) by introduction rules. Cannot use stringtrees (filt_resolve_tac) since goals like ?a:SUM(A,B) have a trivial head-string *) fun intr_tac ctxt thms = let val tac =
Bires.filt_resolve_from_net_tac ctxt 1
(Bires.build_net (thms @ @{thms form_rls} @ @{thms intr_rls})) in REPEAT_FIRST (ASSUME ctxt tac) end
(*Equality proving: solve a=b:A (where a is rigid) by long rules. *) fun equal_tac ctxt thms =
REPEAT_FIRST
(ASSUME ctxt
(Bires.filt_resolve_from_net_tac ctxt 3
(Bires.build_net (thms @ @{thms form_rls element_rls intrL_rls elimL_rls refl_elem})))) ›
text‹To simplify the type in a goal.› lemma replace_type: "[B = A; a : A]==> a : B" apply (rule equal_types) apply (rule_tac [2] sym_type) apply assumption+ done
text‹Simplify the parameter of a unary type operator.› lemma subst_eqtyparg: assumes 1: "a=c : A" and 2: "∧z. z:A ==> B(z) type" shows"B(a) = B(c)" apply (rule subst_typeL) apply (rule_tac [2] refl_type) apply (rule 1) apply (erule 2) done
text‹Simplification rules for Constructive Type Theory.› lemmas reduction_rls = comp_rls [THEN trans_elem]
ML ‹ (*Converts each goal "e : Eq(A,a,b)" into "a=b:A" for simplification. Uses other intro rules to avoid changing flexible goals.*)
val eqintr_net = Bires.build_net @{thms EqI intr_rls} fun eqintr_tac ctxt =
REPEAT_FIRST (ASSUME ctxt (Bires.filt_resolve_from_net_tac ctxt 1 eqintr_net))
(** Tactics that instantiate CTT-rules. Vars in the given terms will be incremented! The (rtac EqE i) lets them apply to equality judgments. **)
fun NE_tac ctxt sp i =
TRY (resolve_tac ctxt @{thms EqE} i) THEN
Rule_Insts.res_inst_tac ctxt [((("p", 0), Position.none), sp)] [] @{thm NE} i
fun SumE_tac ctxt sp i =
TRY (resolve_tac ctxt @{thms EqE} i) THEN
Rule_Insts.res_inst_tac ctxt [((("p", 0), Position.none), sp)] [] @{thm SumE} i
fun PlusE_tac ctxt sp i =
TRY (resolve_tac ctxt @{thms EqE} i) THEN
Rule_Insts.res_inst_tac ctxt [((("p", 0), Position.none), sp)] [] @{thm PlusE} i
(** Predicate logic reasoning, WITH THINNING!! Procedures adapted from NJ. **)
(*Finds f:Prod(A,B) and a:A in the assumptions, concludes there is z:B(a) *) fun add_mp_tac ctxt i =
resolve_tac ctxt @{thms subst_prodE} i THEN assume_tac ctxt i THEN assume_tac ctxt i
(*Finds P\<longrightarrow>Q and P in the assumptions, replaces implication by Q *) fun mp_tac ctxt i = eresolve_tac ctxt @{thms subst_prodE} i THEN assume_tac ctxt i
(*"safe" when regarded as predicate calculus rules*)
val safe_brls = sort Bires.subgoals_ord
[ (true, @{thm FE}), (true,asm_rl),
(false, @{thm ProdI}), (true, @{thm SumE}), (true, @{thm PlusE}) ]
subsection‹Proofs about elementary arithmetic: addition, multiplication, etc.›
subsubsection ‹Addition›
text‹Typing of ‹add›: short and long versions.›
lemma add_typing: "[a:N; b:N]==> a #+ b : N" unfolding arith_defs by typechk
lemma add_typingL: "[a = c:N; b = d:N]==> a #+ b = c #+ d : N" unfolding arith_defs by equal
text‹Computation for ‹add›: 0 and successor cases.›
lemma addC0: "b:N ==> 0 #+ b = b : N" unfolding arith_defs by rew
lemma addC_succ: "[a:N; b:N]==> succ(a) #+ b = succ(a #+ b) : N" unfolding arith_defs by rew
subsubsection ‹Multiplication›
text‹Typing of ‹mult›: short and long versions.›
lemma mult_typing: "[a:N; b:N]==> a #* b : N" unfolding arith_defs by (typechk add_typing)
lemma mult_typingL: "[a = c:N; b = d:N]==> a #* b = c #* d : N" unfolding arith_defs by (equal add_typingL)
text‹Computation for ‹mult›: 0 and successor cases.›
lemma multC0: "b:N ==> 0 #* b = 0 : N" unfolding arith_defs by rew
lemma multC_succ: "[a:N; b:N]==> succ(a) #* b = b #+ (a #* b) : N" unfolding arith_defs by rew
subsubsection ‹Difference›
text‹Typing of difference.›
lemma diff_typing: "[a:N; b:N]==> a - b : N" unfolding arith_defs by typechk
lemma diff_typingL: "[a = c:N; b = d:N]==> a - b = c - d : N" unfolding arith_defs by equal
text‹Computation for difference: 0 and successor cases.›
lemma diffC0: "a:N ==> a - 0 = a : N" unfolding arith_defs by rew
text‹Note: ‹rec(a, 0, λz w.z)› is ‹pred(a).›\<close>
lemma diff_0_eq_0: "b:N ==> 0 - b = 0 : N" unfolding arith_defs by (NE b) hyp_rew
text‹ Essential to simplify FIRST!! (Else we get a critical pair) ‹succ(a) - succ(b)› r › lemma diff_succ_succ: "[a:N; b:N]==> succ(a) - succ(b) = a - b : N" unfolding arith_defs apply hyp_rew apply (NE b) apply hyp_rew done
text‹Associative law for addition.› lemma add_assoc: "[a:N; b:N; c:N]==> (a #+ b) #+ c = a #+ (b #+ c) : N" by (NE a) hyp_arith_rew
text‹Commutative law for addition. Can be proved using three inductions. Must simplify after first induction! Orientation of rewrites is delicate.› lemma add_commute: "[a:N; b:N]==> a #+ b = b #+ a : N" apply (NE a) apply hyp_arith_rew apply (rule sym_elem) prefer 2 apply (NE b) prefer 4 apply (NE b) apply hyp_arith_rew done
subsection‹Multiplication›
text‹Right annihilation in product.› lemma mult_0_right: "a:N ==> a #* 0 = 0 : N" apply (NE a) apply hyp_arith_rew done
text‹Right successor law for multiplication.› lemma mult_succ_right: "[a:N; b:N]==> a #* succ(b) = a #+ (a #* b) : N" apply (NE a) apply (hyp_arith_rew add_assoc [THEN sym_elem]) apply (assumption | rule add_commute mult_typingL add_typingL intrL_rls refl_elem)+ done
text‹Commutative law for multiplication.› lemma mult_commute: "[a:N; b:N]==> a #* b = b #* a : N" apply (NE a) apply (hyp_arith_rew mult_0_right mult_succ_right) done
text‹Addition distributes over multiplication.› lemma add_mult_distrib: "[a:N; b:N; c:N]==> (a #+ b) #* c = (a #* c) #+ (b #* c) : N" apply (NE a) apply (hyp_arith_rew add_assoc [THEN sym_elem]) done
text‹Associative law for multiplication.› lemma mult_assoc: "[a:N; b:N; c:N]==> (a #* b) #* c = a #* (b #* c) : N" apply (NE a) apply (hyp_arith_rew add_mult_distrib) done
subsection‹Difference›
text‹ Difference on natural numbers, without negative numbers 🪙‹a - b = 0› 🪙‹a - b = succ(c)› iff ‹a > b› ›
lemma diff_self_eq_0: "a:N ==> a - a = 0 : N" apply (NE a) apply hyp_arith_rew done
lemma add_0_right: "[c : N; 0 : N; c : N]==> c #+ 0 = c : N" by (rule addC0 [THEN [3] add_commute [THEN trans_elem]])
text‹ Addition is the inverse of subtraction: if ‹b ≤ x› t
An example of induction over a quantified formula (a product). Uses rewriting with a quantified, implicative inductive hypothesis. ›
schematic_goal add_diff_inverse_lemma: "b:N ==> ?a : ∏x:N. Eq(N, b-x, 0) ⟶ Eq(N, b #+ (x-b), x)" apply (NE b) 🍋‹strip one "universal quantifier" but not the "implication"› apply (rule_tac [3] intr_rls) 🍋‹case analysis on ‹x› in ‹succ(u) ≤ x ⟶ succ(u) #+ (x - succ(u)) = x›\<close> prefer 4 apply (NE x) apply assumption 🍋‹Prepare for simplification of types -- the antecedent ‹succ(u) ≤ x›\apply (rule_tac [2] replace_type) apply (rule_tac [1] replace_type) apply arith_rew 🍋‹Solves first 0 goal, simplifies others. Two sugbgoals remain. Both follow by rewriting, (2) using quantified induction hyp.› apply intr 🍋‹strips remaining ‹∏›s\<close> apply (hyp_arith_rew add_0_right) apply assumption done
text‹ Version of above with premise ‹b - a = 0› i Using @{thm ProdE} does not work -- for‹?B(?a)›is ambiguous.
Instead, @{thm add_diff_inverse_lemma} states the desired induction scheme;
the use of ‹THEN› below instantiates Vars in @{thm ProdE} automatically. › lemma add_diff_inverse: "[a:N; b:N; b - a = 0 : N]==> b #+ (a-b) = a : N" apply (rule EqE) apply (rule add_diff_inverse_lemma [THEN ProdE, THEN ProdE]) apply (assumption | rule EqI)+ done
subsection‹Absolute difference›
text‹Typing of absolute difference: short and long versions.›
lemma absdiff_typing: "[a:N; b:N]==> a |-| b : N" unfolding arith_defs by typechk
lemma absdiff_typingL: "[a = c:N; b = d:N]==> a |-| b = c |-| d : N" unfolding arith_defs by equal
lemma absdiff_self_eq_0: "a:N ==> a |-| a = 0 : N" unfolding absdiff_def by (arith_rew diff_self_eq_0)
lemma absdiffC0: "a:N ==> 0 |-| a = a : N" unfolding absdiff_def by hyp_arith_rew
lemma absdiff_succ_succ: "[a:N; b:N]==> succ(a) |-| succ(b) = a |-| b : N" unfolding absdiff_def by hyp_arith_rew
text‹Note how easy using commutative laws can be? ...not always...› lemma absdiff_commute: "[a:N; b:N]==> a |-| b = b |-| a : N" unfolding absdiff_def by (rule add_commute) (typechk diff_typing)
text‹Computation for quotient: 0 and successor cases.›
lemma divC0: "b:N ==> 0 div b = 0 : N" unfolding div_def by (rew mod_typing absdiff_typing)
lemma divC_succ: "[a:N; b:N]==> succ(a) div b = rec(succ(a) mod b, succ(a div b), λx y. a div b) : N" unfolding div_def by (rew mod_typing)
text‹Version of above with same condition as the ‹mod›one.› lemma divC_succ2: "[a:N; b:N]==> succ(a) div b =rec(succ(a mod b) |-| b, succ(a div b), λx y. a div b) : N" apply (rule divC_succ [THEN trans_elem]) apply (rew div_typing_rls modC_succ) apply (NE "succ (a mod b) |-|b") apply (rew mod_typing div_typing absdiff_typing) done
text‹For case analysis on whether a number is 0 or a successor.› lemma iszero_decidable: "a:N ==> rec(a, inl(eq), λka kb. inr()) : Eq(N,a,0) + (∑x:N. Eq(N,a, succ(x)))" apply (NE a) apply (rule_tac [3] PlusI_inr) apply (rule_tac [2] PlusI_inl) apply eqintr apply equal done
text‹Main Result. Holds when ‹b›is 0 since ‹a mod 0 = a› and ‹a div 0 = 0›.› lemma mod_div_equality: "[a:N; b:N]==> a mod b #+ (a div b) #* b = a : N" apply (NE a) apply (arith_rew div_typing_rls modC0 modC_succ divC0 divC_succ2) apply (rule EqE) 🍋‹case analysis on ‹succ(u mod b) |-| b›\› apply (rule_tac a1 = "succ (u mod b) |-| b"in iszero_decidable [THEN PlusE]) apply (erule_tac [3] SumE) apply (hyp_arith_rew div_typing_rls modC0 modC_succ divC0 divC_succ2) 🍋‹Replace one occurrence of ‹b›by ‹succ(u mod b)›. Clumsy!› apply (rule add_typingL [THEN trans_elem]) apply (erule EqE [THEN absdiff_eq0, THEN sym_elem]) apply (rule_tac [3] refl_elem) apply (hyp_arith_rew div_typing_rls) done
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-04-29)
¤
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.