~james/span

ref: 0c6f163a0c6d0b333b095d5f0b629b1709d3bff4 span/src/Layout.thy -rw-r--r-- 5.9 KiB
0c6f163a — james chore(import): snapshot james.dad.town/span at 868a68649c22 14 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
theory Layout
  imports Model
begin

definition width :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> nat \<Rightarrow> nat" where
  "width p W i = (if i \<in> branches p then if i \<in> W then 3 else 2 else 1)"

definition address :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> nat \<Rightarrow> nat" where
  "address p W i = (\<Sum>j<i. width p W j)"

definition distance :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> nat \<Rightarrow> nat" where
  "distance p W i = (let t = destination p i in
    if i < t then (\<Sum>j\<in>{Suc i..<t}. width p W j)
    else (\<Sum>j\<in>{t..<Suc i}. width p W j))"

definition fits :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" where
  "fits p W i bits \<longleftrightarrow>
    (if i < destination p i then distance p W i < 2 ^ (bits - 1)
     else distance p W i \<le> 2 ^ (bits - 1))"

definition displacement :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> nat \<Rightarrow> int" where
  "displacement p W i = int (address p W (destination p i)) - int (address p W (Suc i))"

definition valid :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> bool" where
  "valid p W \<longleftrightarrow> W \<subseteq> branches p \<and>
    (\<forall>i\<in>branches p. fits p W i (if i \<in> W then 16 else 8))"

lemma width_positive: "0 < width p W i"
  by (simp add: width_def)

lemma width_code [code]:
  "width p W i = (if i < length p \<and> target (p ! i) \<noteq> None then if i \<in> W then 3 else 2 else 1)"
  by (simp add: width_def branches_def)

definition sizes :: "nat instruction list \<Rightarrow> nat set \<Rightarrow> nat list" where
  "sizes p W = map (\<lambda>(i,op). if target op = None then 1 else if i \<in> W then 3 else 2)
    (zip [0..<length p] p)"

lemma sizes_length [simp]: "length (sizes p W) = length p"
  by (simp add: sizes_def)

lemma sizes_nth:
  "i < length p \<Longrightarrow> sizes p W ! i = width p W i"
  by (simp add: sizes_def width_def branches_def)

lemma width_mono: "W \<subseteq> V \<Longrightarrow> width p W i \<le> width p V i"
  by (auto simp: width_def)

lemma address_zero [simp]: "address p W 0 = 0"
  by (simp add: address_def)

lemma address_suc [simp]: "address p W (Suc i) = address p W i + width p W i"
  by (simp add: address_def)

lemma address_code [code]:
  "address p W i = sum_list (take i (sizes p W)) + (i - length p)"
proof (induction i)
  case 0
  then show ?case by simp
next
  case (Suc i)
  show ?case
  proof (cases "i < length p")
    case True
    with Suc show ?thesis by (simp add: take_Suc_conv_app_nth sizes_nth)
  next
    case False
    with Suc show ?thesis by (simp add: width_def branches_def Suc_diff_le)
  qed
qed

lemma address_mono:
  "W \<subseteq> V \<Longrightarrow> address p W i \<le> address p V i"
  unfolding address_def by (intro sum_mono width_mono) assumption

lemma distance_mono:
  "W \<subseteq> V \<Longrightarrow> distance p W i \<le> distance p V i"
  unfolding distance_def Let_def
  by (auto simp only: if_True if_False intro!: sum_mono width_mono split: if_splits)

lemma fits_downward:
  "W \<subseteq> V \<Longrightarrow> fits p V i bits \<Longrightarrow> fits p W i bits"
  using distance_mono[of W V p i] unfolding fits_def by auto

lemma prefix_interval:
  fixes f :: "nat \<Rightarrow> nat"
  assumes "a \<le> b"
  shows "(\<Sum>j<b. f j) = (\<Sum>j<a. f j) + (\<Sum>j\<in>{a..<b}. f j)"
proof -
  have disjoint: "{..<a} \<inter> {a..<b} = {}" by auto
  have "{..<b} = {..<a} \<union> {a..<b}" using assms by auto
  then show ?thesis by (simp add: sum.union_disjoint disjoint)
qed

lemma displacement_distance:
  "displacement p W i = (if i < destination p i then int (distance p W i) else - int (distance p W i))"
proof (cases "i < destination p i")
  case True
  then have le: "Suc i \<le> destination p i" by simp
  have eq: "int (\<Sum>j<destination p i. width p W j) =
    int (\<Sum>j<Suc i. width p W j) + int (\<Sum>j\<in>{Suc i..<destination p i}. width p W j)"
    using arg_cong[OF prefix_interval[OF le, of "width p W"], where f=int]
    by (simp only: of_nat_add)
  show ?thesis using eq
    by (simp only: displacement_def distance_def address_def Let_def True if_True; linarith)
next
  case False
  then have le: "destination p i \<le> Suc i" by simp
  have eq: "int (\<Sum>j<Suc i. width p W j) =
    int (\<Sum>j<destination p i. width p W j) + int (\<Sum>j\<in>{destination p i..<Suc i}. width p W j)"
    using arg_cong[OF prefix_interval[OF le, of "width p W"], where f=int]
    by (simp only: of_nat_add)
  show ?thesis using eq
    by (simp only: displacement_def distance_def address_def Let_def False if_False; linarith)
qed

lemma distance_code [code]:
  "distance p W i = (if i < destination p i
    then address p W (destination p i) - address p W (Suc i)
    else address p W (Suc i) - address p W (destination p i))"
  using displacement_distance[of p W i]
  unfolding displacement_def by (auto simp: of_nat_diff split: if_splits)

lemma fits_signed:
  "fits p W i bits \<longleftrightarrow>
    - int (2 ^ (bits - 1)) \<le> displacement p W i \<and>
    displacement p W i < int (2 ^ (bits - 1))"
proof -
  have positive: "(0::int) < int (2 ^ (bits - 1) :: nat)" by simp
  have nonnegative: "(0::int) \<le> int (distance p W i)" by simp
  have lower: "- int (2 ^ (bits - 1)) \<le> int (distance p W i)"
    using positive nonnegative by linarith
  have upper: "- int (distance p W i) < int (2 ^ (bits - 1))"
    using positive nonnegative by linarith
  show ?thesis
    by (cases "i < destination p i")
      (simp_all only: fits_def displacement_distance if_True if_False lower upper
        of_nat_less_iff of_nat_le_iff neg_le_iff_le simp_thms)
qed

lemma address_strict:
  assumes "i < j"
  shows "address p W i < address p W j"
proof -
  have pos: "0 < (\<Sum>k\<in>{i..<j}. width p W k)"
    using assms by (intro sum_pos2[where i=i]) (auto simp: width_positive)
  show ?thesis using prefix_interval[OF less_imp_le[OF assms], of "width p W"] pos
    by (simp add: address_def)
qed

end