You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
6.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
(* Properties of the llair model *)
open HolKernel boolLib bossLib Parse;
open arithmeticTheory integerTheory integer_wordTheory wordsTheory listTheory;
open pred_setTheory finite_mapTheory;
open settingsTheory miscTheory llairTheory;
new_theory "llair_prop";
numLib.prefer_num ();
Theorem ifits_w2i:
∀(w : 'a word). ifits (w2i w) (dimindex (:'a))
Proof
rw [ifits_def, GSYM INT_MIN_def] >>
metis_tac [INT_MIN, w2i_ge, integer_wordTheory.INT_MAX_def, w2i_le,
intLib.COOPER_PROVE ``!(x:int) y. x y - 1 x < y``]
QED
Theorem truncate_2comp_fits:
∀i size. 0 < size ifits (truncate_2comp i size) size
Proof
rw [truncate_2comp_def, ifits_def] >>
qmatch_goalsub_abbrev_tac `(i + s1) % s2` >>
`s2 0 ¬(s2 < 0)` by rw [Abbr `s2`]
>- (
`0 (i + s1) % s2` suffices_by intLib.COOPER_TAC >>
drule INT_MOD_BOUNDS >>
rw [])
>- (
`(i + s1) % s2 < 2 * s1` suffices_by intLib.COOPER_TAC >>
`2 * s1 = s2` by rw [Abbr `s1`, Abbr `s2`, GSYM EXP] >>
drule INT_MOD_BOUNDS >>
rw [Abbr `s1`, Abbr `s2`])
QED
Theorem fits_ident:
∀i size. 0 < size (ifits i size truncate_2comp i size = i)
Proof
rw [ifits_def, truncate_2comp_def] >>
rw [intLib.COOPER_PROVE ``!(x:int) y z. x - y = z <=> x = y + z``] >>
qmatch_goalsub_abbrev_tac `(_ + s1) % s2` >>
`s2 0 ¬(s2 < 0)` by rw [Abbr `s2`] >>
`2 * s1 = s2` by rw [Abbr `s1`, Abbr `s2`, GSYM EXP] >>
eq_tac >>
rw []
>- (
simp [Once INT_ADD_COMM] >>
irule INT_LESS_MOD >>
rw [] >>
intLib.COOPER_TAC)
>- (
`0 (i + s1) % (2 * s1)` suffices_by intLib.COOPER_TAC >>
drule INT_MOD_BOUNDS >>
simp [])
>- (
`(i + s1) % (2 * s1) < 2 * s1` suffices_by intLib.COOPER_TAC >>
drule INT_MOD_BOUNDS >>
simp [])
QED
Theorem i2n_n2i:
!n size. 0 < size (nfits n size (i2n (n2i n size) = n))
Proof
rw [nfits_def, n2i_def, i2n_def] >> rw []
>- intLib.COOPER_TAC
>- (
`2 ** size n` by intLib.COOPER_TAC >> simp [INT_SUB] >>
Cases_on `n = 0` >> fs [] >>
`n - 2 ** size < n` suffices_by intLib.COOPER_TAC >>
irule SUB_LESS >> simp [])
>- (
`2 ** (size - 1) < 2 ** size` suffices_by intLib.COOPER_TAC >>
fs [])
QED
Theorem n2i_i2n:
!i size. 0 < size (ifits i size (n2i (i2n (IntV i size)) size) = IntV i size)
Proof
rw [ifits_def, n2i_def, i2n_def] >> rw [] >> fs []
>- (
eq_tac >> rw []
>- (
simp [intLib.COOPER_PROVE ``∀(x:int) y z. x - y = z x = y + z``] >>
`2 ** (size - 1) < 2 ** size` suffices_by intLib.COOPER_TAC >>
fs [INT_OF_NUM])
>- (
fs [intLib.COOPER_PROVE ``∀(x:int) y z. x - y = z x = y + z``] >>
fs [INT_OF_NUM] >>
`?j. i = -j` by intLib.COOPER_TAC >> rw [] >> fs [] >>
qpat_x_assum `_ Num _` mp_tac >>
fs [GSYM INT_OF_NUM] >>
ASM_REWRITE_TAC [GSYM INT_LE] >> rw [] >>
`2 ** size = 2 * 2 ** (size - 1)` by rw [GSYM EXP, ADD1] >> fs [] >>
intLib.COOPER_TAC)
>- intLib.COOPER_TAC)
>- (
eq_tac >> rw []
>- intLib.COOPER_TAC
>- intLib.COOPER_TAC >>
`0 i` by intLib.COOPER_TAC >>
fs [GSYM INT_OF_NUM] >>
`&(2 ** size) = 0` by intLib.COOPER_TAC >>
fs [])
>- (
eq_tac >> rw []
>- (
`2 ** size = 2 * 2 ** (size - 1)` by rw [GSYM EXP, ADD1] >> fs [] >>
intLib.COOPER_TAC)
>- intLib.COOPER_TAC
>- intLib.COOPER_TAC)
>- intLib.COOPER_TAC
QED
Theorem w2n_i2n:
∀w. w2n (w : 'a word) = i2n (IntV (w2i w) (dimindex (:'a)))
Proof
rw [i2n_def] >> Cases_on `w` >> fs []
>- (
`INT_MIN (:α) n`
by (
fs [w2i_def] >> rw [] >>
BasicProvers.EVERY_CASE_TAC >> fs [word_msb_n2w_numeric] >>
rfs []) >>
rw [w2i_n2w_neg, dimword_def, int_arithTheory.INT_NUM_SUB])
>- (
`n < INT_MIN (:'a)`
by (
fs [w2i_def] >> rw [] >>
BasicProvers.EVERY_CASE_TAC >> fs [word_msb_n2w_numeric] >>
rfs []) >>
rw [w2i_n2w_pos])
QED
Theorem w2i_n2w:
∀n. n < dimword (:'a) IntV (w2i (n2w n : 'a word)) (dimindex (:'a)) = n2i n (dimindex (:'a))
Proof
rw [n2i_def]
>- (
qspec_then `n` mp_tac w2i_n2w_neg >>
fs [dimword_def, INT_MIN_def] >> rw [GSYM INT_SUB])
>- (irule w2i_n2w_pos >> rw [INT_MIN_def])
QED
Theorem eval_exp_ignores_lem:
∀s1 e v. eval_exp s1 e v ∀s2. s1.locals = s2.locals eval_exp s2 e v
Proof
ho_match_mp_tac eval_exp_ind >>
rw [] >> simp [Once eval_exp_cases] >>
TRY (qexists_tac `vals` >> rw [] >> fs [LIST_REL_EL_EQN] >> NO_TAC) >>
TRY (fs [LIST_REL_EL_EQN] >> NO_TAC) >>
metis_tac []
QED
Theorem eval_exp_ignores:
∀s1 e v s2. s1.locals = s2.locals (eval_exp s1 e v eval_exp s2 e v)
Proof
metis_tac [eval_exp_ignores_lem]
QED
Definition exp_uses_def:
(exp_uses (Var x) = {x})
(exp_uses Nondet = {})
(exp_uses (Label _) = {})
(exp_uses (Splat e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Memory e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Concat es) = bigunion (set (map exp_uses es)))
(exp_uses (Integer _ _) = {})
(exp_uses (Eq e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Lt e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Ult e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Sub _ e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Record es) = bigunion (set (map exp_uses es)))
(exp_uses (Select e1 e2) = exp_uses e1 exp_uses e2)
(exp_uses (Update e1 e2 e3) = exp_uses e1 exp_uses e2 exp_uses e3)
Termination
WF_REL_TAC `measure exp_size` >> rw [] >>
Induct_on `es` >> rw [exp_size_def] >> res_tac >> rw []
End
Theorem eval_exp_ignores_unused_lem:
∀s1 e v.
eval_exp s1 e v
∀s2. DRESTRICT s1.locals (exp_uses e) = DRESTRICT s2.locals (exp_uses e)
eval_exp s2 e v
Proof
ho_match_mp_tac eval_exp_ind >>
rw [exp_uses_def] >> simp [Once eval_exp_cases]
>- (
fs [DRESTRICT_EQ_DRESTRICT, EXTENSION, FDOM_DRESTRICT] >>
imp_res_tac FLOOKUP_SUBMAP >>
fs [FLOOKUP_DRESTRICT]) >>
fs [drestrict_union_eq]
>- metis_tac []
>- metis_tac []
>- (
rpt (pop_assum mp_tac) >>
qid_spec_tac `vals` >>
Induct_on `es` >> rw [] >> Cases_on `vals` >> rw [PULL_EXISTS] >> fs [] >>
rw [] >> fs [drestrict_union_eq] >>
rename [`v1++flat vs`] >>
first_x_assum (qspec_then `vs` mp_tac) >> rw [] >>
qexists_tac `v1 :: vals'` >> rw [])
>- metis_tac []
>- metis_tac []
>- metis_tac []
>- metis_tac []
>- (
rpt (pop_assum mp_tac) >>
qid_spec_tac `vals` >>
Induct_on `es` >> rw [] >> fs [drestrict_union_eq])
>- metis_tac []
>- metis_tac []
QED
Theorem eval_exp_ignores_unused:
∀s1 e v s2. DRESTRICT s1.locals (exp_uses e) = DRESTRICT s2.locals (exp_uses e) (eval_exp s1 e v eval_exp s2 e v)
Proof
metis_tac [eval_exp_ignores_unused_lem]
QED
export_theory ();