1 (* Code for reading QDicams. *)
2 (* Based on Minisat/dimacs_tools.ml *)
3 (* from HOL Light distribution. *)
6 exception Read_dimacs_error;;
10 let intToPrefixedLiteral n =
12 then mk_var(((!prefix) ^ (string_of_int n)), bool_ty)
13 else mk_neg(mk_var((!prefix) ^ (string_of_int(abs n)), bool_ty))
17 (fun t n -> mk_disj(intToPrefixedLiteral n, t))
18 (intToPrefixedLiteral (hd l))
21 let rec dropLine ins =
22 match Stream.peek ins with
23 Some '\n' -> Stream.junk ins
24 | Some _ -> (Stream.junk ins; dropLine ins)
25 | None -> raise Read_dimacs_error
27 let rec stripPreamble ins =
28 match Stream.peek ins with
29 Some 'c' -> (dropLine ins; stripPreamble ins)
30 | Some 'p' -> (dropLine ins; stripPreamble ins)
34 let rec getIntClause lex acc =
36 (try Stream.next lex with
37 Stream.Failure -> Genlex.Kwd "EOF" (* EOF *))
39 (Genlex.Int 0) -> Some acc
40 | (Genlex.Int i) -> getIntClause lex (i::acc)
41 | (Genlex.Kwd "EOF") ->
42 if List.length acc = 0
45 | _ -> raise Read_dimacs_error
47 let rec getIntClause2 lex acc =
48 match Stream.next lex with
50 | (Genlex.Int i) -> i::(getIntClause2 lex acc)
51 | _ -> raise Read_dimacs_error
53 let getTerms lex start_acc =
55 match getIntClause lex [] with
56 Some ns -> loop (mk_conj(buildClause ns,acc))
58 match getIntClause lex start_acc with
59 Some ns -> loop (buildClause ns)
62 type qs = Qe of int list | Qa of int list;;
66 match Stream.next lex with
68 let vars = getIntClause2 lex [] in
69 let (acc',var) = loop acc in
72 let vars = getIntClause2 lex [] in
73 let (acc',var) = loop acc in
75 | Genlex.Int i -> (acc,i)
76 | _ -> raise Read_dimacs_error
81 List.map intToPrefixedLiteral l
83 let add_quantifiers quant body =
84 List.fold_right (fun quants b -> match quants with
85 Qa l -> list_mk_forall (var_map l,b)
86 | Qe l -> list_mk_exists (var_map l,b)
91 match stripPreamble ins with
93 let lex = (Genlex.make_lexer ["EOF";"e";"a"] ins) in
94 let (quant,var) = read_quant lex in
95 ( match getTerms lex [var] with
96 Some body -> Some (add_quantifiers quant body)
100 let readQDimacs filename =
101 let inf = open_in filename in
102 let ins = Stream.of_channel inf in
103 let term = readTerms ins in
105 match term with Some t -> t | None -> raise Read_dimacs_error)