Release coccinelle-0.2.4
[bpt/coccinelle.git] / popl09 / insert_quantifiers.ml
CommitLineData
9bc82bae
C
1(*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
c491d8ee
C
25(*
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
31 *
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
35 *
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
43 *
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
46 *)
47
48
951c7801
C
49module Ast = Ast_cocci
50module Past = Ast_popl
51
52(* --------------------------------------------------------------------- *)
53
54let rec fvs_sequence = function
55 Past.Seq(elem,seq) ->
56 Common.union_set (fvs_element elem) (fvs_sequence seq)
57 | Past.Empty -> []
58 | Past.SExists(var,seq) -> failwith "not possible"
59
60and fvs_term = function
61 Past.Atomic(term) -> Ast.get_fvs term
62 | Past.IfThen(test,thn,(afvs,_,_,_)) ->
63 Common.union_set afvs
64 (Common.union_set (fvs_term test) (fvs_term thn))
65 | Past.TExists(var,term) -> failwith "not possible"
66
67and fvs_element = function
68 Past.Term(term,_) -> fvs_term term
69 | Past.Or(seq1,seq2) ->
70 Common.union_set (fvs_sequence seq1) (fvs_sequence seq2)
71 | Past.DInfo(dots) -> fvs_dots dots
72 | Past.EExists(var,seq) -> failwith "not possible"
73
74and fvs_dots = function
75 Past.Dots -> []
76 | Past.Nest(seq) -> fvs_sequence seq
77 | Past.When(dots,seq) -> Common.union_set (fvs_dots dots) (fvs_sequence seq)
78
79(* --------------------------------------------------------------------- *)
80
81let inter_set l1 l2 = List.filter (function l1e -> List.mem l1e l2) l1
82
83let minus_set l1 l2 = List.filter (function l1e -> not (List.mem l1e l2)) l1
84
85let rec quant_sequence bound = function
86 Past.Seq(elem,seq) ->
87 let fe = fvs_element elem in
88 let fs = fvs_sequence seq in
89 let inter = inter_set fe fs in
90 let free = minus_set inter bound in
91 let new_bound = free @ bound in
92 List.fold_right (function cur -> function rest -> Past.SExists(cur,rest))
93 free (Past.Seq(quant_element new_bound elem,
94 quant_sequence new_bound seq))
95 | Past.Empty -> Past.Empty
96 | Past.SExists(var,seq) -> failwith "not possible"
97
98and quant_term bound = function
99 (Past.Atomic(term)) as x ->
100 let free = minus_set (Ast.get_fvs term) bound in
101 List.fold_right (function cur -> function rest -> Past.TExists(cur,rest))
102 free x
103 | Past.IfThen(test,thn,((afvs,_,_,_) as aft)) ->
104 let fts = fvs_term test in
105 let fth = fvs_term thn in
106 let inter = inter_set fts fth in
107 let free = minus_set inter bound in
108 let new_bound = free @ bound in
109 List.fold_right (function cur -> function rest -> Past.TExists(cur,rest))
110 free (Past.IfThen(quant_term new_bound test,
111 quant_term new_bound thn,
112 aft))
113 | Past.TExists(var,term) -> failwith "not possible"
114
115and quant_element bound = function
116 Past.Term(term,ba) ->
117 Past.Term(quant_term bound term,dots_bef_aft bound ba)
118 | Past.Or(seq1,seq2) ->
119 Past.Or(quant_sequence bound seq1,quant_sequence bound seq2)
120 | Past.DInfo(dots) ->
121 Past.DInfo(quant_dots bound dots)
122 | Past.EExists(var,seq) -> failwith "not possible"
123
124and dots_bef_aft bound = function
125 Past.AddingBetweenDots (brace_term,n) ->
126 Past.AddingBetweenDots (quant_term bound brace_term,n)
127 | Past.DroppingBetweenDots (brace_term,n) ->
128 Past.DroppingBetweenDots (quant_term bound brace_term,n)
129 | Past.NoDots -> Past.NoDots
130
131and quant_dots bound = function
132 Past.Dots -> Past.Dots
133 | Past.Nest(seq) -> Past.Nest(quant_sequence bound seq)
134 | Past.When(dots,seq) ->
135 Past.When(quant_dots bound dots, quant_sequence bound seq)
136
137(* --------------------------------------------------------------------- *)
138
139let insert_quantifiers x = quant_sequence [] x