1
1
open Sexplib
2
2
open PPrint
3
3
4
- let pHeader filename =
5
- print_endline (String. concat " " [ " // KeY File generated of" ; filename ])
6
-
7
- let pSection name fn sexprs =
8
- let x = List. filter_map fn sexprs in
9
- let doc = PPrint. separate PPrint. hardline x in
10
- print_endline (String. concat " " [ " \\ " ; name; " {" ]);
11
- ToChannel. pretty 0.9 80 stdout doc;
12
- print_endline " }"
13
-
14
- let pSort = function
15
- | Sexp. List [ Sexp. Atom " define-sort" ; Sexp. Atom name ] ->
16
- Some
17
- (PPrint. concat [ PPrint. utf8string name; PPrint. semi; PPrint. hardline ])
18
- | _ -> None
19
-
20
- let pFunction = function
21
- | Sexp. List [ Sexp. Atom " declare-fun" ;
22
- Sexp. Atom name;
23
- Sexp. List args;
24
- Sexp. Atom ret ] ->
25
- if ret = " bool" then None
26
- else if (List. length args) = 0 then
27
- Some
28
- (PPrint. concat [ PPrint. string ret; PPrint. space; PPrint. utf8string name; PPrint. semi; ])
29
- else
30
- Some
31
- (PPrint. concat [PPrint. string ret; PPrint. space;
32
- PPrint. utf8string name;
33
- PPrint. parens
34
- (PPrint. separate_map
35
- (PPrint. precede PPrint. comma PPrint. space)
36
- (fun x -> match x with
37
- | Sexp. Atom y -> PPrint. string y
38
- | Sexp. List _ -> PPrint. empty) args);
39
- PPrint. semi;])
40
- | _ -> None
41
-
42
- let pPredicate = function
43
- | Sexp. List [ Sexp. Atom " define-fun" ; Sexp. Atom name; _; Sexp. Atom " Bool" ]
44
- ->
45
- Some
46
- (PPrint. concat [ PPrint. utf8string name; PPrint. semi; PPrint. hardline ])
47
- | _ -> None
48
-
4
+ (* ----------------------------------------------------------------------------*)
49
5
let op_prec = function
50
6
| "and" -> 100
51
7
| "or" -> 110
@@ -60,43 +16,152 @@ let rec op_prec_sexpr = function
60
16
let unpackAtom = function Sexp. Atom a -> a | _ -> " n/a"
61
17
62
18
let rec expandTerm op exprs =
63
- let opd = PPrint. string op in
19
+ let opd = space ^^ PPrint. string op ^^ space in
64
20
let prec = op_prec op in
65
21
PPrint. flow opd
66
22
(List. map
67
23
(fun x ->
68
24
if prec > = op_prec_sexpr x then term2KeY x
69
- else PPrint. concat [ PPrint. lparen; term2KeY x; PPrint. rparen ] )
25
+ else PPrint. parens ( term2KeY x) )
70
26
exprs)
71
27
72
28
and term2KeY = function
73
29
| Sexp. Atom a -> PPrint. string a
74
- | Sexp. List args ->
75
- let hd = unpackAtom (List. hd args) in
76
- let tl = List. tl args in
77
- match hd with
78
- | "and" -> expandTerm " &" tl
79
- | "or" -> expandTerm " |" tl
80
- | "=>" -> expandTerm " ->" tl
81
- | "+" -> expandTerm " +" tl
82
- | "-" -> expandTerm " -" tl
83
- | "*" -> expandTerm " *" tl
84
- | "/" -> expandTerm " /" tl
85
- | "mod" -> expandTerm " %" tl
86
- | "<" -> expandTerm " %" tl
87
- | "<=" -> expandTerm " <=" tl
88
- | ">" -> expandTerm " >" tl
89
- | ">=" -> expandTerm " >=" tl
90
- | "=" -> expandTerm " =" tl
91
- | _ ->
30
+ | Sexp. List args -> (
31
+ let hd = unpackAtom (List. hd args) in
32
+ let tl = List. tl args in
33
+ match hd with
34
+ | "and" -> expandTerm " &" tl
35
+ | "or" -> expandTerm " |" tl
36
+ | "=>" -> expandTerm " ->" tl
37
+ | "+" -> expandTerm " +" tl
38
+ | "-" -> expandTerm " -" tl
39
+ | "*" -> expandTerm " *" tl
40
+ | "/" -> expandTerm " /" tl
41
+ | "mod" -> expandTerm " %" tl
42
+ | "<" -> expandTerm " %" tl
43
+ | "<=" -> expandTerm " <=" tl
44
+ | ">" -> expandTerm " >" tl
45
+ | ">=" -> expandTerm " >=" tl
46
+ | "=" -> expandTerm " =" tl
47
+ | _ ->
92
48
PPrint. precede (PPrint. string hd)
93
- (PPrint. parens (PPrint. separate_map (PPrint. precede PPrint. space PPrint. comma) term2KeY tl))
49
+ (PPrint. parens
50
+ (PPrint. nest 4 (PPrint. separate_map
51
+ (PPrint. precede PPrint. space PPrint. comma)
52
+ term2KeY tl))))
53
+
54
+ (* ----------------------------------------------------------------------------*)
94
55
56
+ let pHeader filename =
57
+ (* Gives the Header of the KeY file *)
58
+ string " // KeY File generated of" ^^ space ^^ string filename ^^ hardline
59
+
60
+ let pSection name fn sexprs =
61
+ let x = List. filter_map fn sexprs in
62
+ let doc = PPrint. separate PPrint. hardline x in
63
+ hardline ^^ string " \\ " ^^ ! ^ name ^^ braces (nest 4 (hardline ^^ doc)^^ hardline)
64
+
65
+ let pSort = function
66
+ | Sexp. List [ Sexp. Atom " define-sort" ; Sexp. Atom name ] ->
67
+ Some
68
+ (PPrint. concat [ PPrint. utf8string name; PPrint. semi; PPrint. hardline ])
69
+ | _ -> None
70
+
71
+ let rec pFunction = function
72
+ | Sexp. List
73
+ [ Sexp. Atom " declare-fun" ; Sexp. Atom name; Sexp. List args; Sexp. Atom ret ]
74
+ ->
75
+ buildFunction name args ret
76
+ | Sexp. List
77
+ [
78
+ Sexp. Atom " define-fun" ; Sexp. Atom name; Sexp. List args; Sexp. Atom ret; _;
79
+ ] ->
80
+ buildFunction name args ret
81
+ (* (List.map (fun x -> match x with
82
+ | Sexp.List n::_ -> n
83
+ | _ -> Sexp.Atom "") args)*)
84
+ | _ -> None
85
+
86
+ and buildFunction name args ret =
87
+ if ret = " bool" then None
88
+ else if List. length args = 0 then
89
+ Some
90
+ (PPrint. concat
91
+ [
92
+ PPrint. string ret; PPrint. space; PPrint. utf8string name; PPrint. semi;
93
+ ])
94
+ else
95
+ Some
96
+ (PPrint. concat
97
+ [
98
+ PPrint. string ret;
99
+ PPrint. space;
100
+ PPrint. utf8string name;
101
+ PPrint. parens
102
+ (PPrint. separate_map
103
+ (PPrint. precede PPrint. comma PPrint. space)
104
+ (fun x ->
105
+ match x with
106
+ | Sexp. Atom y -> PPrint. string y
107
+ | Sexp. List [ Sexp. Atom n ] -> PPrint. string n
108
+ | _ -> PPrint. empty)
109
+ args);
110
+ PPrint. semi;
111
+ ])
112
+
113
+ let pPredicate = function
114
+ | Sexp. List [ Sexp. Atom " define-fun" ; Sexp. Atom name; _; Sexp. Atom " Bool" ] ->
115
+ Some
116
+ (PPrint. concat [ PPrint. utf8string name; PPrint. semi; PPrint. hardline ])
117
+ | _ -> None
118
+
119
+
120
+ let break0 = break 0
121
+ let break1 = break 1
122
+
123
+ let buildRuleForFunction name args ret def =
124
+ string (" def" ^ name) ^^ space
125
+ ^^ braces
126
+ (nest 4
127
+ (break0 ^^
128
+ (PPrint. separate_map break0
129
+ (fun x ->
130
+ match x with
131
+ | Sexp. List [ Sexp. Atom name; Sexp. Atom sort ] ->
132
+ ! ^ " \\ schemaVar" ^^ space ^^ ! ^ " \\ term " ^^ ! ^ sort ^^ space
133
+ ^^ ! ^ name ^^ semi
134
+ | _ -> empty)
135
+ args
136
+ ^^ break0
137
+ ^^ string " \\ find"
138
+ ^^ parens(! ^ name ^^ parens
139
+ (nest 4
140
+ (PPrint. separate_map (comma ^^ space)
141
+ (fun x ->
142
+ match x with
143
+ | Sexp. List [ Sexp. Atom name; _ ] -> ! ^ name
144
+ | _ -> empty)
145
+ args)))
146
+ ^^ break0 ^^ ! ^ " \\ replacewith" ^^ PPrint. parens (term2KeY def)))^^ break0)
147
+
148
+
149
+ let pRule = function
150
+ (* Tries to construct proof rules for declare functions *)
151
+ | Sexp. List
152
+ [
153
+ Sexp. Atom " define-fun" ;
154
+ Sexp. Atom name;
155
+ Sexp. List args;
156
+ Sexp. Atom ret;
157
+ def
158
+ ] ->
159
+ Some (buildRuleForFunction name args ret def)
160
+ | _ -> None
95
161
96
162
let pprint doc = ToChannel. pretty 0.9 80 stdout doc
97
163
98
164
let pProblem sexprs =
99
- print_endline " \\ problem {" ;
100
165
let assertions =
101
166
List. filter_map
102
167
(function
@@ -106,47 +171,46 @@ let pProblem sexprs =
106
171
let a = Sexp. Atom " and" :: assertions in
107
172
let sexpr = Sexp. List a in
108
173
let term = term2KeY sexpr in
109
- pprint term;
110
- print_endline " }"
174
+ hardline ^^ ! ^ " \\ problem" ^^ braces (term ^^ space ^^ ! ^ " ==>" )
111
175
112
- let pFooter =
113
- print_endline " \n " ;
114
- ()
176
+ let pFooter = hardline
115
177
116
178
let build_goals sexprs =
117
179
let rec loop sexprs goals stack =
118
180
match sexprs with
119
181
| Sexp. List (Sexp. Atom "check-sat" :: _ ) :: rest ->
120
- loop rest (List. rev (List. flatten stack) :: goals) stack
182
+ loop rest (List. rev (List. flatten stack) :: goals) stack
121
183
| Sexp. List (Sexp. Atom "pop" :: _ ) :: rest ->
122
- loop rest goals (List. tl stack)
123
- | Sexp. List (Sexp. Atom "push" :: _ ) :: rest ->
124
- loop rest goals ([] :: stack)
125
- | (_ as term )::rest ->
126
- let firstStack =
127
- if 0 = List. length stack then [] else List. hd stack
128
- in
129
- let restStack = if 0 = List. length stack then [] else List. tl stack in
130
- loop rest goals ((term :: firstStack) :: restStack)
184
+ loop rest goals (List. tl stack)
185
+ | Sexp. List (Sexp. Atom "push" :: _ ) :: rest -> loop rest goals ([] :: stack)
186
+ | (_ as term ) :: rest ->
187
+ let firstStack = if 0 = List. length stack then [] else List. hd stack in
188
+ let restStack = if 0 = List. length stack then [] else List. tl stack in
189
+ loop rest goals ((term :: firstStack) :: restStack)
131
190
| [] -> goals
132
191
in
133
192
loop sexprs [] []
134
193
135
194
let smt2key filename =
136
195
let sexprs = Sexp. load_sexps filename in
137
196
let goals = build_goals sexprs in
138
- List. iter (fun dt ->
139
- pHeader filename;
140
- pSection " sorts" pSort dt;
141
- pSection " functions" pFunction dt;
142
- pSection " predicates" pSort dt;
143
- pProblem dt;
144
- pFooter) goals
197
+
198
+ let docs =
199
+ List. map
200
+ (fun dt ->
201
+ pHeader filename ^^ pSection " sorts" pSort dt
202
+ ^^ pSection " functions" pFunction dt
203
+ ^^ pSection " predicates" pSort dt
204
+ ^^ pSection " rules" pRule dt
205
+ ^^ pProblem dt ^^ pFooter)
206
+ goals
207
+ in
208
+ List. iter (fun doc -> ToChannel. pretty 0.9 80 stdout doc) docs
145
209
146
210
open Sys
211
+
147
212
let () =
148
- if ( Array. length Sys. argv) > 1 then
213
+ if Array. length Sys. argv > 1 then
149
214
let arg = Array. get Sys. argv 1 in
150
215
smt2key arg
151
- else
152
- print_endline " Insufficient Arguments"
216
+ else print_endline " Insufficient Arguments"
0 commit comments