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