Coccinelle release 1.0.0-rc14
[bpt/coccinelle.git] / popl / insert_quantifiers.ml
1 (*
2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
9 *
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
13 *
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
24 *)
25
26
27 # 0 "./insert_quantifiers.ml"
28 module Ast = Ast_cocci
29 module Past = Ast_popl
30
31 (* --------------------------------------------------------------------- *)
32
33 let rec fvs_sequence = function
34 Past.Seq(elem,seq) ->
35 Common.union_set (fvs_element elem) (fvs_sequence seq)
36 | Past.Empty -> []
37 | Past.SExists(var,seq) -> failwith "not possible"
38
39 and fvs_element = function
40 Past.Term(term) -> Ast.get_fvs term
41 | Past.Or(seq1,seq2) ->
42 Common.union_set (fvs_sequence seq1) (fvs_sequence seq2)
43 | Past.DInfo(dots,seq_bef,seq_aft) ->
44 List.fold_left
45 (function prev ->
46 function cur ->
47 Common.union_set (fvs_element cur) prev)
48 (fvs_dots dots) seq_bef
49 | Past.EExists(var,seq) -> failwith "not possible"
50
51 and fvs_dots = function
52 Past.Dots -> []
53 | Past.Nest(seq) -> fvs_sequence seq
54 | Past.When(dots,seq) -> Common.union_set (fvs_dots dots) (fvs_sequence seq)
55 | Past.DExists(var,dots) -> failwith "not possible"
56
57 (* --------------------------------------------------------------------- *)
58
59 let rec quant_sequence bound = function
60 Past.Seq(elem,seq) ->
61 let fe = fvs_element elem in
62 let fs = fvs_sequence seq in
63 let inter = Common.inter_set fe fs in
64 let free = Common.minus_set inter bound in
65 let new_bound = free @ bound in
66 List.fold_right (function cur -> function rest -> Past.SExists(cur,rest))
67 free (Past.Seq(quant_element new_bound elem,
68 quant_sequence new_bound seq))
69 | Past.Empty -> Past.Empty
70 | Past.SExists(var,seq) -> failwith "not possible"
71
72 and quant_element bound = function
73 Past.Term(term) as x ->
74 let free = Common.minus_set (fvs_element x) bound in
75 List.fold_right (function cur -> function rest -> Past.EExists(cur,rest))
76 free x
77 | Past.Or(seq1,seq2) ->
78 Past.Or(quant_sequence bound seq1,quant_sequence bound seq2)
79 | Past.DInfo(dots,seq_bef,seq_aft) ->
80 Past.DInfo(quant_dots bound dots,seq_bef,
81 List.map (quant_element bound) seq_aft)
82 | Past.EExists(var,seq) -> failwith "not possible"
83
84 and quant_dots bound = function
85 Past.Dots -> Past.Dots
86 | Past.Nest(seq) -> Past.Nest(quant_sequence bound seq)
87 | Past.When(dots,seq) ->
88 let fd = fvs_dots dots in
89 let fs = fvs_sequence seq in
90 let inter = Common.inter_set fd fs in
91 let free = Common.minus_set inter bound in
92 let new_bound = free @ bound in
93 List.fold_right (function cur -> function rest -> Past.DExists(cur,rest))
94 free (Past.When(quant_dots new_bound dots,
95 quant_sequence new_bound seq))
96 | Past.DExists(var,dots) -> failwith "not possible"
97
98 (* --------------------------------------------------------------------- *)
99
100 let insert_quantifiers x = quant_sequence [] x