File: utils.ml

package info (click to toggle)
hol-light 20190729-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 42,676 kB
  • sloc: ml: 637,078; cpp: 439; makefile: 301; lisp: 286; java: 279; sh: 239; yacc: 108; perl: 78; ansic: 57; sed: 39; python: 13
file content (169 lines) | stat: -rw-r--r-- 5,793 bytes parent folder | download | duplicates (4)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
(* ========================================================================= *)
(*                                                                           *)
(*   Quantum optics library: utilities.                                      *)
(*                                                                           *)
(*    (c) Copyright, Mohamed Yousri Mahmoud, Vincent Aravantinos, 2012-2013  *)
(*                   Hardware Verification Group,                            *)
(*                   Concordia University                                    *)
(*                                                                           *)
(*           Contact: <mosolim@ece.concordia.ca>, <vincent@ece.concordia.ca> *)
(*                                                                           *)
(* Last update: Feb 27, 2013                                                 *)
(*                                                                           *)
(* ========================================================================= *)

needs "Library/q.ml";;

let EQ_TO_IMP = TAUT `!P Q. (P <=> Q) <=> (P ==> Q) /\ (Q==>P)`;;
let EQ_NOT =  TAUT `!P Q.(~P <=> ~Q) <=> (P <=> Q)`;;
let LET_DEFS = CONJ LET_DEF LET_END_DEF;;

module Pa =
  struct
    include Pa
    let COMPLEX_FIELD = call_with_interface prioritize_complex COMPLEX_FIELD;;
    let SIMPLE_COMPLEX_ARITH =
      call_with_interface prioritize_complex SIMPLE_COMPLEX_ARITH;
  end;;

let HINT_EXISTS_TAC (hs,c as g) =
   let hs = map snd hs in
   let v,c' = dest_exists c in
   let vs,c' = strip_exists c' in
   let hyp_match c h =
     ignore (check (not o exists (C mem vs) o frees) c);
     term_match (subtract (frees c) [v]) c (concl h), h
   in
   let (_,subs,_),h = tryfind (C tryfind hs o hyp_match) (binops `/\` c') in
   let witness =
     match subs with
       |[] -> v
       |[t,u] when u = v -> t
       |_ -> failwith "HINT_EXISTS_TAC not applicable"
   in
   (EXISTS_TAC witness THEN REWRITE_TAC hs) g;;

let GEN_PURE_MP_REWR_TAC sel th =
  let PART_MATCH =
    let concl = snd o dest_imp in
    let body = snd o strip_forall o concl in
    try PART_MATCH (lhs o body) th
    with _ ->
      let f1 = PART_MATCH concl th and f2 = PART_MATCH body th in
      fun t -> try f1 t with _ -> f2 t
  in
  fun (_,c as g) ->
    let th = ref TRUTH in
    let match_term t = try th := PART_MATCH t; true with _ -> false in
    ignore (find_term match_term (sel c));
    let _,big_th = EQ_IMP_RULE (ONCE_REWRITE_CONV[UNDISCH (SPEC_ALL !th)] c) in
    let mp_th = (GEN_ALL o ONCE_REWRITE_RULE[IMP_IMP] o DISCH_ALL) big_th in
    MATCH_MP_TAC mp_th g;;

let PURE_MP_REWR_TAC = GEN_PURE_MP_REWR_TAC I;;

let GEN_MP_REWR_TAC s x =
  GEN_PURE_MP_REWR_TAC s x THEN TRY HINT_EXISTS_TAC THEN ASM_REWRITE_TAC[];;

let MP_REWR_TAC = GEN_MP_REWR_TAC I;;

let MP_REWRITE_TAC = MAP_EVERY MP_REWR_TAC;;

let CASES_REWRITE_TAC th (_,c as g) =
  let PART_MATCH =
    let concl = snd o dest_imp in
    let body = snd o strip_forall o concl in
    try PART_MATCH (lhs o body) th
    with _ ->
      let f1 = PART_MATCH concl th and f2 = PART_MATCH body th in
      fun t -> try f1 t with _ -> f2 t
  in
  let th = ref TRUTH in
  ignore (find_term (fun t -> try th := PART_MATCH t; true with _ -> false) c);
  (ASM_CASES_TAC (lhand (concl !th)) THENL [
    POP_ASSUM (fun x -> REWRITE_TAC[MP !th x] THEN ASSUME_TAC x);
    POP_ASSUM (ASSUME_TAC o REWRITE_RULE[NOT_CLAUSES])]) g;;

let wrap f x = f [x];;

let CONJS xs = end_itlist CONJ xs;;

let rec simp_horn_conv =
  let fact (x,y) = if x = [] then y else fail () in
  let rec tl = function [] -> [] | _::xs -> xs in
  fun l ->
    let fixpoint = ref true in
    let l' =
      rev_itlist (fun (hs,cs) (dones,todos) ->
        let facts = flat (mapfilter fact (dones@todos)) in
        let f = filter (not o C mem facts) in
        let hs' = f hs in
        let cs' = filter (not o C mem hs') (f cs) in
        if not (hs' = hs) || not (cs' = cs) then fixpoint := false;
        if (cs' = [] && cs <> [])
        then (dones,tl todos)
        else ((hs',cs')::dones),tl todos)
      l ([],tl l)
    in
    if !fixpoint then l else simp_horn_conv (fst l');;

let horns_of_term =
  let strip_conj = binops `(/\)` in
  fun t -> map (fun t ->
    try
      let h,c = dest_imp t in
      strip_conj h,strip_conj c
    with _ -> [],[t]) (strip_conj t);;

let term_of_horns =
  let term_of_horn = function
    |[],cs -> list_mk_conj cs
    |_,[] -> `T`
    |hs,cs -> mk_imp (list_mk_conj hs,list_mk_conj cs)
  in
  list_mk_conj o map term_of_horn;;

let SIMP_HORN_CONV t =
  TAUT (mk_eq (t,((term_of_horns o simp_horn_conv o horns_of_term) t)));;

let SIMP_HORN_TAC =
  ASSUM_LIST (fun xs ->
    TRY (fun g -> (MP_TAC (CONJS xs) THEN REWRITE_TAC[IMP_IMP]) g)
    THEN CONV_TAC (TOP_DEPTH_CONV (CHANGED_CONV SIMP_HORN_CONV))
    THEN REWRITE_TAC xs);;

let rec fixpoint f x =
  let y = f x in
  if y = x then y else fixpoint f y;;

let gimp_imp =
  let rec self vars premisses t =
    try
      let v,b = dest_forall t in
      self (v::vars) premisses b
    with _ ->
      try
        let p,c = dest_imp t in
        self vars (p::premisses) c
      with _ ->
        let body =
          match premisses with
          |[] -> t
          |_::_ -> mk_imp(list_mk_conj (rev premisses),t)
        in
        list_mk_forall(rev vars,body)
  in
  self [] [];;

let GIMP_IMP_CONV t = MESON[](mk_eq(t,gimp_imp t));;

let GIMP_IMP = CONV_RULE GIMP_IMP_CONV;;

let MATCH_TRANS thm1 thm2 =
  GEN_ALL (DISCH_ALL (MATCH_MP thm2 (UNDISCH (SPEC_ALL thm1))));;

let GCONV_TAC = CONV_TAC o DEPTH_CONV o CHANGED_CONV;;

let LET_RULE thm = REWRITE_RULE[LET_DEF;LET_END_DEF] thm;;
let LET_RULE_L l thm = REWRITE_RULE([LET_DEF;LET_END_DEF]@l) thm;;
let SPEC_V (x,v) thm = (Pa.SPEC v o Pa.GEN x  o SPEC_ALL) thm;;