Voici un langage très simple:Comment prouver que l'ajout d'une nouvelle variable à l'expression ne change pas sa sémantique?
type_synonym vname = "string"
type_synonym bool3 = "bool option"
type_synonym env = "vname ⇒ bool3"
datatype exp = Let vname bool exp | Var vname | And exp exp
primrec val :: "exp ⇒ env ⇒ bool3" where
"val (Let var init body) e = val body (e(var ↦ init))"
| "val (Var var) e = e var"
| "val (And a b) e = (case (val a e, val b e) of
(Some x, Some y) ⇒ Some (x ∧ y) | _ ⇒ None)"
Je suis en train de prouver que si l'expression n'a pas de variables libres, je peux déclarer toute nouvelle variable au début de l'expression. J'ai essayé 3 approches pour le prouver.
1) defined
fonction vérifie si la valeur de l'expression est bien définie (= toutes les variables utilisées sont déclarées):
primrec defined :: "exp ⇒ env ⇒ bool" where
"defined (Let var init body) e = defined body (e(var ↦ init))"
| "defined (Var var) e = (var : dom e)"
| "defined (And a b) e = (defined a e ∧ defined b e)"
lemma var_intro: "defined exp env ⟹ defined exp (env(x ↦ init))"
apply (induct exp)
apply (simp_all split: if_splits)
2) L'approche alternative est de collecter toutes les variables libres de l'expression. Et si l'expression ne contient pas alors nous pouvons ajouter une nouvelle variable à l'environnement:
primrec freeVars :: "exp ⇒ vname set ⇒ vname set" where
"freeVars (Let var init body) e = freeVars body (insert var e)"
| "freeVars (Var var) e = (if var ∈ e then {} else {var})"
| "freeVars (And a b) e = freeVars a e ∪ freeVars b e"
lemma var_intro2: "freeVars exp {} = {} ⟹ freeVars exp {x} = {}"
apply (induct exp)
apply (simp_all split: if_splits)
3) Et la dernière approche est d'éliminer toutes les variables bornées de l'environnement:
primrec isFree :: "vname ⇒ exp ⇒ bool" where
"isFree x (Let var init body) = (if var = x then False else isFree x body)"
| "isFree x (Var var) = (var = x)"
| "isFree x (And a b) = (isFree x a ∨ isFree x b)"
lemma var_elim: "¬ isFree x exp ⟹ val exp (env(x ↦ init)) = val exp (env)"
apply (induct exp)
apply (simp_all split: if_splits)
Je ne peux prouver aucun des lemmes. Pourriez-vous suggérer une solution?