mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-10 21:24:06 -05:00
Added small lexer/parser for dimacs (work in progress).
This commit is contained in:
parent
709ea9740e
commit
df524375a7
6 changed files with 105 additions and 29 deletions
2
Makefile
2
Makefile
|
|
@ -20,7 +20,7 @@ doc:
|
||||||
$(COMP) $(FLAGS) $(DIRS) $(DOC)
|
$(COMP) $(FLAGS) $(DIRS) $(DOC)
|
||||||
|
|
||||||
test: $(TEST)
|
test: $(TEST)
|
||||||
./tests/main
|
./tests/main tests/test-0.d
|
||||||
|
|
||||||
$(TEST): $(LIB)
|
$(TEST): $(LIB)
|
||||||
$(COMP) $(FLAGS) $(DIRS) $(TEST)
|
$(COMP) $(FLAGS) $(DIRS) $(TEST)
|
||||||
|
|
|
||||||
18
sat/sat.ml
18
sat/sat.ml
|
|
@ -1,6 +1,7 @@
|
||||||
(* Copyright 2014 Guillaume Bury *)
|
(* Copyright 2014 Guillaume Bury *)
|
||||||
|
|
||||||
module Fsat = struct
|
module Fsat = struct
|
||||||
|
exception Dummy
|
||||||
exception Out_of_int
|
exception Out_of_int
|
||||||
|
|
||||||
(* Until the constant true_ and false_ are not needed anymore,
|
(* Until the constant true_ and false_ are not needed anymore,
|
||||||
|
|
@ -10,6 +11,8 @@ module Fsat = struct
|
||||||
let max_lit = min max_int (- min_int)
|
let max_lit = min max_int (- min_int)
|
||||||
let max_index = ref 0
|
let max_index = ref 0
|
||||||
|
|
||||||
|
let make i = if i <> 0 then i else raise Dummy
|
||||||
|
|
||||||
let dummy = 0
|
let dummy = 0
|
||||||
|
|
||||||
let neg a = - a
|
let neg a = - a
|
||||||
|
|
@ -64,6 +67,8 @@ end
|
||||||
module Make(Dummy : sig end) = struct
|
module Make(Dummy : sig end) = struct
|
||||||
module SatSolver = Solver.Make(Fsat)(Stypes)(Exp)(Tsat)
|
module SatSolver = Solver.Make(Fsat)(Stypes)(Exp)(Tsat)
|
||||||
|
|
||||||
|
exception Bad_atom
|
||||||
|
|
||||||
type res =
|
type res =
|
||||||
| Sat
|
| Sat
|
||||||
| Unsat
|
| Unsat
|
||||||
|
|
@ -73,8 +78,19 @@ module Make(Dummy : sig end) = struct
|
||||||
type atom = Fsat.t
|
type atom = Fsat.t
|
||||||
type state = SatSolver.t
|
type state = SatSolver.t
|
||||||
|
|
||||||
|
let new_atom () =
|
||||||
|
try
|
||||||
|
Fsat.create ()
|
||||||
|
with Fsat.Out_of_int ->
|
||||||
|
raise Bad_atom
|
||||||
|
|
||||||
|
let make i =
|
||||||
|
try
|
||||||
|
Fsat.make i
|
||||||
|
with Fsat.Dummy ->
|
||||||
|
raise Bad_atom
|
||||||
|
|
||||||
let neg = Fsat.neg
|
let neg = Fsat.neg
|
||||||
let new_atom = Fsat.create
|
|
||||||
|
|
||||||
let hash = Fsat.hash
|
let hash = Fsat.hash
|
||||||
let equal = Fsat.equal
|
let equal = Fsat.equal
|
||||||
|
|
|
||||||
14
sat/sat.mli
14
sat/sat.mli
|
|
@ -3,14 +3,22 @@
|
||||||
module Make(Dummy: sig end) : sig
|
module Make(Dummy: sig end) : sig
|
||||||
(** Fonctor to make a pure SAT Solver module with built-in literals. *)
|
(** Fonctor to make a pure SAT Solver module with built-in literals. *)
|
||||||
|
|
||||||
type atom
|
exception Bad_atom
|
||||||
(** Abstract type for atoms, i.e boolean literals. *)
|
(** Exception raised when a problem with atomic formula encoding is detected. *)
|
||||||
|
|
||||||
|
type atom = private int
|
||||||
|
(** Type for atoms, i.e boolean literals. *)
|
||||||
|
|
||||||
type res = Sat | Unsat
|
type res = Sat | Unsat
|
||||||
(** Type of results returned by the solve function. *)
|
(** Type of results returned by the solve function. *)
|
||||||
|
|
||||||
val new_atom : unit -> atom
|
val new_atom : unit -> atom
|
||||||
(** [new_atom ()] returns a fresh literal. *)
|
(** [new_atom ()] returns a fresh literal.
|
||||||
|
@raise Bad_atom if there are no more integer available to represent new atoms. *)
|
||||||
|
|
||||||
|
val make : int -> atom
|
||||||
|
(** Returns the literal corresponding to the integer.
|
||||||
|
@raise bad_atom if given [0] as argument.*)
|
||||||
|
|
||||||
val neg : atom -> atom
|
val neg : atom -> atom
|
||||||
(** [neg a] returns the negation of a literal. Involutive, i.e [neg (neg a) = a]. *)
|
(** [neg a] returns the negation of a literal. Involutive, i.e [neg (neg a) = a]. *)
|
||||||
|
|
|
||||||
16
util/lexdimacs.mll
Normal file
16
util/lexdimacs.mll
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
(* Copyright 2005 INRIA *)
|
||||||
|
{
|
||||||
|
open Lexing;;
|
||||||
|
open Parsedimacs;;
|
||||||
|
}
|
||||||
|
|
||||||
|
let number = ['0' - '9']+
|
||||||
|
|
||||||
|
rule token = parse
|
||||||
|
| ' ' { token lexbuf }
|
||||||
|
| 'c' [^ '\n']* '\n' { token lexbuf }
|
||||||
|
| 'p' { P }
|
||||||
|
| "cnf" { CNF }
|
||||||
|
| '\n' { EOL }
|
||||||
|
| ['-']? number { LIT (int_of_string (Lexing.lexeme lexbuf)) }
|
||||||
|
| eof { EOF }
|
||||||
29
util/parsedimacs.mly
Normal file
29
util/parsedimacs.mly
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* Copyright 2005 INRIA */
|
||||||
|
|
||||||
|
%{
|
||||||
|
exception Clause_ending of int
|
||||||
|
%}
|
||||||
|
|
||||||
|
%token <int> LIT
|
||||||
|
%token P CNF EOL EOF
|
||||||
|
|
||||||
|
%start file
|
||||||
|
%type <int list list> file
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/* DIMACS syntax */
|
||||||
|
|
||||||
|
file:
|
||||||
|
| EOF { [] }
|
||||||
|
| P CNF LIT LIT EOL clause_list { $6 }
|
||||||
|
;
|
||||||
|
clause_list:
|
||||||
|
| EOF { [] }
|
||||||
|
| clause clause_list { $1 :: $2 }
|
||||||
|
;
|
||||||
|
clause:
|
||||||
|
/* Clause always ends with a '0' */
|
||||||
|
| LIT EOL { if $1 = 0 then [] else raise (Clause_ending $1) }
|
||||||
|
| LIT clause { $1 :: $2 }
|
||||||
|
;
|
||||||
55
util/test.ml
55
util/test.ml
|
|
@ -1,25 +1,32 @@
|
||||||
|
|
||||||
module S = Sat.Make(struct end)
|
module S = Sat.Make(struct end)
|
||||||
|
|
||||||
let anon_fun = fun _ -> ()
|
(* Arguments parsing *)
|
||||||
let usage = "Coming soon..."
|
let file = ref ""
|
||||||
let argspec = [
|
|
||||||
|
let input_file = fun s -> file := s
|
||||||
|
let usage = "Usage : main [options] <file>"
|
||||||
|
let argspec = Arg.align [
|
||||||
"-v", Arg.Int (fun i -> Log.set_debug i),
|
"-v", Arg.Int (fun i -> Log.set_debug i),
|
||||||
"Sets the debug verbose level";
|
"<lvl> Sets the debug verbose level";
|
||||||
]
|
]
|
||||||
|
|
||||||
(* Temp until lexer/parsezr is set up *)
|
(* Entry file parsing *)
|
||||||
let init () =
|
let get_cnf () =
|
||||||
let v = Array.init 5 (fun _ -> S.new_atom ()) in
|
let chan = open_in !file in
|
||||||
[ [
|
let lexbuf = Lexing.from_channel chan in
|
||||||
[v.(0); v.(1)];
|
let l = Parsedimacs.file Lexdimacs.token lexbuf in
|
||||||
[S.neg v.(0); v.(2)];
|
List.map (List.map S.make) l
|
||||||
[S.neg v.(1); v.(2)];
|
|
||||||
[v.(3); v.(4)];
|
let print_cnf cnf =
|
||||||
[S.neg v.(3); S.neg v.(2)];
|
Format.printf "CNF :@\n";
|
||||||
[S.neg v.(4); S.neg v.(2)];
|
List.iter (fun c ->
|
||||||
]
|
Format.fprintf Format.std_formatter "%a;@\n"
|
||||||
]
|
(fun fmt -> List.iter (fun a ->
|
||||||
|
Format.fprintf fmt "%a@ " S.print_atom a
|
||||||
|
)
|
||||||
|
) c
|
||||||
|
) cnf
|
||||||
|
|
||||||
(* Iterate over all variables created *)
|
(* Iterate over all variables created *)
|
||||||
let print_assign fmt () =
|
let print_assign fmt () =
|
||||||
|
|
@ -30,14 +37,14 @@ let print_assign fmt () =
|
||||||
)
|
)
|
||||||
|
|
||||||
let main () =
|
let main () =
|
||||||
Arg.parse argspec anon_fun usage;
|
Arg.parse argspec input_file usage;
|
||||||
List.iter (fun l ->
|
if !file = "" then begin
|
||||||
List.iter (fun c -> Format.printf "Adding : %a@."
|
Arg.usage argspec usage;
|
||||||
(fun _ -> List.iter (fun a -> Format.printf "%a " S.print_atom a)) c) l;
|
exit 2
|
||||||
S.assume l;
|
end;
|
||||||
match S.solve () with
|
let cnf = get_cnf () in
|
||||||
| S.Sat -> Format.printf "Sat@\n%a@." print_assign ()
|
print_cnf cnf;
|
||||||
| S.Unsat -> Format.printf "Unsat@.") (init ());
|
()
|
||||||
;;
|
;;
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue