isabelle


How to prove that addition of a new variable to the expression doesn't change its semantics?


Here is very simple language:
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)"
I'm trying to prove that if an expression doesn't have any free variables, then I can declare any new variable at the begining of the expression. I've tried 3 approaches to prove it.
1) defined function checks whether the expression's value is well defined (= all used variables are declared):
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) The alternative approach is to collect all free variables from the expression. And if the expression doesn't contain any then we can add a new variable to the environment:
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) And the last approach is to eliminate all bounded variables from the environment:
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)
I can't prove any of the lemmas. Could you suggest a solution?
Your proofs will probably require you to set env to arbitrary in the induction or the proofs will not work. With that, you will probably be able to prove the properties you stated, but I think it'll be a bit ugly because both your definitions and your lemma statements are unnecessarily specific, which can make proofs more painful.
In particular, your notion of ‘free variable w.r.t. an environment’ seems a bit unnecessarily complicated to me. I think it's easier to use the following:
primrec freeVars :: "exp ⇒ vname set" where
"freeVars (Let var init body) = freeVars body - {var}"
| "freeVars (Var var) = {var}"
| "freeVars (And a b) = freeVars a ∪ freeVars b"
The statement ‘expression exp is well-defined w.r.t. an environment env’ is then simply freeVars exp ⊆ dom env.
Then it is obvious that any expression that is well-defined w.r.t. some environment is also well-defined with any bigger environment.
1) You have to lift the communicative property of element insertion on sets into that of state updates on maps, on which your lemma is based.
lemma defined_dom: "defined exp env ⟹ dom env = dom env' ⟹ defined exp env'"
by (induction exp arbitrary: env env'; auto)
lemma defined_comm: "defined exp (env(x↦a, y↦b)) ⟹ defined exp (env(y↦b, x↦a))"
by (auto elim!: defined_dom)
lemma var_intro: "defined exp env ⟹ defined exp (env(x ↦ init))"
by (induction exp arbitrary: env; simp add: defined_comm)
2) If your lemma is based on sets, you will also need the communicative lemma, which is already in the library:
lemma var_intro2': "freeVars exp s = {} ⟹ freeVars exp (insert x s) = {}"
by (induction exp arbitrary: s x; force simp: insert_commute)
lemma var_intro2: "freeVars exp {} = {} ⟹ freeVars exp {x} = {}"
using var_intro2' .
3) Similarly:
lemma var_elim: "¬ isFree x exp ⟹ val exp (env(x ↦ init)) = val exp (env)"
by (induction exp arbitrary: env; simp add: fun_upd_twist split: if_splits)

Related Links

Defining functions between constants in Isabelle
Using the ordering locale with partial maps
Avoiding assumption with sledgehammer
Discriminant with Inequalities
Instances in locale declaration for Isabelle
How to interactively simplify a formula in a relational theory in Isabelle
Nonnegative Interval Integration
Widening the domain of a partial function
Automatically unfolding a record definition when accessor is used
Creating a datatype with inequalities in Isabelle
Isabelle Logic simple natural deduction test
Instantiating variables ending in a digit using where-attribute (Isabelle)
Using an existing definition in Isabelle/ Hol
Pending sort hypotheses
How can I use proved goals of locale interpretation to prove the remaining ones
Isabelle class obligation prove blue

Categories

HOME
ms-access
ionic-framework
client
bluetooth
vbscript
cookies
zeromq
server
onedrive
raspberry-pi
spagobi
read-eval-print-loop
youtube-dl
q
razor
malloc
icloud
ojdbc
yum
upload
dax
export-to-csv
google-apps-marketplace
vb.net-2010
msp430
uitypeeditor
invantive-sql
oxyplot
beyondcompare
google-pagespeed
jprofiler
google-search-api
one-to-many
javacv
entitlements
ping
ejabberd-module
galsim
google-qpx-express-api
usbserial
hexo
disassembling
libraries
hp-ux
sfdc
smartcontracts
hendrix
dropbox-php
togetherjs
media-player
lync-client-sdk
cubes
wdf
deadbolt-2
android-fonts
log4c
url-masking
multiple-regression
holder.js
pagedlist
packagist
pickadate
yaws
kendonumerictextbox
srand
separator
msys
cannon.js
citrus-pay
kcachegrind
census
pretty-print
npapi
tt-news
id3v2
sgen
wp-query
xceed-datagrid
seaside
jboss-weld
cloud-connect
industrial
ivyde
web2py-modules
gridcontrol
robotics-studio
dsn
custom-backend
invite
yetanotherforum
remember-me
dmx512
audio-capture
data-acquisition
wsdl.exe
uiq3

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App