1(*
2 * Copyright 1991-1995  University of Cambridge (Author: Monica Nesi)
3 * Copyright 2016-2017  University of Bologna   (Author: Chun Tian)
4 *)
5
6structure ObsCongrConv :> ObsCongrConv =
7struct
8
9open HolKernel Parse boolLib bossLib;
10
11open IndDefRules;
12open CCSLib CCSTheory CCSSyntax;
13open StrongEQTheory StrongEQLib StrongLawsTheory StrongLawsConv;
14open WeakEQTheory WeakEQLib WeakLawsTheory WeakLawsConv;
15open ObsCongrTheory ObsCongrLib ObsCongrLawsTheory;
16
17infix 0 OC_THENC OC_ORELSEC;
18
19(******************************************************************************)
20(*                                                                            *)
21(*          Basic conversions and tactics for applying the laws for           *)
22(*                observation congruence                                      *)
23(*                                                                            *)
24(******************************************************************************)
25
26(* Define the function OC_SUB_CONV. *)
27fun OC_SUB_CONV (c: conv) tm =
28  if is_prefix tm then
29      let val (u, P) = args_prefix tm;
30          val thm = c P
31      in
32          ISPEC u (MATCH_MP OBS_CONGR_SUBST_PREFIX thm)
33      end
34  else if is_sum tm then
35      let val (t1, t2) = args_sum tm;
36          val thm1 = c t1
37          and thm2 = c t2
38      in
39          MATCH_MP OBS_CONGR_PRESD_BY_SUM (CONJ thm1 thm2)
40      end
41  else if is_par tm then
42      let val (t1, t2) = args_par tm;
43          val thm1 = c t1
44          and thm2 = c t2
45      in
46          MATCH_MP OBS_CONGR_PRESD_BY_PAR (CONJ thm1 thm2)
47      end
48  else if is_restr tm then
49      let val (P, L) = args_restr tm;
50          val thm = c P
51      in
52          ISPEC L (MATCH_MP OBS_CONGR_SUBST_RESTR thm)
53      end
54  else if is_relab tm then
55      let val (P, rf) = args_relab tm;
56          val thm = c P
57      in
58          ISPEC rf (MATCH_MP OBS_CONGR_SUBST_RELAB thm)
59      end
60  else
61      OC_ALL_CONV tm;
62
63(* Define the function OC_DEPTH_CONV. *)
64fun OC_DEPTH_CONV (c: conv) t =
65   (OC_SUB_CONV (OC_DEPTH_CONV c) OC_THENC (OC_REPEATC c)) t;
66
67(* Define the function OC_TOP_DEPTH_CONV. *)
68fun OC_TOP_DEPTH_CONV (c: conv) t =
69  ((OC_REPEATC c) OC_THENC
70   (OC_SUB_CONV (OC_TOP_DEPTH_CONV c)) OC_THENC
71   ((c OC_THENC (OC_TOP_DEPTH_CONV c)) OC_ORELSEC OC_ALL_CONV))
72      t;
73
74(* Define the function OC_SUBST for substitution in OBS_CONGR terms. *)
75fun OC_SUBST thm tm = let
76    val (ti, ti') = args_thm thm
77in
78    if tm ~~ ti then thm
79    else if is_prefix tm then
80        let val (u, t) = args_prefix tm;
81            val thm1 = OC_SUBST thm t
82        in
83            ISPEC u (MATCH_MP OBS_CONGR_SUBST_PREFIX thm1)
84        end
85    else if is_sum tm then
86        let val (t1, t2) = args_sum tm;
87            val thm1 = OC_SUBST thm t1;
88            val thm2 = OC_SUBST thm t2
89        in
90            MATCH_MP OBS_CONGR_PRESD_BY_SUM (CONJ thm1 thm2)
91        end
92    else if is_par tm then
93        let val (t1, t2) = args_par tm;
94            val thm1 = OC_SUBST thm t1
95            and thm2 = OC_SUBST thm t2
96        in
97            MATCH_MP OBS_CONGR_PRESD_BY_PAR (CONJ thm1 thm2)
98        end
99    else if is_restr tm then
100        let val (t, L) = args_restr tm;
101            val thm1 = OC_SUBST thm t
102        in
103            ISPEC L (MATCH_MP OBS_CONGR_SUBST_RESTR thm1)
104        end
105    else if is_relab tm then
106        let val (t, rf) = args_relab tm;
107            val thm1 = OC_SUBST thm t
108        in
109            ISPEC rf (MATCH_MP OBS_CONGR_SUBST_RELAB thm1)
110        end
111    else
112        OC_ALL_CONV tm
113end;
114
115(* Define the tactic OC_LHS_SUBST1_TAC: thm_tactic which substitutes a theorem
116   in the left-hand side of an observation congruence. *)
117fun OC_LHS_SUBST1_TAC thm :tactic =
118  fn (asl, w) => let
119      val (opt, t1, t2) = args_equiv w
120  in
121      if opt ~~ ``OBS_CONGR`` then
122          let val thm' = OC_SUBST thm t1;
123              val (t1', t') = args_thm thm' (* t1' = t1 *)
124          in
125              if (t' ~~ t2) then
126                  ([], fn _ => OC_TRANS thm' (ISPEC t' OBS_CONGR_REFL))
127              else
128                  ([(asl, ``OBS_CONGR ^t' ^t2``)], fn [thm''] => OC_TRANS thm' thm'')
129          end
130      else
131          failwith "the goal is not an OBS_CONGR relation"
132  end;
133
134(* The tactic OC_LHS_SUBST_TAC substitutes a list of theorems in the left-hand
135   side of an observation congruence. *)
136fun OC_LHS_SUBST_TAC thmlist =
137    EVERY (map OC_LHS_SUBST1_TAC thmlist);
138
139(* The tactic OC_RHS_SUBST1_TAC substitutes a theorem in the right-hand side
140   of an observation congruence. *)
141fun OC_RHS_SUBST1_TAC thm =
142    REPEAT GEN_TAC
143 >> RULE_TAC OBS_CONGR_SYM
144 >> OC_LHS_SUBST1_TAC thm
145 >> RULE_TAC OBS_CONGR_SYM;
146
147(* The tactic OC_RHS_SUBST_TAC substitutes a list of theorems in the right-hand
148   side of an observation congruence. *)
149fun OC_RHS_SUBST_TAC thmlist =
150    REPEAT GEN_TAC
151 >> RULE_TAC OBS_CONGR_SYM
152 >> OC_LHS_SUBST_TAC thmlist
153 >> RULE_TAC OBS_CONGR_SYM;
154
155(* The tactic OC_SUBST1_TAC (OC_SUBST_TAC) substitutes a (list of) theorem(s)
156   in both sides of an observation congruence. *)
157fun OC_SUBST1_TAC thm =
158    OC_LHS_SUBST1_TAC thm
159 >> OC_RHS_SUBST1_TAC thm;
160
161fun OC_SUBST_TAC thmlist =
162    OC_LHS_SUBST_TAC thmlist
163 >> OC_RHS_SUBST_TAC thmlist;
164
165(******************************************************************************)
166(*                                                                            *)
167(*     Conversions for applying the tau-laws of observation congruence        *)
168(*                                                                            *)
169(******************************************************************************)
170
171(* Conversion for the application of the tau-law TAU1:
172   |- !u E. OBS_CONGR (prefix u (prefix tau E)) (prefix u E) *)
173fun TAU1_CONV tm =
174  if is_prefix tm then
175      let val (u, t) = args_prefix tm
176      in
177          if is_prefix t then
178              let val (u', t') = args_prefix t
179              in
180                  if is_tau u' then
181                      ISPECL [u, t'] TAU1
182                  else
183                      failwith "TAU1_CONV"
184              end
185          else
186              failwith "TAU1_CONV"
187      end
188  else
189      failwith "TAU1_CONV";
190
191(* Conversion for the application of the tau-law TAU2:
192   |- !E. OBS_CONGR (sum E (prefix tau E)) (prefix tau E)
193 *)
194fun TAU2_CONV tm =
195  if is_sum tm then
196    let
197      val (tm1, tm2) = args_sum tm
198    in
199      if is_prefix tm2 then
200        let val (u, t) = args_prefix tm2
201        in
202          if is_tau u andalso tm1 ~~ t then ISPEC t TAU2
203          else failwith "TAU2_CONV"
204        end
205      else failwith "TAU2_CONV"
206    end
207  else failwith "TAU2_CONV";
208
209(* Conversion for the application of the tau-law TAU3:
210   |- !u E E'.
211       OBS_CONGR (sum (prefix u (sum E (prefix tau E'))) (prefix u E'))
212                 (prefix u (sum E (prefix tau E')))
213 *)
214fun TAU3_CONV tm =
215  if is_sum tm then
216      let val (tm1, tm2) = args_sum tm
217      in
218          if is_prefix tm2 then
219              let val (u, t2) = args_prefix tm2
220              in
221                  if is_prefix tm1 then
222                      let val (u', tm3) = args_prefix tm1
223                      in
224                          if u ~~ u' andalso is_sum tm3 then
225                              let val (t1, tm4) = args_sum tm3
226                              in
227                                  if is_prefix tm4 then
228                                      let val (u'', tm5) = args_prefix tm4
229                                      in
230                                          if is_tau u'' andalso tm5 ~~ t2 then
231                                              ISPECL [u, t1, t2] TAU3
232                                          else failwith "TAU3_CONV"
233                                      end
234                                  else failwith "TAU3_CONV"
235                              end
236                          else failwith "TAU3_CONV"
237                      end
238                  else failwith "TAU3_CONV"
239              end
240          else failwith "TAU3_CONV"
241      end
242  else failwith "TAU3_CONV";
243
244(******************************************************************************)
245(*                                                                            *)
246(*            Conversions and tactics for applying the laws for               *)
247(*                 observation congruence                                     *)
248(*                                                                            *)
249(******************************************************************************)
250
251(* Define the conversions for the application of the laws for OBS_CONGR
252   (through the conversions for strong equivalence). *)
253fun STRONG_TO_OBS_CONGR_CONV (c: conv) tm =
254    MATCH_MP STRONG_IMP_OBS_CONGR (c tm);
255
256val [OC_SUM_IDEMP_CONV, OC_SUM_NIL_CONV,
257     OC_RELAB_ELIM_CONV, OC_RESTR_ELIM_CONV,
258     OC_PAR_ELIM_CONV, OC_EXP_THM_CONV, OC_REC_UNF_CONV] =
259    map STRONG_TO_OBS_CONGR_CONV
260        [STRONG_SUM_IDEMP_CONV, STRONG_SUM_NIL_CONV, STRONG_RELAB_ELIM_CONV,
261         STRONG_RESTR_ELIM_CONV, STRONG_PAR_ELIM_CONV, STRONG_EXP_THM_CONV,
262         STRONG_REC_UNF_CONV];
263
264(* Define the tactics for the application of the laws for OBS_CONGR *)
265val [OC_SUM_IDEMP_TAC, OC_SUM_NIL_TAC, OC_RELAB_ELIM_TAC, OC_RESTR_ELIM_TAC,
266     OC_PAR_ELIM_TAC, OC_REC_UNF_TAC, TAU1_TAC, TAU2_TAC, TAU3_TAC] =
267    map (OC_LHS_CONV_TAC o OC_DEPTH_CONV)
268        [OC_SUM_IDEMP_CONV, OC_SUM_NIL_CONV,
269         OC_RELAB_ELIM_CONV, OC_RESTR_ELIM_CONV,
270         OC_PAR_ELIM_CONV, OC_REC_UNF_CONV,
271         TAU1_CONV, TAU2_CONV, TAU3_CONV];
272
273val OC_RHS_RELAB_ELIM_TAC =
274    (OC_RHS_CONV_TAC o OC_DEPTH_CONV) OC_RELAB_ELIM_CONV;
275
276(* TODO: idem for the other operators *)
277
278(* Tactic for applying the expansion theorem (parallel and restriction operators). *)
279val OC_EXP_THM_TAC = OC_LHS_CONV_TAC OC_EXP_THM_CONV;
280
281end (* struct *)
282
283(* last updated: Jun 24, 2017 *)
284