68 (**************************************************************************************************) |
68 (**************************************************************************************************) |
69 |
69 |
70 (* rename_abs:term (von:string,nach:string,trm:term) benennt in trm alle Lambda-Abstraktionen |
70 (* rename_abs:term (von:string,nach:string,trm:term) benennt in trm alle Lambda-Abstraktionen |
71 mit Namen von in nach um *) |
71 mit Namen von in nach um *) |
72 |
72 |
73 fun rename_abs (von,nach,Abs (s,t,trm)) =if von=s |
73 fun rename_abs (von,nach,Abs (s,t,trm)) =if von=s |
74 then Abs (nach,t,rename_abs (von,nach,trm)) |
74 then Abs (nach,t,rename_abs (von,nach,trm)) |
75 else Abs (s,t,rename_abs (von,nach,trm)) |
75 else Abs (s,t,rename_abs (von,nach,trm)) |
76 | rename_abs (von,nach,trm1 $ trm2) =rename_abs (von,nach,trm1) $ rename_abs (von,nach,trm2) |
76 | rename_abs (von,nach,trm1 $ trm2) =rename_abs (von,nach,trm1) $ rename_abs (von,nach,trm2) |
77 | rename_abs (_,_,trm) =trm; |
77 | rename_abs (_,_,trm) =trm; |
78 |
78 |
79 (* ren_abs_thm:thm (von:string,nach:string,theorem:thm) benennt in theorem alle Lambda-Abstraktionen |
79 (* ren_abs_thm:thm (von:string,nach:string,theorem:thm) benennt in theorem alle Lambda-Abstraktionen |
80 mit Namen von in nach um. Vorgehen: |
80 mit Namen von in nach um. Vorgehen: |
81 - Term t zu thoerem bestimmen |
81 - Term t zu thoerem bestimmen |
82 - Term t' zu t durch Umbenennen der Namen generieren |
82 - Term t' zu t durch Umbenennen der Namen generieren |
83 - Certified Term ct' zu t' erstellen |
83 - Certified Term ct' zu t' erstellen |
84 - Thoerem ct'==ct' anlegen |
84 - Thoerem ct'==ct' anlegen |
85 - Nach der Regel "[|P==Q; P|] ==> Q" wird aus "ct'==ct'" und theorem das Theorem zu ct' |
85 - Nach der Regel "[|P==Q; P|] ==> Q" wird aus "ct'==ct'" und theorem das Theorem zu ct' |
86 abgeleitet (ist moeglich, da t' mit t unifiziert werden kann, da nur Umnbenennungen) *) |
86 abgeleitet (ist moeglich, da t' mit t unifiziert werden kann, da nur Umnbenennungen) *) |
87 |
87 |
88 fun ren_abs_thm (von,nach,theorem) = |
88 fun ren_abs_thm (von,nach,theorem) = |
89 equal_elim |
89 equal_elim |
90 ( |
90 ( |
91 reflexive ( |
91 reflexive ( |
92 cterm_of |
92 cterm_of |
93 (#sign (rep_thm theorem)) |
93 (#sign (rep_thm theorem)) |
94 (rename_abs (von,nach,#prop (rep_thm theorem))) |
94 (rename_abs (von,nach,#prop (rep_thm theorem))) |
95 ) |
95 ) |
96 ) |
96 ) |
97 theorem; |
97 theorem; |
98 |
98 |
99 |
99 |
100 (**************************************************************************************************) |
100 (**************************************************************************************************) |
101 (*** Taktik zum Anwenden eines Theorems theorem auf ein Subgoal i durch ***) |
101 (*** Taktik zum Anwenden eines Theorems theorem auf ein Subgoal i durch ***) |
102 (*** - Umbenennen von Lambda-Abstraktionen im Theorem ***) |
102 (*** - Umbenennen von Lambda-Abstraktionen im Theorem ***) |
105 (**************************************************************************************************) |
105 (**************************************************************************************************) |
106 |
106 |
107 (* - rens:(string*string) list, d.h. es koennen verschiedene Lambda-Abstraktionen umbenannt werden |
107 (* - rens:(string*string) list, d.h. es koennen verschiedene Lambda-Abstraktionen umbenannt werden |
108 - insts:(cterm*cterm) list, d.h. es koennen verschiedene Variablen instanziiert werden *) |
108 - insts:(cterm*cterm) list, d.h. es koennen verschiedene Variablen instanziiert werden *) |
109 |
109 |
110 fun comp_inst_ren_tac rens insts theorem i = |
110 fun comp_inst_ren_tac rens insts theorem i = |
111 let |
111 let |
112 fun compose_inst_ren_tac [] insts theorem i = |
112 fun compose_inst_ren_tac [] insts theorem i = |
113 compose_tac (false,cterm_instantiate insts theorem,nprems_of theorem) i |
113 compose_tac (false,cterm_instantiate insts theorem,nprems_of theorem) i |
114 | compose_inst_ren_tac ((von,nach)::rl) insts theorem i = |
114 | compose_inst_ren_tac ((von,nach)::rl) insts theorem i = |
115 compose_inst_ren_tac rl insts (ren_abs_thm (von,nach,theorem)) i |
115 compose_inst_ren_tac rl insts (ren_abs_thm (von,nach,theorem)) i |
116 in |
116 in |
117 compose_inst_ren_tac rens insts theorem i |
117 compose_inst_ren_tac rens insts theorem i |
118 end; |
118 end; |
119 |
119 |
120 |
120 |
121 (**************************************************************************************************) |
121 (**************************************************************************************************) |
122 (*** Taktik zum Eliminieren des Zustandes waehrend Hoare-Beweisen ***) |
122 (*** Taktik zum Eliminieren des Zustandes waehrend Hoare-Beweisen ***) |
123 (*** Bsp.: "!!s. s(Suc(0))=0 --> s(Suc(0))+1=1" wird zu "!!s b. b=0 --> b+1=1" ***) |
123 (*** Bsp.: "!!s. s(Suc(0))=0 --> s(Suc(0))+1=1" wird zu "!!s b. b=0 --> b+1=1" ***) |
124 (**************************************************************************************************) |
124 (**************************************************************************************************) |
125 |
125 |
126 (* pvars_of_term:term list (name:string,trm:term) gibt die Liste aller Programm-Variablen |
126 (* pvars_of_term:term list (name:string,trm:term) gibt die Liste aller Programm-Variablen |
127 aus trm zurueck. name gibt dabei den Namen der Zustandsvariablen an. |
127 aus trm zurueck. name gibt dabei den Namen der Zustandsvariablen an. |
128 Bsp.: bei name="s" und dem Term "s(Suc(Suc(0)))=s(0)" (entspricht "c=a") |
128 Bsp.: bei name="s" und dem Term "s(Suc(Suc(0)))=s(0)" (entspricht "c=a") |
129 wird [0,Suc(Suc(0))] geliefert (Liste ist i.A. unsortiert) *) |
129 wird [0,Suc(Suc(0))] geliefert (Liste ist i.A. unsortiert) *) |
130 |
130 |
131 fun pvars_of_term (name,trm) = |
131 fun pvars_of_term (name,trm) = |
132 let |
132 let |
133 fun add_vars (name,Free (s,t) $ trm,vl) =if name=s |
133 fun add_vars (name,Free (s,t) $ trm,vl) =if name=s |
134 then if trm mem vl |
134 then if trm mem vl |
135 then vl |
135 then vl |
136 else trm::vl |
136 else trm::vl |
137 else add_vars (name,trm,vl) |
137 else add_vars (name,trm,vl) |
138 | add_vars (name,Abs (s,t,trm),vl) =add_vars (name,trm,vl) |
138 | add_vars (name,Abs (s,t,trm),vl) =add_vars (name,trm,vl) |
139 | add_vars (name,trm1 $ trm2,vl) =add_vars (name,trm2,add_vars (name,trm1,vl)) |
139 | add_vars (name,trm1 $ trm2,vl) =add_vars (name,trm2,add_vars (name,trm1,vl)) |
140 | add_vars (_,_,vl) =vl |
140 | add_vars (_,_,vl) =vl |
141 in |
141 in |
142 add_vars (name,trm,[]) |
142 add_vars (name,trm,[]) |
143 end; |
143 end; |
144 |
144 |
145 (* VarsElimTac: Taktik zum Eliminieren von bestimmten Programmvariablen aus dem Subgoal i |
145 (* VarsElimTac: Taktik zum Eliminieren von bestimmten Programmvariablen aus dem Subgoal i |
146 - v::vl:(term) list Liste der zu eliminierenden Programmvariablen |
146 - v::vl:(term) list Liste der zu eliminierenden Programmvariablen |
147 - meta_spec:thm Theorem, welches zur Entfernung der Variablen benutzt wird |
147 - meta_spec:thm Theorem, welches zur Entfernung der Variablen benutzt wird |
148 z.B.: "(!!s x.PROP P(s,x)) ==> (!!s.PROP P(s,x(s)))" |
148 z.B.: "(!!s x.PROP P(s,x)) ==> (!!s.PROP P(s,x(s)))" |
149 - namexAll:string Name von ^ (hier "x") |
149 - namexAll:string Name von ^ (hier "x") |
150 - varx:term Term zu ^ (hier Var(("x",0),...)) |
150 - varx:term Term zu ^ (hier Var(("x",0),...)) |
151 - varP:term Term zu ^ (hier Var(("P",0),...)) |
151 - varP:term Term zu ^ (hier Var(("P",0),...)) |
152 - type_pvar:typ Typ der Programmvariablen (d.h. 'a bei 'a prog, z.B.: nat, bool, ...) |
152 - type_pvar:typ Typ der Programmvariablen (d.h. 'a bei 'a prog, z.B.: nat, bool, ...) |
153 |
153 |
154 Vorgehen: |
154 Vorgehen: |
155 - eliminiere jede pvar durch Anwendung von comp_inst_ren_tac. Dazu: |
155 - eliminiere jede pvar durch Anwendung von comp_inst_ren_tac. Dazu: |
156 - Unbenennung in meta_spec: namexAll wird in den Namen der Prog.-Var. umbenannt |
156 - Unbenennung in meta_spec: namexAll wird in den Namen der Prog.-Var. umbenannt |
157 z.B.: fuer die Prog.-Var. mit Namen "a" ergibt sich |
157 z.B.: fuer die Prog.-Var. mit Namen "a" ergibt sich |
158 meta_spec zu "(!! s a.PROP P(s,a)) ==> (!! s.PROP P(s,x(s)))" |
158 meta_spec zu "(!! s a.PROP P(s,a)) ==> (!! s.PROP P(s,x(s)))" |
159 - Instanziierungen in meta_spec: |
159 - Instanziierungen in meta_spec: |
160 varx wird mit "%s:(type_pvar) state.s(pvar)" instanziiert |
160 varx wird mit "%s:(type_pvar) state.s(pvar)" instanziiert |
161 varP wird entsprechend instanziiert. Beispiel fuer Prog.-Var. "a": |
161 varP wird entsprechend instanziiert. Beispiel fuer Prog.-Var. "a": |
162 - zu Subgoal "!!s.s(Suc(0)) = s(0) ==> s(0) = 1" bestimme Term ohne "!!s.": |
162 - zu Subgoal "!!s.s(Suc(0)) = s(0) ==> s(0) = 1" bestimme Term ohne "!!s.": |
163 trm0 = "s(Suc(0)) = s(0) ==> s(0) = 1" (s ist hier freie Variable) |
163 trm0 = "s(Suc(0)) = s(0) ==> s(0) = 1" (s ist hier freie Variable) |
164 - substituiere alle Vorkommen von s(pvar) durch eine freie Var. xs: |
164 - substituiere alle Vorkommen von s(pvar) durch eine freie Var. xs: |
165 trm1 = "s(Suc(0)) = xs ==> xs = 1" |
165 trm1 = "s(Suc(0)) = xs ==> xs = 1" |
166 - abstrahiere ueber xs: |
166 - abstrahiere ueber xs: |
167 trm2 = "%xs.s(Suc(0)) = xs ==> xs = 1" |
167 trm2 = "%xs.s(Suc(0)) = xs ==> xs = 1" |
168 - abstrahiere ueber restliche Vorkommen von s: |
168 - abstrahiere ueber restliche Vorkommen von s: |
169 trm3 = "%s xs.s(Suc(0)) = xs ==> xs = 1" |
169 trm3 = "%s xs.s(Suc(0)) = xs ==> xs = 1" |
170 - instanziiere varP mit trm3 |
170 - instanziiere varP mit trm3 |
171 *) |
171 *) |
172 |
172 |
173 fun VarsElimTac ([],_,_,_,_,_) i =all_tac |
173 fun VarsElimTac ([],_,_,_,_,_) i =all_tac |
174 | VarsElimTac (v::vl,meta_spec,namexAll,varx,varP,type_pvar) i = |
174 | VarsElimTac (v::vl,meta_spec,namexAll,varx,varP,type_pvar) i = |
175 STATE ( |
175 STATE ( |
176 fn state => |
176 fn state => |
177 comp_inst_ren_tac |
177 comp_inst_ren_tac |
178 [(namexAll,pvar2pvarID v)] |
178 [(namexAll,pvar2pvarID v)] |
179 [( |
179 [( |
180 cterm_of (#sign (rep_thm state)) varx, |
180 cterm_of (#sign (rep_thm state)) varx, |
181 cterm_of (#sign (rep_thm state)) ( |
181 cterm_of (#sign (rep_thm state)) ( |
182 Abs ("s",Type ("nat",[]) --> type_pvar,Bound 0 $ v) |
182 Abs ("s",Type ("nat",[]) --> type_pvar,Bound 0 $ v) |
183 ) |
183 ) |
184 ),( |
184 ),( |
185 cterm_of (#sign (rep_thm state)) varP, |
185 cterm_of (#sign (rep_thm state)) varP, |
186 cterm_of (#sign (rep_thm state)) ( |
186 cterm_of (#sign (rep_thm state)) ( |
187 let |
187 let |
188 val (_,_,_ $ Abs (_,_,trm),_) = dest_state (state,i); |
188 val (_,_,_ $ Abs (_,_,trm),_) = dest_state (state,i); |
189 val (sname,trm0) = variant_abs ("s",dummyT,trm); |
189 val (sname,trm0) = variant_abs ("s",dummyT,trm); |
190 val xsname = variant_name ("xs",trm0); |
190 val xsname = variant_name ("xs",trm0); |
191 val trm1 = subst_term (Free (sname,dummyT) $ v,Syntax.free xsname,trm0) |
191 val trm1 = subst_term (Free (sname,dummyT) $ v,Syntax.free xsname,trm0) |
192 val trm2 = Abs ("xs",type_pvar,abstract_over (Syntax.free xsname,trm1)) |
192 val trm2 = Abs ("xs",type_pvar,abstract_over (Syntax.free xsname,trm1)) |
193 in |
193 in |
194 Abs ("s",Type ("nat",[]) --> type_pvar,abstract_over (Free (sname,dummyT),trm2)) |
194 Abs ("s",Type ("nat",[]) --> type_pvar,abstract_over (Free (sname,dummyT),trm2)) |
195 end |
195 end |
196 ) |
196 ) |
197 )] |
197 )] |
198 meta_spec i |
198 meta_spec i |
199 ) |
199 ) |
200 THEN |
200 THEN |
201 (VarsElimTac (vl,meta_spec,namexAll,varx,varP,type_pvar) i); |
201 (VarsElimTac (vl,meta_spec,namexAll,varx,varP,type_pvar) i); |
202 |
202 |
203 (* StateElimTac: Taktik zum Eliminieren aller Programmvariablen aus dem Subgoal i |
203 (* StateElimTac: Taktik zum Eliminieren aller Programmvariablen aus dem Subgoal i |
204 |
204 |
205 zur Erinnerung: |
205 zur Erinnerung: |
206 - das Subgoal hat vor Anwendung dieser Taktik die Form "!!s:('a) state.P(s)", |
206 - das Subgoal hat vor Anwendung dieser Taktik die Form "!!s:('a) state.P(s)", |
207 d.h. den Term Const("all",_) $ Abs ("s",pvar --> 'a,_) |
207 d.h. den Term Const("all",_) $ Abs ("s",pvar --> 'a,_) |
208 - meta_spec hat die Form "(!!s x.PROP P(s,x)) ==> (!!s.PROP P(s,x(s)))" |
208 - meta_spec hat die Form "(!!s x.PROP P(s,x)) ==> (!!s.PROP P(s,x(s)))" |
209 *) |
209 *) |
210 |
210 |
211 fun StateElimTac i = |
211 fun StateElimTac i = |
212 STATE ( |
212 STATE ( |
213 fn state => |
213 fn state => |
214 let |
214 let |
215 val (_,_,_ $ Abs (_,Type ("fun",[_,type_pvar]),trm),_) = dest_state (state,i); |
215 val (_,_,_ $ Abs (_,Type ("fun",[_,type_pvar]),trm),_) = dest_state (state,i); |
216 val _ $ (_ $ Abs (_,_,_ $ Abs (namexAll,_,_))) $ |
216 val _ $ (_ $ Abs (_,_,_ $ Abs (namexAll,_,_))) $ |
217 (_ $ Abs (_,_,varP $ _ $ (varx $ _))) = #prop (rep_thm meta_spec) |
217 (_ $ Abs (_,_,varP $ _ $ (varx $ _))) = #prop (rep_thm meta_spec) |
218 in |
218 in |
219 VarsElimTac (pvars_of_term (variant_abs ("s",dummyT,trm)),meta_spec,namexAll,varx,varP,type_pvar) i |
219 VarsElimTac (pvars_of_term (variant_abs ("s",dummyT,trm)),meta_spec,namexAll,varx,varP,type_pvar) i |
220 end |
220 end |
221 ); |
221 ); |
222 |
222 |
223 |
223 |
224 |
224 |
225 (*** tactics for verification condition generation ***) |
225 (*** tactics for verification condition generation ***) |
226 |
226 |