Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/HOL/Nominal/Examples/   (Beweissystem Isabelle Version 2025-1©)  Datei vom 16.11.2025 mit Größe 24 kB image not shown  

Quelle  SOS.thy

  Sprache: Isabelle
 

(*                                                        *)
(* Formalisation of some typical SOS-proofs.              *)
(*                                                        *) 
(* This work was inspired by challenge suggested by Adam  *)
(* Chlipala on the POPLmark mailing list.                 *)
(*                                                        *) 
(* We thank Nick Benton for helping us with the           *) 
(* termination-proof for evaluation.                      *)
(*                                                        *)
(* The formalisation was done by Julien Narboux and       *)
(* Christian Urban.                                       *)

theory SOS
  imports "HOL-Nominal.Nominal"
begin

atom_decl name

text types and terms
nominal_datatype ty = 
    TVar "nat"
  | Arrow "ty" "ty" (__ [100,100] 100)

nominal_datatype trm = 
    Var "name"
  | Lam "«name¬trm" (Lam [_]._ [100,100] 100)
  | App "trm" "trm"

lemma fresh_ty:
  fixes x::"name" 
  and   T::"ty"
  shows "xT"
by (induct T rule: ty.induct)
   (auto simp add: fresh_nat)

text Parallel and single substitution.
fun
  lookup :: "(name×trm) list ==> name ==> trm"   
where
  "lookup [] x = Var x"
"lookup ((y,e)#θ) x = (if x=y then e else lookup θ x)"

lemma lookup_eqvt[eqvt]:
  fixes pi::"name prm"
  shows "pi(lookup θ X) = lookup (piθ) (piX)"
by (induct θ) (auto simp add: eqvts)

lemma lookup_fresh:
  fixes z::"name"
  assumes a: "zθ" and b: "zx"
  shows "z lookup θ x"
using a b
by (induct rule: lookup.induct) (auto simp add: fresh_list_cons)

lemma lookup_fresh':
  assumes "zθ"
  shows "lookup θ z = Var z"
using assms 
by (induct rule: lookup.induct)
   (auto simp add: fresh_list_cons fresh_prod fresh_atm)

(* parallel substitution *)

nominal_primrec
  psubst :: "(name×trm) list ==> trm ==> trm"  (_🪙 [95,95] 105)
where
  "θ<(Var x)> = (lookup θ x)"
"θ<(App e🪙1 e🪙2)> = App (θ🪙1>) (θ🪙2>)"
"xθ ==> θ<(Lam [x].e)> = Lam [x].(θ)"
  by (finite_guess | simp add: abs_fresh | fresh_guess)+

lemma psubst_eqvt[eqvt]:
  fixes pi::"name prm" 
  and   t::"trm"
  shows "pi) = (piθ)<(pit)>"
by (nominal_induct t avoiding: θ rule: trm.strong_induct)
   (perm_simp add: fresh_bij lookup_eqvt)+

lemma fresh_psubst: 
  fixes z::"name"
  and   t::"trm"
  assumes "zt" and "zθ"
  shows "z)"
using assms
by (nominal_induct t avoiding: z θ t rule: trm.strong_induct)
   (auto simp add: abs_fresh lookup_fresh)

lemma psubst_empty[simp]:
  shows "[] = t"
  by (nominal_induct t rule: trm.strong_induct) 
     (auto simp add: fresh_list_nil)

text Single substitution
abbreviation 
  subst :: "trm ==> name ==> trm ==> trm" (_[_::=_] [100,100,100] 100)
where 
  "t[x::=t'] ([(x,t')])" 

lemma subst[simp]:
  shows "(Var x)[y::=t'] = (if x=y then t' else (Var x))"
  and   "(App t🪙1 t🪙2)[y::=t'] = App (t🪙1[y::=t']) (t🪙2[y::=t'])"
  and   "x(y,t') ==> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])"
by (simp_all add: fresh_list_cons fresh_list_nil)

lemma fresh_subst:
  fixes z::"name"
  shows "[zs; (z=y zt)] ==> zt[y::=s]"
by (nominal_induct t avoiding: z y s rule: trm.strong_induct)
   (auto simp add: abs_fresh fresh_prod fresh_atm)

lemma forget: 
  assumes a: "xe" 
  shows "e[x::=e'] = e"
using a
by (nominal_induct e avoiding: x e' rule: trm.strong_induct)
   (auto simp add: fresh_atm abs_fresh)

lemma psubst_subst_psubst:
  assumes h: "xθ"
  shows [x::=e'] = ((x,e')#θ)"
  using h
by (nominal_induct e avoiding: θ x e' rule: trm.strong_induct)
   (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh')

text Typing Judgements

inductive
  valid :: "(name×ty) list ==> bool"
where
  v_nil[intro]:  "valid []"
| v_cons[intro]: "[valid Γ;xΓ] ==> valid ((x,T)#Γ)"

equivariance valid 

inductive_cases
  valid_elim[elim]: "valid ((x,T)#Γ)"

lemma valid_insert:
  assumes a: "valid (Δ@[(x,T)]@Γ)"
  shows "valid (Δ @ Γ)" 
using a
by (induct Δ)
   (auto simp add:  fresh_list_append fresh_list_cons elim!: valid_elim)

lemma fresh_set: 
  shows "yxs = (xset xs. yx)"
by (induct xs) (simp_all add: fresh_list_nil fresh_list_cons)

lemma context_unique:
  assumes a1: "valid Γ"
  and     a2: "(x,T) set Γ"
  and     a3: "(x,U) set Γ"
  shows "T = U" 
using a1 a2 a3
by (induct) (auto simp add: fresh_set fresh_prod fresh_atm)

text Typing Relation

inductive
  typing :: "(name×ty) list==>trm==>ty==>bool" (_ _ : _ [60,60,60] 60) 
where
  t_Var[intro]:   "[valid Γ; (x,T)set Γ] ==> Γ Var x : T"
| t_App[intro]:   "[Γ e🪙1 : T🪙1T🪙2; Γ e🪙2 : T🪙1] ==> Γ App e🪙1 e🪙2 : T🪙2"
| t_Lam[intro]:   "[xΓ; (x,T🪙1)#Γ e : T🪙2] ==> Γ Lam [x].e : T🪙1T🪙2"

equivariance typing

nominal_inductive typing
  by (simp_all add: abs_fresh fresh_ty)

lemma typing_implies_valid:
  assumes a:  t : T"
  shows "valid Γ"
using a by (induct) (auto)


lemma t_App_elim:
  assumes a:  App t1 t2 : T"
  obtains T' where  t1 : T' T" and  t2 : T'"
using a
by (cases) (auto simp add: trm.inject)

lemma t_Lam_elim: 
  assumes a:  Lam [x].t : T" "xΓ"
  obtains T🪙and T🪙where "(x,T🪙1)#Γ t : T🪙2" and "T=T🪙1T🪙2"
using a
by (cases rule: typing.strong_cases [where x="x"])
   (auto simp add: abs_fresh fresh_ty alpha trm.inject)

abbreviation
  "sub_context" :: "(name×ty) list ==> (name×ty) list ==> bool" (_ _ [55,55] 55)
where
  🪙1 Γ🪙2 x T. (x,T)set Γ🪙1 (x,T)set Γ🪙2"

lemma weakening: 
  fixes Γ🪙1 Γ🪙2::"(name×ty) list"
  assumes 🪙1 e: T" and "valid Γ🪙2" and 🪙1 Γ🪙2"
  shows 🪙2 e: T"
  using assms
proof(nominal_induct Γ🪙1 e T avoiding: Γ🪙2 rule: typing.strong_induct)
  case (t_Lam x Γ🪙1 T🪙1 t T🪙2 Γ🪙2)
  have vc: "xΓ🪙2" by fact
  have ih: "[valid ((x,T🪙1)#Γ🪙2); (x,T🪙1)#Γ🪙1 (x,T🪙1)#Γ🪙2] ==> (x,T🪙1)#Γ🪙2 t : T🪙2" by fact
  have "valid Γ🪙2" by fact
  then have "valid ((x,T🪙1)#Γ🪙2)" using vc by auto
  moreover
  have 🪙1 Γ🪙2" by fact
  then have "(x,T🪙1)#Γ🪙1 (x,T🪙1)#Γ🪙2" by simp
  ultimately have "(x,T🪙1)#Γ🪙2 t : T🪙2" using ih by simp 
  with vc show 🪙2 Lam [x].t : T🪙1T🪙2" by auto
qed (auto)

lemma type_substitutivity_aux:
  assumes a: "(Δ@[(x,T')]@Γ) e : T"
  and     b:  e' : T'"
  shows "(Δ@Γ) e[x::=e'] : T" 
using a b 
proof (nominal_induct Γ"Δ@[(x,T')]@Γ" e T avoiding: e' Δ rule: typing.strong_induct)
  case (t_Var y T e' Δ)
  then have a1: "valid (Δ@[(x,T')]@Γ)" 
       and  a2: "(y,T) set (Δ@[(x,T')]@Γ)" 
       and  a3:  e' : T'" .
  from a1 have a4: "valid (Δ@Γ)" by (rule valid_insert)
  { assume eq: "x=y"
    from a1 a2 have "T=T'" using eq by (auto intro: context_unique)
    with a3 have "Δ@Γ Var y[x::=e'] : T" using eq a4 by (auto intro: weakening)
  }
  moreover
  { assume ineq: "xy"
    from a2 have "(y,T) set (Δ@Γ)" using ineq by simp
    then have "Δ@Γ Var y[x::=e'] : T" using ineq a4 by auto
  }
  ultimately show "Δ@Γ Var y[x::=e'] : T" by blast
qed (force simp add: fresh_list_append fresh_list_cons)+

corollary type_substitutivity:
  assumes a: "(x,T')#Γ e : T"
  and     b:  e' : T'"
  shows  e[x::=e'] : T"
using a b type_substitutivity_aux[where Δ="[]"]
by (auto)

text Values
inductive
  val :: "trm==>bool" 
where
  v_Lam[intro]:   "val (Lam [x].e)"

equivariance val 

lemma not_val_App[simp]:
  shows 
  "¬ val (App e🪙1 e🪙2)" 
  "¬ val (Var x)"
  by (auto elim: val.cases)

text Big-Step Evaluation

inductive
  big :: "trm==>trm==>bool" (_ _ [80,80] 80) 
where
  b_Lam[intro]:   "Lam [x].e Lam [x].e"
| b_App[intro]:   "[x(e🪙1,e🪙2,e'); e🪙1Lam [x].e; e🪙2e🪙2'; e[x::=e🪙2']e'] ==> App e🪙1 e🪙2 e'"

equivariance big

nominal_inductive big
  by (simp_all add: abs_fresh)

lemma big_preserves_fresh:
  fixes x::"name"
  assumes a: "e e'" "xe" 
  shows "xe'"
  using a by (induct) (auto simp add: abs_fresh fresh_subst)

lemma b_App_elim:
  assumes a: "App e🪙1 e🪙2 e'" "x(e🪙1,e🪙2,e')"
  obtains f🪙and f🪙where "e🪙1 Lam [x]. f🪙1" "e🪙2 f🪙2" "f🪙1[x::=f🪙2] e'"
  using a
by (cases rule: big.strong_cases[where x="x" and xa="x"])
   (auto simp add: trm.inject)

lemma subject_reduction:
  assumes a: "e e'" and b:  e : T"
  shows  e' : T"
  using a b
proof (nominal_induct avoiding: Γ arbitrary: T rule: big.strong_induct) 
  case (b_App x e🪙1 e🪙2 e' e e🪙2' Γ T)
  have vc: "xΓ" by fact
  have  App e🪙1 e🪙2 : T" by fact
  then obtain T' where a1:  e🪙1 : T'T" and a2:  e🪙2 : T'" 
    by (cases) (auto simp add: trm.inject)
  have ih1:  e🪙1 : T' T ==> Γ Lam [x].e : T' T" by fact
  have ih2:  e🪙2 : T' ==> Γ e🪙2' : T'" by fact 
  have ih3:  e[x::=e🪙2'] : T ==> Γ e' : T" by fact
  have  Lam [x].e : T'T" using ih1 a1 by simp 
  then have "((x,T')#Γ) e : T" using vc  
    by (auto elim: t_Lam_elim simp add: ty.inject)
  moreover
  have  e🪙2': T'" using ih2 a2 by simp
  ultimately have  e[x::=e🪙2'] : T" by (simp add: type_substitutivity)
  thus  e' : T" using ih3 by simp
qed (blast)

lemma subject_reduction2:
  assumes a: "e e'" and b:  e : T"
  shows  e' : T"
  using a b
by (nominal_induct avoiding: Γ T rule: big.strong_induct)
   (force elim: t_App_elim t_Lam_elim simp add: ty.inject type_substitutivity)+

lemma unicity_of_evaluation:
  assumes a: "e e🪙1" 
  and     b: "e e🪙2"
  shows "e🪙1 = e🪙2"
  using a b
proof (nominal_induct e e🪙1 avoiding: e🪙2 rule: big.strong_induct)
  case (b_Lam x e t🪙2)
  have "Lam [x].e t🪙2" by fact
  thus "Lam [x].e = t🪙2" by cases (simp_all add: trm.inject)
next
  case (b_App x e🪙1 e🪙2 e' e🪙1' e🪙2' t🪙2)
  have ih1: "t. e🪙1 t ==> Lam [x].e🪙1' = t" by fact
  have ih2:"t. e🪙2 t ==> e🪙2' = t" by fact
  have ih3: "t. e🪙1'[x::=e🪙2'] t ==> e' = t" by fact
  have app: "App e🪙1 e🪙2 t🪙2" by fact
  have vc: "xe🪙1" "xe🪙2" "xt🪙2" by fact+
  then have "xApp e🪙1 e🪙2" by auto
  from app vc obtain f🪙1 f🪙where x1: "e🪙1 Lam [x]. f🪙1" and x2: "e🪙2 f🪙2" and x3: "f🪙1[x::=f🪙2] t🪙2"
    by (auto elim!: b_App_elim)
  then have "Lam [x]. f🪙1 = Lam [x]. e🪙1'" using ih1 by simp
  then 
  have "f🪙1 = e🪙1'" by (auto simp add: trm.inject alpha) 
  moreover 
  have "f🪙2 = e🪙2'" using x2 ih2 by simp
  ultimately have "e🪙1'[x::=e🪙2'] t🪙2" using x3 by simp
  thus "e' = t🪙2" using ih3 by simp
qed

lemma reduces_evaluates_to_values:
  assumes h: "t t'"
  shows "val t'"
using h by (induct) (auto)

(* Valuation *)

nominal_primrec
  V :: "ty ==> trm set" 
where
  "V (TVar x) = {e. val e}"
"V (T🪙1 T🪙2) = {Lam [x].e | x e. v (V T🪙1). v'. e[x::=v] v' v' V T🪙2}"
  by (rule TrueI)+ 

lemma V_eqvt:
  fixes pi::"name prm"
  assumes "x V T"
  shows "(pix) V T"
using assms
proof (nominal_induct T arbitrary: pi x rule: ty.strong_induct)
  case (TVar nat)
  then show ?case
    by (simp add: val.eqvt)
next
  case (Arrow T🪙1 T🪙2 pi x)
  obtain a e where ae: "x = Lam [a]. e" "vV T🪙1. v'. e[a::=v] v' v' V T🪙2"
    using Arrow.prems by auto
  have "v'. (pi e)[(pi a)::=v] v' v' V T🪙2" if v: "v V T🪙1" for v
  proof -
    have "rev pi v V T🪙1"
      by (simp add: Arrow.hyps(1) v)
    then obtain v' where "e[a::=(rev pi v)] v'" "v' V T🪙2"
      using ae(2) by blast
    then have "(pi e)[(pi a)::=v] pi v'"
      by (metis (no_types, lifting) big.eqvt cons_eqvt nil_eqvt perm_pi_simp(1) perm_prod.simps psubst_eqvt)
    then show ?thesis
      using Arrow.hyps v' V T🪙2 by blast
  qed
  with ae show ?case by force
qed

lemma V_arrow_elim_weak:
  assumes h:"u V (T🪙1 T🪙2)"
  obtains a t where "u = Lam [a].t" and " v (V T🪙1). v'. t[a::=v] v' v' V T🪙2"
using h by (auto)

lemma V_arrow_elim_strong:
  fixes c::"'a::fs_name"
  assumes h: "u V (T🪙1 T🪙2)"
  obtains a t where "ac" "u = Lam [a].t" "v (V T🪙1). v'. t[a::=v] v' v' V T??2"
proof -
  obtain a t where "u = Lam [a].t" 
    and at: "v. v (V T🪙1) ==> v'. t[a::=v] v' v' V T🪙2"
    using V_arrow_elim_weak [OF assms] by metis
  obtain a'::name where a': "a'(a,t,c)"
    by (meson exists_fresh fs_name_class.axioms)
  then have "u = Lam [a'].([(a, a')] t)"
    unfolding u = Lam [a].t
    by (smt (verit) alpha fresh_atm fresh_prod perm_swap trm.inject(2))
  moreover
  have " v'. ([(a, a')] t)[a'::=v] v' v' V T🪙2" if "v (V T🪙1)" for v
  proof -
    obtain v' where v': "t[a::=([(a, a')] v)] v' v' V T🪙2"
      using V_eqvt v V T🪙1 at by blast
    then have "([(a, a')] t[a::=([(a, a')] v)]) [(a, a')] v'"
      by (simp add: big.eqvt)
    then show ?thesis
      by (smt (verit) V_eqvt cons_eqvt nil_eqvt perm_prod.simps perm_swap(1) psubst_eqvt swap_simps(1) v')
  qed
  ultimately show thesis
    by (metis fresh_prod that a')
qed

lemma Vs_are_values:
  assumes a: "e V T"
  shows "val e"
using a by (nominal_induct T arbitrary: e rule: ty.strong_induct) (auto)

lemma values_reduce_to_themselves:
  assumes a: "val v"
  shows "v v"
using a by (induct) (auto)

lemma Vs_reduce_to_themselves:
  assumes a: "v V T"
  shows "v v"
using a by (simp add: values_reduce_to_themselves Vs_are_values)

text 'θ maps x to e' asserts that θ substitutes x with e
abbreviation 
  mapsto :: "(name×trm) list ==> name ==> trm ==> bool" (_ maps _ to _ [55,55,55] 55
where
 "θ maps x to e (lookup θ x) = e"

abbreviation 
  v_closes :: "(name×trm) list ==> (name×ty) list ==> bool" (_ Vcloses _ [55,55] 55) 
where
  "θ Vcloses Γ x T. (x,T) set Γ (v. θ maps x to v v V T)"

lemma case_distinction_on_context:
  fixes Γ::"(name×ty) list"
  assumes asm1: "valid ((m,t)#Γ)" 
  and     asm2: "(n,U) set ((m,T)#Γ)"
  shows "(n,U) = (m,T) ((n,U) set Γ n m)"
proof -
  from asm2 have "(n,U) set [(m,T)] (n,U) set Γ" by auto
  moreover
  { assume eq: "m=n"
    assume "(n,U) set Γ" 
    then have "¬ nΓ" 
      by (induct Γ) (auto simp add: fresh_list_cons fresh_prod fresh_atm)
    moreover have "mΓ" using asm1 by auto
    ultimately have False using eq by auto
  }
  ultimately show ?thesis by auto
qed

lemma monotonicity:
  fixes m::"name"
  fixes θ::"(name × trm) list" 
  assumes h1: "θ Vcloses Γ"
  and     h2: "e V T" 
  and     h3: "valid ((x,T)#Γ)"
  shows "(x,e)#θ Vcloses (x,T)#Γ"
proof(intro strip)
  fix x' T'
  assume "(x',T') set ((x,T)#Γ)"
  then have "((x',T')=(x,T)) ((x',T')set Γ x'x)" using h3 
    by (rule_tac case_distinction_on_context)
  moreover
  { (* first case *)
    assume "(x',T') = (x,T)"
    then have "e'. ((x,e)#θ) maps x to e' e' V T'" using h2 by auto
  }
  moreover
  { (* second case *)
    assume "(x',T') set Γ" and neq:"x' x"
      then have "e'. θ maps x' to e' e' V T'" using h1 by auto
      then have "e'. ((x,e)#θ) maps x' to e' e' V T'" using neq by auto
  }
  ultimately show "e'. ((x,e)#θ) maps x' to e' e' V T'" by blast
qed

lemma termination_aux:
  assumes h1:  e : T"
  and     h2: "θ Vcloses Γ"
  shows "v. θ v v V T" 
using h2 h1
proof(nominal_induct e avoiding: Γ θ arbitrary: T rule: trm.strong_induct)
  case (App e🪙1 e🪙2 Γ θ T)
  have ih🪙1: "θ Γ T. [θ Vcloses Γ; Γ e🪙1 : T] ==> v. θ🪙1> v v V T" by fact
  have ih🪙2: "θ Γ T. [θ Vcloses Γ; Γ e🪙2 : T] ==> v. θ🪙2> v v V T" by fact
  have as🪙1: "θ Vcloses Γ" by fact 
  have as🪙2:  App e🪙1 e🪙2 : T" by fact
  then obtain T' where  e🪙1 : T' T" and  e🪙2 : T'" by (auto elim: t_App_elim)
  then obtain v🪙1 v🪙where "(i)"🪙1> v🪙1" "v🪙1 V (T' T)"
                      and "(ii)"🪙2> v🪙2" "v🪙2 V T'" using ih🪙1 ih🪙2 as🪙by blast
  from "(i)" obtain x e' 
            where "v🪙1 = Lam [x].e'" 
            and "(iii)""(v (V T'). v'. e'[x::=v] v' v' V T)"
            and "(iv)":  🪙1> Lam [x].e'" 
            and fr: "x(θ,e🪙1,e🪙2)" by (blast elim: V_arrow_elim_strong)
  from fr have fr🪙1: "xθ🪙1>" and fr🪙2: "xθ🪙2>" by (simp_all add: fresh_psubst)
  from "(ii)" "(iii)" obtain v🪙where "(v)""e'[x::=v🪙2] v🪙3" "v🪙3 V T" by auto
  from fr🪙"(ii)" have "xv🪙2" by (simp add: big_preserves_fresh)
  then have "xe'[x::=v🪙2]" by (simp add: fresh_subst)
  then have fr🪙3: "xv🪙3" using "(v)" by (simp add: big_preserves_fresh)
  from fr🪙1 fr🪙2 fr🪙have "x🪙1>,θ🪙2>,v🪙3)" by simp
  with "(iv)" "(ii)" "(v)" have "App (θ🪙1>) (θ🪙2>) v🪙3" by auto
  then show "v. θ🪙1 e🪙2> v v V T" using "(v)" by auto
next
  case (Lam x e Γ θ T)
  have ih:"θ Γ T. [θ Vcloses Γ; Γ e : T] ==> v. θ v v V T" by fact
  have as🪙1: "θ Vcloses Γ" by fact
  have as🪙2:  Lam [x].e : T" by fact
  have fs: "xΓ" "xθ" by fact+
  from as🪙2 fs obtain T🪙1 T🪙
    where "(i)""(x,T🪙1)#Γ e:T🪙2" and "(ii)""T = T🪙1 T🪙2" using fs
    by (auto elim: t_Lam_elim)
  from "(i)" have "(iii)""valid ((x,T🪙1)#Γ)" by (simp add: typing_implies_valid)
  have "v (V T🪙1). v'. (θ)[x::=v] v' v' V T🪙2"
  proof
    fix v
    assume "v (V T🪙1)"
    with "(iii)" as🪙have "(x,v)#θ Vcloses (x,T🪙1)#Γ" using monotonicity by auto
    with ih "(i)" obtain v' where "((x,v)#θ) v' v' V T🪙2" by blast
    then have [x::=v] v' v' V T🪙2" using fs by (simp add: psubst_subst_psubst)
    then show "v'. θ[x::=v] v' v' V T🪙2" by auto
  qed
  then have "Lam[x].θ V (T🪙1 T🪙2)" by auto
  then have  Lam [x].θ Lam [x].θ V (T🪙1T🪙2)" using fs by auto
  thus "v. θ v v V T" using "(ii)" by auto
next
  case (Var x Γ θ T)
  have  (Var x) : T" by fact
  then have "(x,T)set Γ" by (cases) (auto simp add: trm.inject)
  with Var have  θ θ V T" 
    by (auto intro!: Vs_reduce_to_themselves)
  then show "v. θ v v V T" by auto
qed 

theorem termination_of_evaluation:
  assumes a: "[] e : T"
  shows "v. e v val v"
proof -
  from a have "v. [] v v V T" by (rule termination_aux) (auto)
  thus "v. e v val v" using Vs_are_values by auto
qed 

end

Messung V0.5 in Prozent
C=91 H=69 G=80

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet am  2026-05-03) ¤

*© Formatika GbR, Deutschland






Versionsinformation zu Columbo

Bemerkung:

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Anfrage:

Dauer der Verarbeitung:

Sekunden

sprechenden Kalenders