Hier ist ganz einfach die Sprache aus:Wie zu beweisen, dass die Hinzufügung einer neuen Variablen zu dem Ausdruck seine Semantik nicht ändert?
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)"
Ich versuche zu beweisen, dass, wenn ein Ausdruck keine freien Variablen nicht hat, dann kann ich am Anfang des Ausdrucks jede neue Variable deklariert. Ich habe 3 Ansätze ausprobiert, um es zu beweisen.
1) defined
Funktion überprüft, ob der Wert des Ausdrucks gut definiert ist (= alle verwendeten Variablen deklariert):
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) Der alternative Ansatz ist es, alle freien Variablen aus dem Ausdruck zu sammeln. Und wenn der Ausdruck enthält keine, dann können wir eine neue Variable in die Umwelt hinzuzufügen:
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) und den letzten Ansatz ist es, alle beschränkten Variablen aus der Umgebung zu beseitigen:
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)
Ich kann keines der Lemmas beweisen. Könnten Sie eine Lösung vorschlagen?