mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-09 20:55:39 -05:00
Added Expr and typing module from ArchSat
This commit is contained in:
parent
bb2c931d68
commit
742f8c469d
24 changed files with 1503 additions and 1249 deletions
4
.merlin
4
.merlin
|
|
@ -4,7 +4,6 @@ S src/sat
|
||||||
S src/smt
|
S src/smt
|
||||||
S src/backend
|
S src/backend
|
||||||
S src/util
|
S src/util
|
||||||
S src/util/smtlib
|
|
||||||
S tests
|
S tests
|
||||||
|
|
||||||
B _build/src/
|
B _build/src/
|
||||||
|
|
@ -13,6 +12,7 @@ B _build/src/solver
|
||||||
B _build/src/sat
|
B _build/src/sat
|
||||||
B _build/src/smt
|
B _build/src/smt
|
||||||
B _build/src/util
|
B _build/src/util
|
||||||
B _build/src/util/smtlib
|
|
||||||
B _build/src/backend
|
B _build/src/backend
|
||||||
B _build/tests
|
B _build/tests
|
||||||
|
|
||||||
|
PKG dolmen
|
||||||
|
|
|
||||||
7
_tags
7
_tags
|
|
@ -9,10 +9,9 @@ true: inline(100), optimize(3), unbox_closures, unbox_closures_factor(20)
|
||||||
<src/core>: include
|
<src/core>: include
|
||||||
<src/solver>: include
|
<src/solver>: include
|
||||||
<src/backend>: include
|
<src/backend>: include
|
||||||
<src/smt>: include
|
|
||||||
<src/sat>: include
|
<src/sat>: include
|
||||||
|
<src/smt>: include
|
||||||
<src/util>: include
|
<src/util>: include
|
||||||
<src/util/smtlib>: include
|
|
||||||
|
|
||||||
# Pack options
|
# Pack options
|
||||||
<src/core/*.cmx>: for-pack(Msat)
|
<src/core/*.cmx>: for-pack(Msat)
|
||||||
|
|
@ -22,6 +21,10 @@ true: inline(100), optimize(3), unbox_closures, unbox_closures_factor(20)
|
||||||
<src/sat/*.cmx>: for-pack(Msat_sat)
|
<src/sat/*.cmx>: for-pack(Msat_sat)
|
||||||
<src/smt/*.cmx>: for-pack(Msat_smt)
|
<src/smt/*.cmx>: for-pack(Msat_smt)
|
||||||
|
|
||||||
|
# Bin options
|
||||||
|
<src/main.*>: package(dolmen)
|
||||||
|
<src/util/type.*>: package(dolmen)
|
||||||
|
|
||||||
# more warnings
|
# more warnings
|
||||||
<src/**/*.ml>: warn_K, warn_Y, warn_X
|
<src/**/*.ml>: warn_K, warn_Y, warn_X
|
||||||
<src/**/*.ml>: short_paths, safe_string, strict_sequence
|
<src/**/*.ml>: short_paths, safe_string, strict_sequence
|
||||||
|
|
|
||||||
137
src/main.ml
137
src/main.ml
|
|
@ -5,45 +5,27 @@ Copyright 2014 Simon Cruanes
|
||||||
*)
|
*)
|
||||||
|
|
||||||
module F = Expr
|
module F = Expr
|
||||||
|
(*
|
||||||
module T = Msat_smt.Cnf.S
|
module T = Msat_smt.Cnf.S
|
||||||
module Sat = Msat_sat.Sat.Make(struct end)
|
module Sat = Msat_sat.Sat.Make(struct end)
|
||||||
module Smt = Msat_smt.Smt.Make(struct end)
|
module Smt = Msat_smt.Smt.Make(struct end)
|
||||||
module Mcsat = Msat_smt.Mcsat.Make(struct end)
|
module Mcsat = Msat_smt.Mcsat.Make(struct end)
|
||||||
|
*)
|
||||||
|
|
||||||
|
module P =
|
||||||
|
Dolmen.Logic.Make(Dolmen.ParseLocation)
|
||||||
|
(Dolmen.Id)(Dolmen.Term)(Dolmen.Statement)
|
||||||
|
|
||||||
exception Incorrect_model
|
exception Incorrect_model
|
||||||
exception Out_of_time
|
exception Out_of_time
|
||||||
exception Out_of_space
|
exception Out_of_space
|
||||||
|
|
||||||
(* IO wrappers *)
|
|
||||||
(* Types for input/output languages *)
|
|
||||||
type sat_input =
|
|
||||||
| Auto
|
|
||||||
| Dimacs
|
|
||||||
| Smtlib
|
|
||||||
|
|
||||||
type sat_output =
|
|
||||||
| Standard (* Only output problem status *)
|
|
||||||
| Dedukti
|
|
||||||
| Dot
|
|
||||||
|
|
||||||
type solver =
|
type solver =
|
||||||
| Sat
|
| Sat
|
||||||
| Smt
|
| Smt
|
||||||
| Mcsat
|
| Mcsat
|
||||||
|
|
||||||
let input = ref Auto
|
|
||||||
let output = ref Standard
|
|
||||||
let solver = ref Smt
|
let solver = ref Smt
|
||||||
|
|
||||||
let input_list = [
|
|
||||||
"auto", Auto;
|
|
||||||
"dimacs", Dimacs;
|
|
||||||
"smtlib", Smtlib;
|
|
||||||
]
|
|
||||||
let output_list = [
|
|
||||||
"dot", Dot;
|
|
||||||
"dk", Dedukti;
|
|
||||||
]
|
|
||||||
let solver_list = [
|
let solver_list = [
|
||||||
"sat", Sat;
|
"sat", Sat;
|
||||||
"smt", Smt;
|
"smt", Smt;
|
||||||
|
|
@ -61,86 +43,8 @@ let set_flag opt arg flag l =
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
invalid_arg (error_msg opt arg l)
|
invalid_arg (error_msg opt arg l)
|
||||||
|
|
||||||
let set_input s = set_flag "Input" s input input_list
|
|
||||||
let set_output s = set_flag "Output" s output output_list
|
|
||||||
let set_solver s = set_flag "Solver" s solver solver_list
|
let set_solver s = set_flag "Solver" s solver solver_list
|
||||||
|
|
||||||
(* Input Parsing *)
|
|
||||||
let rec rev_flat_map f acc = function
|
|
||||||
| [] -> acc
|
|
||||||
| a :: r -> rev_flat_map f (List.rev_append (f a) acc) r
|
|
||||||
|
|
||||||
let format_of_filename s =
|
|
||||||
let last n =
|
|
||||||
try String.sub s (String.length s - n) n
|
|
||||||
with Invalid_argument _ -> ""
|
|
||||||
in
|
|
||||||
if last 4 = ".cnf" then
|
|
||||||
Dimacs
|
|
||||||
else if last 5 = ".smt2" then
|
|
||||||
Smtlib
|
|
||||||
else (* Default choice *)
|
|
||||||
Dimacs
|
|
||||||
|
|
||||||
let parse_with_input file = function
|
|
||||||
| Auto -> assert false
|
|
||||||
| Dimacs -> List.rev_map (List.rev_map F.mk_prop) (Parsedimacs.parse file)
|
|
||||||
| Smtlib -> rev_flat_map T.make_cnf [] (Smtlib.parse file)
|
|
||||||
|
|
||||||
let parse_input file =
|
|
||||||
parse_with_input file (match !input with
|
|
||||||
| Auto -> format_of_filename file
|
|
||||||
| f -> f)
|
|
||||||
|
|
||||||
(* Printing wrappers *)
|
|
||||||
let std = Format.std_formatter
|
|
||||||
|
|
||||||
let print format = match !output with
|
|
||||||
| Standard ->
|
|
||||||
Format.kfprintf (fun fmt -> Format.fprintf fmt "@.") std format
|
|
||||||
| Dot ->
|
|
||||||
Format.fprintf std "/* ";
|
|
||||||
Format.kfprintf (fun fmt -> Format.fprintf fmt " */@.") std format
|
|
||||||
| Dedukti ->
|
|
||||||
Format.fprintf std "(; ";
|
|
||||||
Format.kfprintf (fun fmt -> Format.fprintf fmt " ;)@.") std format
|
|
||||||
|
|
||||||
let print_proof proof = match !output with
|
|
||||||
| Standard -> ()
|
|
||||||
| Dot -> Smt.print_dot std proof
|
|
||||||
| Dedukti -> Smt.print_dedukti std proof
|
|
||||||
|
|
||||||
let print_mcproof proof = match !output with
|
|
||||||
| Standard -> ()
|
|
||||||
| Dot -> Mcsat.print_dot std proof
|
|
||||||
| Dedukti -> Mcsat.print_dedukti std proof
|
|
||||||
|
|
||||||
let rec print_cl fmt = function
|
|
||||||
| [] -> Format.fprintf fmt "[]"
|
|
||||||
| [a] -> F.print fmt a
|
|
||||||
| a :: ((_ :: _) as r) -> Format.fprintf fmt "%a ∨ %a" F.print a print_cl r
|
|
||||||
|
|
||||||
let print_lcl l =
|
|
||||||
List.iter (fun c -> Format.fprintf std "%a@\n" print_cl c) l
|
|
||||||
|
|
||||||
let print_lclause l =
|
|
||||||
List.iter (fun c -> Format.fprintf std "%a@\n" Smt.print_clause c) l
|
|
||||||
|
|
||||||
let print_mclause l =
|
|
||||||
List.iter (fun c -> Format.fprintf std "%a@\n" Mcsat.print_clause c) l
|
|
||||||
|
|
||||||
let print_cnf cnf = match !output with
|
|
||||||
| Standard -> print_lcl cnf
|
|
||||||
| Dot | Dedukti -> ()
|
|
||||||
|
|
||||||
let print_unsat_core u = match !output with
|
|
||||||
| Standard -> print_lclause u
|
|
||||||
| Dot | Dedukti -> ()
|
|
||||||
|
|
||||||
let print_mc_unsat_core u = match !output with
|
|
||||||
| Standard -> print_mclause u
|
|
||||||
| Dot | Dedukti -> ()
|
|
||||||
|
|
||||||
(* Arguments parsing *)
|
(* Arguments parsing *)
|
||||||
let file = ref ""
|
let file = ref ""
|
||||||
let p_cnf = ref false
|
let p_cnf = ref false
|
||||||
|
|
@ -170,7 +74,7 @@ let int_arg r arg =
|
||||||
| 'd' -> multiplier 86400.
|
| 'd' -> multiplier 86400.
|
||||||
| '0'..'9' -> r := float_of_string arg
|
| '0'..'9' -> r := float_of_string arg
|
||||||
| _ -> raise (Arg.Bad "bad numeric argument")
|
| _ -> raise (Arg.Bad "bad numeric argument")
|
||||||
with Failure "float_of_string" -> raise (Arg.Bad "bad numeric argument")
|
with Failure _ -> raise (Arg.Bad "bad numeric argument")
|
||||||
|
|
||||||
let setup_gc_stat () =
|
let setup_gc_stat () =
|
||||||
at_exit (fun () ->
|
at_exit (fun () ->
|
||||||
|
|
@ -189,12 +93,8 @@ let argspec = Arg.align [
|
||||||
" Build, check and print the proof (if output is set), if unsat";
|
" Build, check and print the proof (if output is set), if unsat";
|
||||||
"-gc", Arg.Unit setup_gc_stat,
|
"-gc", Arg.Unit setup_gc_stat,
|
||||||
" Outputs statistics about the GC";
|
" Outputs statistics about the GC";
|
||||||
"-i", Arg.String set_input,
|
|
||||||
" Sets the input format (default auto)";
|
|
||||||
"-o", Arg.String set_output,
|
|
||||||
" Sets the output format (default none)";
|
|
||||||
"-s", Arg.String set_solver,
|
"-s", Arg.String set_solver,
|
||||||
"{smt,mcsat} Sets the solver to use (default smt)";
|
"{sat,smt,mcsat} Sets the solver to use (default smt)";
|
||||||
"-size", Arg.String (int_arg size_limit),
|
"-size", Arg.String (int_arg size_limit),
|
||||||
"<s>[kMGT] Sets the size limit for the sat solver";
|
"<s>[kMGT] Sets the size limit for the sat solver";
|
||||||
"-time", Arg.String (int_arg time_limit),
|
"-time", Arg.String (int_arg time_limit),
|
||||||
|
|
@ -215,9 +115,6 @@ let check () =
|
||||||
else if s > !size_limit then
|
else if s > !size_limit then
|
||||||
raise Out_of_space
|
raise Out_of_space
|
||||||
|
|
||||||
(* Entry file parsing *)
|
|
||||||
let get_cnf () = parse_input !file
|
|
||||||
|
|
||||||
let main () =
|
let main () =
|
||||||
(* Administrative duties *)
|
(* Administrative duties *)
|
||||||
Arg.parse argspec input_file usage;
|
Arg.parse argspec input_file usage;
|
||||||
|
|
@ -228,6 +125,12 @@ let main () =
|
||||||
let al = Gc.create_alarm check in
|
let al = Gc.create_alarm check in
|
||||||
|
|
||||||
(* Interesting stuff happening *)
|
(* Interesting stuff happening *)
|
||||||
|
let _, _input = P.parse_file !file in
|
||||||
|
Gc.delete_alarm al;
|
||||||
|
()
|
||||||
|
|
||||||
|
(* Old code ...
|
||||||
|
|
||||||
let cnf = get_cnf () in
|
let cnf = get_cnf () in
|
||||||
if !p_cnf then
|
if !p_cnf then
|
||||||
print_cnf cnf;
|
print_cnf cnf;
|
||||||
|
|
@ -257,7 +160,6 @@ let main () =
|
||||||
| Mcsat ->
|
| Mcsat ->
|
||||||
Mcsat.assume cnf;
|
Mcsat.assume cnf;
|
||||||
let res = Mcsat.solve () in
|
let res = Mcsat.solve () in
|
||||||
Gc.delete_alarm al;
|
|
||||||
begin match res with
|
begin match res with
|
||||||
| Mcsat.Sat sat ->
|
| Mcsat.Sat sat ->
|
||||||
let t = Sys.time () in
|
let t = Sys.time () in
|
||||||
|
|
@ -275,18 +177,21 @@ let main () =
|
||||||
print_mc_unsat_core (Mcsat.unsat_core p)
|
print_mc_unsat_core (Mcsat.unsat_core p)
|
||||||
end;
|
end;
|
||||||
print "Unsat (%f/%f)" t (Sys.time () -. t)
|
print "Unsat (%f/%f)" t (Sys.time () -. t)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
try
|
try
|
||||||
main ()
|
main ()
|
||||||
with
|
with
|
||||||
| Incorrect_model ->
|
| Incorrect_model ->
|
||||||
print "Internal error : incorrect *sat* model";
|
Format.printf "Internal error : incorrect *sat* model@.";
|
||||||
exit 4
|
exit 4
|
||||||
| Out_of_time ->
|
| Out_of_time ->
|
||||||
print "Timeout";
|
Format.printf "Timeout@.";
|
||||||
exit 2
|
exit 2
|
||||||
| Out_of_space ->
|
| Out_of_space ->
|
||||||
print "Spaceout";
|
Format.printf "Spaceout@.";
|
||||||
exit 3
|
exit 3
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
open Msat
|
|
||||||
|
|
||||||
module S = Tseitin.Make(Expr)
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
open Msat
|
|
||||||
|
|
||||||
module S : Tseitin.S with type atom = Expr.Formula.t
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
open Msat
|
|
||||||
|
|
||||||
module I = Formula_intf
|
|
||||||
module Term = Term
|
|
||||||
|
|
||||||
exception Invalid_prop
|
|
||||||
|
|
||||||
type term = Term.t
|
|
||||||
|
|
||||||
(* atomic formula
|
|
||||||
|
|
||||||
Prop:
|
|
||||||
- sign of int determines sign of formula
|
|
||||||
- odd numbers --> fresh atoms (for Tseitin CNF)
|
|
||||||
- even numbers --> used for regular int-mapping
|
|
||||||
*)
|
|
||||||
type formula =
|
|
||||||
| Prop of int
|
|
||||||
| Equal of term * term
|
|
||||||
| Distinct of term * term
|
|
||||||
|
|
||||||
type t = formula
|
|
||||||
type proof = unit
|
|
||||||
|
|
||||||
let dummy = Prop 0
|
|
||||||
|
|
||||||
let max_fresh = ref 0
|
|
||||||
|
|
||||||
let fresh () =
|
|
||||||
incr max_fresh;
|
|
||||||
Prop (2 * !max_fresh + 1)
|
|
||||||
|
|
||||||
let mk_prop i =
|
|
||||||
if i <> 0 && i < max_int / 2 then Prop (2 * i)
|
|
||||||
else raise Invalid_prop
|
|
||||||
|
|
||||||
let order_ t1 t2 = if Term.compare t1 t2 > 0 then t2,t1 else t1,t2
|
|
||||||
|
|
||||||
let mk_eq a b =
|
|
||||||
let a, b = order_ a b in
|
|
||||||
Equal (a, b)
|
|
||||||
|
|
||||||
let mk_neq a b =
|
|
||||||
let a, b = order_ a b in
|
|
||||||
Distinct (a, b)
|
|
||||||
|
|
||||||
let mk_true = mk_eq Term.true_ Term.true_
|
|
||||||
let mk_false = mk_eq Term.true_ Term.false_
|
|
||||||
let mk_atom = mk_eq Term.true_
|
|
||||||
let mk_atom_neg = mk_eq Term.false_
|
|
||||||
|
|
||||||
let neg = function
|
|
||||||
| Prop i -> Prop (-i)
|
|
||||||
| Equal (a, b) -> Distinct (a, b)
|
|
||||||
| Distinct (a, b) -> Equal (a, b)
|
|
||||||
|
|
||||||
let norm = function
|
|
||||||
| Prop i -> Prop (abs i), if i < 0 then I.Negated else I.Same_sign
|
|
||||||
| Equal (a, b) -> Equal (a, b), I.Same_sign
|
|
||||||
| Distinct (a, b) -> Equal (a, b), I.Negated
|
|
||||||
|
|
||||||
(* Only used after normalisation, so usual functions should work *)
|
|
||||||
let hash = Hashtbl.hash
|
|
||||||
let equal = (=)
|
|
||||||
let compare = Pervasives.compare
|
|
||||||
|
|
||||||
let print fmt = function
|
|
||||||
| Prop i ->
|
|
||||||
Format.fprintf fmt "%s%s%d"
|
|
||||||
(if i < 0 then "¬ " else "")
|
|
||||||
(if i mod 2 = 0 then "v" else "f") ((abs i) / 2)
|
|
||||||
| Equal (a, b) -> Format.fprintf fmt "(@[=@ %a@ %a@])" Term.print a Term.print b
|
|
||||||
| Distinct (a, b) -> Format.fprintf fmt "(@[!=@ %a@ %a@])" Term.print a Term.print b
|
|
||||||
|
|
||||||
module Formula = struct
|
|
||||||
type t = formula
|
|
||||||
let hash = Hashtbl.hash
|
|
||||||
let equal = (=)
|
|
||||||
let compare = Pervasives.compare
|
|
||||||
let print = print
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
open Msat
|
|
||||||
|
|
||||||
type term = Term.t
|
|
||||||
|
|
||||||
type formula = private
|
|
||||||
| Prop of int (* prop or tseitin atom *)
|
|
||||||
| Equal of term * term
|
|
||||||
| Distinct of term * term
|
|
||||||
|
|
||||||
type t = formula
|
|
||||||
type proof = unit
|
|
||||||
|
|
||||||
include Formula_intf.S with type t := formula and type proof := proof
|
|
||||||
|
|
||||||
val dummy : t
|
|
||||||
|
|
||||||
val fresh : unit -> t
|
|
||||||
|
|
||||||
val mk_prop : int -> t
|
|
||||||
(** [mk_prop i] makes a prop literal from [i], whose sign matters.
|
|
||||||
@raise Invalid_prop if [i=0] or if [i] is too large *)
|
|
||||||
|
|
||||||
val mk_true : t
|
|
||||||
val mk_false : t
|
|
||||||
val mk_atom : term -> t
|
|
||||||
val mk_atom_neg : term -> t
|
|
||||||
val mk_eq : term -> term -> t
|
|
||||||
val mk_neq : term -> term -> t
|
|
||||||
|
|
||||||
module Term = Term
|
|
||||||
module Formula : sig
|
|
||||||
type t = formula
|
|
||||||
val hash : t -> int
|
|
||||||
val equal : t -> t -> bool
|
|
||||||
val compare : t -> t -> int
|
|
||||||
val print : Format.formatter -> t -> unit
|
|
||||||
end
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
S ./
|
|
||||||
S ./smtlib/
|
|
||||||
S ../sat/
|
|
||||||
S ../common/
|
|
||||||
|
|
||||||
B ../_build/
|
|
||||||
B ../_build/util/
|
|
||||||
B ../_build/util/smtlib/
|
|
||||||
B ../_build/sat/
|
|
||||||
B ../_build/smt/
|
|
||||||
B ../_build/common/
|
|
||||||
522
src/util/expr.ml
Normal file
522
src/util/expr.ml
Normal file
|
|
@ -0,0 +1,522 @@
|
||||||
|
(*
|
||||||
|
Base modules that defines the terms used in the prover.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* Type definitions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
(* Private aliases *)
|
||||||
|
type hash = int
|
||||||
|
type index = int
|
||||||
|
|
||||||
|
(* Identifiers, parametrized by the kind of the type of the variable *)
|
||||||
|
type 'ty id = {
|
||||||
|
id_type : 'ty;
|
||||||
|
id_name : string;
|
||||||
|
index : index; (** unique *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Type for first order types *)
|
||||||
|
type ttype = Type
|
||||||
|
|
||||||
|
(* The type of functions *)
|
||||||
|
type 'ty function_descr = {
|
||||||
|
fun_vars : ttype id list; (* prenex forall *)
|
||||||
|
fun_args : 'ty list;
|
||||||
|
fun_ret : 'ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Types *)
|
||||||
|
type ty_descr =
|
||||||
|
| TyVar of ttype id (** Bound variables *)
|
||||||
|
| TyApp of ttype function_descr id * ty list
|
||||||
|
|
||||||
|
and ty = {
|
||||||
|
ty : ty_descr;
|
||||||
|
mutable ty_hash : hash; (** lazy hash *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Terms & formulas *)
|
||||||
|
type term_descr =
|
||||||
|
| Var of ty id
|
||||||
|
| App of ty function_descr id * ty list * term list
|
||||||
|
|
||||||
|
and term = {
|
||||||
|
term : term_descr;
|
||||||
|
t_type : ty;
|
||||||
|
mutable t_hash : hash; (* lazy hash *)
|
||||||
|
}
|
||||||
|
|
||||||
|
type atom_descr =
|
||||||
|
| Pred of term
|
||||||
|
| Equal of term * term
|
||||||
|
|
||||||
|
and atom = {
|
||||||
|
sign : bool;
|
||||||
|
atom : atom_descr;
|
||||||
|
mutable f_hash : hash; (* lazy hash *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Utilities *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
let rec list_cmp ord l1 l2 =
|
||||||
|
match l1, l2 with
|
||||||
|
| [], [] -> 0
|
||||||
|
| [], _ -> -1
|
||||||
|
| _, [] -> 1
|
||||||
|
| x1::l1', x2::l2' ->
|
||||||
|
let c = ord x1 x2 in
|
||||||
|
if c = 0
|
||||||
|
then list_cmp ord l1' l2'
|
||||||
|
else c
|
||||||
|
|
||||||
|
(* Exceptions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
exception Type_mismatch of term * ty * ty
|
||||||
|
exception Bad_arity of ty function_descr id * ty list * term list
|
||||||
|
exception Bad_ty_arity of ttype function_descr id * ty list
|
||||||
|
|
||||||
|
(* Printing functions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Print = struct
|
||||||
|
let rec list f sep fmt = function
|
||||||
|
| [] -> ()
|
||||||
|
| [x] -> f fmt x
|
||||||
|
| x :: ((y :: _) as r) ->
|
||||||
|
Format.fprintf fmt "%a%s" f x sep;
|
||||||
|
list f sep fmt r
|
||||||
|
|
||||||
|
let id fmt v = Format.fprintf fmt "%s" v.id_name
|
||||||
|
let ttype fmt = function Type -> Format.fprintf fmt "Type"
|
||||||
|
|
||||||
|
let rec ty fmt t = match t.ty with
|
||||||
|
| TyVar v -> id fmt v
|
||||||
|
| TyApp (f, []) ->
|
||||||
|
Format.fprintf fmt "%a" id f
|
||||||
|
| TyApp (f, l) ->
|
||||||
|
Format.fprintf fmt "%a(%a)" id f (list ty ", ") l
|
||||||
|
|
||||||
|
let params fmt = function
|
||||||
|
| [] -> ()
|
||||||
|
| l -> Format.fprintf fmt "∀ %a. " (list id ", ") l
|
||||||
|
|
||||||
|
let signature print fmt f =
|
||||||
|
match f.fun_args with
|
||||||
|
| [] -> Format.fprintf fmt "%a%a" params f.fun_vars print f.fun_ret
|
||||||
|
| l -> Format.fprintf fmt "%a%a -> %a" params f.fun_vars
|
||||||
|
(list print " -> ") l print f.fun_ret
|
||||||
|
|
||||||
|
let fun_ty = signature ty
|
||||||
|
let fun_ttype = signature ttype
|
||||||
|
|
||||||
|
let id_type print fmt v = Format.fprintf fmt "%a : %a" id v print v.id_type
|
||||||
|
|
||||||
|
let id_ty = id_type ty
|
||||||
|
let id_ttype = id_type ttype
|
||||||
|
let const_ty = id_type fun_ty
|
||||||
|
let const_ttype = id_type fun_ttype
|
||||||
|
|
||||||
|
let rec term fmt t = match t.term with
|
||||||
|
| Var v -> id fmt v
|
||||||
|
| App (f, [], []) ->
|
||||||
|
Format.fprintf fmt "%a" id f
|
||||||
|
| App (f, [], args) ->
|
||||||
|
Format.fprintf fmt "%a(%a)" id f
|
||||||
|
(list term ", ") args
|
||||||
|
| App (f, tys, args) ->
|
||||||
|
Format.fprintf fmt "%a(%a; %a)" id f
|
||||||
|
(list ty ", ") tys
|
||||||
|
(list term ", ") args
|
||||||
|
|
||||||
|
let atom_aux fmt f =
|
||||||
|
match f.atom with
|
||||||
|
| Equal (a, b) -> Format.fprintf fmt "%a = %a" term a term b
|
||||||
|
| Pred t -> Format.fprintf fmt "%a" term t
|
||||||
|
|
||||||
|
let atom fmt f = Format.fprintf fmt "⟦%a⟧" atom_aux f
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Substitutions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Subst = struct
|
||||||
|
module Mi = Map.Make(struct
|
||||||
|
type t = int * int
|
||||||
|
let compare (a, b) (c, d) = match compare a c with 0 -> compare b d | x -> x
|
||||||
|
end)
|
||||||
|
|
||||||
|
type ('a, 'b) t = ('a * 'b) Mi.t
|
||||||
|
|
||||||
|
(* Usual functions *)
|
||||||
|
let empty = Mi.empty
|
||||||
|
|
||||||
|
let is_empty = Mi.is_empty
|
||||||
|
|
||||||
|
let iter f = Mi.iter (fun _ (key, value) -> f key value)
|
||||||
|
|
||||||
|
let fold f = Mi.fold (fun _ (key, value) acc -> f key value acc)
|
||||||
|
|
||||||
|
let bindings s = Mi.fold (fun _ (key, value) acc -> (key, value) :: acc) s []
|
||||||
|
|
||||||
|
(* Comparisons *)
|
||||||
|
let equal f = Mi.equal (fun (_, value1) (_, value2) -> f value1 value2)
|
||||||
|
let compare f = Mi.compare (fun (_, value1) (_, value2) -> f value1 value2)
|
||||||
|
let hash h s = Mi.fold (fun i (_, value) acc -> Hashtbl.hash (acc, i, h value)) s 1
|
||||||
|
|
||||||
|
let choose m = snd (Mi.choose m)
|
||||||
|
|
||||||
|
(* Iterators *)
|
||||||
|
let exists pred s =
|
||||||
|
try
|
||||||
|
iter (fun m s -> if pred m s then raise Exit) s;
|
||||||
|
false
|
||||||
|
with Exit ->
|
||||||
|
true
|
||||||
|
|
||||||
|
let for_all pred s =
|
||||||
|
try
|
||||||
|
iter (fun m s -> if not (pred m s) then raise Exit) s;
|
||||||
|
true
|
||||||
|
with Exit ->
|
||||||
|
false
|
||||||
|
|
||||||
|
let print print_key print_value fmt map =
|
||||||
|
let aux _ (key, value) =
|
||||||
|
Format.fprintf fmt "%a -> %a@ " print_key key print_value value
|
||||||
|
in
|
||||||
|
Format.fprintf fmt "@[<hov 0>%a@]" (fun _ -> Mi.iter aux) map
|
||||||
|
|
||||||
|
module type S = sig
|
||||||
|
type 'a key
|
||||||
|
val get : 'a key -> ('a key, 'b) t -> 'b
|
||||||
|
val mem : 'a key -> ('a key, 'b) t -> bool
|
||||||
|
val bind : 'a key -> 'b -> ('a key, 'b) t -> ('a key, 'b) t
|
||||||
|
val remove : 'a key -> ('a key, 'b) t -> ('a key, 'b) t
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Variable substitutions *)
|
||||||
|
module Id = struct
|
||||||
|
type 'a key = 'a id
|
||||||
|
let tok v = (v.index, 0)
|
||||||
|
let get v s = snd (Mi.find (tok v) s)
|
||||||
|
let mem v s = Mi.mem (tok v) s
|
||||||
|
let bind v t s = Mi.add (tok v) (v, t) s
|
||||||
|
let remove v s = Mi.remove (tok v) s
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Dummies *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Dummy = struct
|
||||||
|
|
||||||
|
let id_ttype =
|
||||||
|
{ index = -1; id_name = "<dummy>"; id_type = Type; }
|
||||||
|
|
||||||
|
let ty =
|
||||||
|
{ ty = TyVar id_ttype; ty_hash = -1; }
|
||||||
|
|
||||||
|
let id =
|
||||||
|
{ index = -2; id_name = "<dummy>"; id_type = ty; }
|
||||||
|
|
||||||
|
let term =
|
||||||
|
{ term = Var id; t_type = ty; t_hash = -1; }
|
||||||
|
|
||||||
|
let atom =
|
||||||
|
{ atom = Pred term; sign = true; f_hash = -1; }
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Variables *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Id = struct
|
||||||
|
type 'a t = 'a id
|
||||||
|
|
||||||
|
(* Hash & comparisons *)
|
||||||
|
let hash v = v.index
|
||||||
|
|
||||||
|
let compare: 'a. 'a id -> 'a id -> int =
|
||||||
|
fun v1 v2 -> compare v1.index v2.index
|
||||||
|
|
||||||
|
let equal v1 v2 = compare v1 v2 = 0
|
||||||
|
|
||||||
|
(* Printing functions *)
|
||||||
|
let print = Print.id
|
||||||
|
|
||||||
|
(* Id count *)
|
||||||
|
let _count = ref 0
|
||||||
|
|
||||||
|
(* Constructors *)
|
||||||
|
let mk_new id_name id_type =
|
||||||
|
incr _count;
|
||||||
|
let index = !_count in
|
||||||
|
{ index; id_name; id_type }
|
||||||
|
|
||||||
|
let ttype name = mk_new name Type
|
||||||
|
let ty name ty = mk_new name ty
|
||||||
|
|
||||||
|
let const name fun_vars fun_args fun_ret =
|
||||||
|
mk_new name { fun_vars; fun_args; fun_ret; }
|
||||||
|
|
||||||
|
let ty_fun name n =
|
||||||
|
let rec replicate acc n =
|
||||||
|
if n <= 0 then acc
|
||||||
|
else replicate (Type :: acc) (n - 1)
|
||||||
|
in
|
||||||
|
const name [] (replicate [] n) Type
|
||||||
|
|
||||||
|
let term_fun = const
|
||||||
|
|
||||||
|
(* Builtin Types *)
|
||||||
|
let prop = ty_fun "Prop" 0
|
||||||
|
let base = ty_fun "$i" 0
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Types *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Ty = struct
|
||||||
|
type t = ty
|
||||||
|
type subst = (ttype id, ty) Subst.t
|
||||||
|
|
||||||
|
(* Hash & Comparisons *)
|
||||||
|
let rec hash_aux t = match t.ty with
|
||||||
|
| TyVar v -> Id.hash v
|
||||||
|
| TyApp (f, args) ->
|
||||||
|
Hashtbl.hash (Id.hash f, List.map hash args)
|
||||||
|
|
||||||
|
and hash t =
|
||||||
|
if t.ty_hash = -1 then
|
||||||
|
t.ty_hash <- hash_aux t;
|
||||||
|
t.ty_hash
|
||||||
|
|
||||||
|
let discr ty = match ty.ty with
|
||||||
|
| TyVar _ -> 1
|
||||||
|
| TyApp _ -> 2
|
||||||
|
|
||||||
|
let rec compare u v =
|
||||||
|
let hu = hash u and hv = hash v in
|
||||||
|
if hu <> hv then Pervasives.compare hu hv
|
||||||
|
else match u.ty, v.ty with
|
||||||
|
| TyVar v1, TyVar v2 -> Id.compare v1 v2
|
||||||
|
| TyApp (f1, args1), TyApp (f2, args2) ->
|
||||||
|
begin match Id.compare f1 f2 with
|
||||||
|
| 0 -> list_cmp compare args1 args2
|
||||||
|
| x -> x
|
||||||
|
end
|
||||||
|
| _, _ -> Pervasives.compare (discr u) (discr v)
|
||||||
|
|
||||||
|
let equal u v =
|
||||||
|
u == v || (hash u = hash v && compare u v = 0)
|
||||||
|
|
||||||
|
(* Printing functions *)
|
||||||
|
let print = Print.ty
|
||||||
|
|
||||||
|
(* Constructors *)
|
||||||
|
let mk_ty ty = { ty; ty_hash = -1; }
|
||||||
|
|
||||||
|
let of_id v = mk_ty (TyVar v)
|
||||||
|
|
||||||
|
let apply f args =
|
||||||
|
assert (f.id_type.fun_vars = []);
|
||||||
|
if List.length args <> List.length f.id_type.fun_args then
|
||||||
|
raise (Bad_ty_arity (f, args))
|
||||||
|
else
|
||||||
|
mk_ty (TyApp (f, args))
|
||||||
|
|
||||||
|
(* Builtin types *)
|
||||||
|
let prop = apply Id.prop []
|
||||||
|
let base = apply Id.base []
|
||||||
|
|
||||||
|
(* Substitutions *)
|
||||||
|
let rec subst_aux map t = match t.ty with
|
||||||
|
| TyVar v -> begin try Subst.Id.get v map with Not_found -> t end
|
||||||
|
| TyApp (f, args) ->
|
||||||
|
let new_args = List.map (subst_aux map) args in
|
||||||
|
if List.for_all2 (==) args new_args then t
|
||||||
|
else apply f new_args
|
||||||
|
|
||||||
|
let subst map t = if Subst.is_empty map then t else subst_aux map t
|
||||||
|
|
||||||
|
(* Typechecking *)
|
||||||
|
let instantiate f tys args =
|
||||||
|
if List.length f.id_type.fun_vars <> List.length tys ||
|
||||||
|
List.length f.id_type.fun_args <> List.length args then
|
||||||
|
raise (Bad_arity (f, tys, args))
|
||||||
|
else
|
||||||
|
let map = List.fold_left2 (fun acc v ty -> Subst.Id.bind v ty acc) Subst.empty f.id_type.fun_vars tys in
|
||||||
|
let fun_args = List.map (subst map) f.id_type.fun_args in
|
||||||
|
List.iter2 (fun t ty ->
|
||||||
|
if not (equal t.t_type ty) then raise (Type_mismatch (t, t.t_type, ty)))
|
||||||
|
args fun_args;
|
||||||
|
subst map f.id_type.fun_ret
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Terms *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Term = struct
|
||||||
|
type t = term
|
||||||
|
type subst = (ty id, term) Subst.t
|
||||||
|
|
||||||
|
(* Hash & Comparisons *)
|
||||||
|
let rec hash_aux t = match t.term with
|
||||||
|
| Var v -> Id.hash v
|
||||||
|
| App (f, tys, args) ->
|
||||||
|
let l = List.map Ty.hash tys in
|
||||||
|
let l' = List.map hash args in
|
||||||
|
Hashtbl.hash (Id.hash f, l, l')
|
||||||
|
|
||||||
|
and hash t =
|
||||||
|
if t.t_hash = -1 then
|
||||||
|
t.t_hash <- hash_aux t;
|
||||||
|
t.t_hash
|
||||||
|
|
||||||
|
let discr t = match t.term with
|
||||||
|
| Var _ -> 1
|
||||||
|
| App _ -> 2
|
||||||
|
|
||||||
|
let rec compare u v =
|
||||||
|
let hu = hash u and hv = hash v in
|
||||||
|
if hu <> hv then Pervasives.compare hu hv
|
||||||
|
else match u.term, v.term with
|
||||||
|
| Var v1, Var v2 -> Id.compare v1 v2
|
||||||
|
| App (f1, tys1, args1), App (f2, tys2, args2) ->
|
||||||
|
begin match Id.compare f1 f2 with
|
||||||
|
| 0 ->
|
||||||
|
begin match list_cmp Ty.compare tys1 tys2 with
|
||||||
|
| 0 -> list_cmp compare args1 args2
|
||||||
|
| x -> x
|
||||||
|
end
|
||||||
|
| x -> x
|
||||||
|
end
|
||||||
|
| _, _ -> Pervasives.compare (discr u) (discr v)
|
||||||
|
|
||||||
|
let equal u v =
|
||||||
|
u == v || (hash u = hash v && compare u v = 0)
|
||||||
|
|
||||||
|
(* Printing functions *)
|
||||||
|
let print = Print.term
|
||||||
|
|
||||||
|
(* Constructors *)
|
||||||
|
let mk_term term t_type =
|
||||||
|
{ term; t_type; t_hash = -1; }
|
||||||
|
|
||||||
|
let of_id v =
|
||||||
|
mk_term (Var v) v.id_type
|
||||||
|
|
||||||
|
let apply f ty_args t_args =
|
||||||
|
mk_term (App (f, ty_args, t_args)) (Ty.instantiate f ty_args t_args)
|
||||||
|
|
||||||
|
(* Substitutions *)
|
||||||
|
let rec subst_aux ty_map t_map t = match t.term with
|
||||||
|
| Var v -> begin try Subst.Id.get v t_map with Not_found -> t end
|
||||||
|
| App (f, tys, args) ->
|
||||||
|
let new_tys = List.map (Ty.subst ty_map) tys in
|
||||||
|
let new_args = List.map (subst_aux ty_map t_map) args in
|
||||||
|
if List.for_all2 (==) new_tys tys && List.for_all2 (==) new_args args then t
|
||||||
|
else apply f new_tys new_args
|
||||||
|
|
||||||
|
let subst ty_map t_map t =
|
||||||
|
if Subst.is_empty ty_map && Subst.is_empty t_map then
|
||||||
|
t
|
||||||
|
else
|
||||||
|
subst_aux ty_map t_map t
|
||||||
|
|
||||||
|
let rec replace (t, t') t'' = match t''.term with
|
||||||
|
| _ when equal t t'' -> t'
|
||||||
|
| App (f, ty_args, t_args) ->
|
||||||
|
apply f ty_args (List.map (replace (t, t')) t_args)
|
||||||
|
| _ -> t''
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Formulas *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Atom = struct
|
||||||
|
type t = atom
|
||||||
|
|
||||||
|
type proof = unit
|
||||||
|
|
||||||
|
(* Hash & Comparisons *)
|
||||||
|
let h_eq = 2
|
||||||
|
let h_pred = 3
|
||||||
|
|
||||||
|
let rec hash_aux f = match f.atom with
|
||||||
|
| Equal (t1, t2) ->
|
||||||
|
Hashtbl.hash (h_eq, Term.hash t1, Term.hash t2)
|
||||||
|
| Pred t ->
|
||||||
|
Hashtbl.hash (h_pred, Term.hash t)
|
||||||
|
|
||||||
|
and hash f =
|
||||||
|
if f.f_hash = -1 then
|
||||||
|
f.f_hash <- hash_aux f;
|
||||||
|
f.f_hash
|
||||||
|
|
||||||
|
let discr f = match f.atom with
|
||||||
|
| Equal _ -> 1
|
||||||
|
| Pred _ -> 2
|
||||||
|
|
||||||
|
let compare f g =
|
||||||
|
let hf = hash f and hg = hash g in
|
||||||
|
if hf <> hg then Pervasives.compare hf hg
|
||||||
|
else match f.atom, g.atom with
|
||||||
|
| Equal (u1, v1), Equal(u2, v2) ->
|
||||||
|
list_cmp Term.compare [u1; v1] [u2; v2]
|
||||||
|
| Pred t1, Pred t2 -> Term.compare t1 t2
|
||||||
|
| _, _ -> Pervasives.compare (discr f) (discr g)
|
||||||
|
|
||||||
|
let equal u v =
|
||||||
|
u == v || (hash u = hash v && compare u v = 0)
|
||||||
|
|
||||||
|
(* Printing functions *)
|
||||||
|
let print = Print.atom
|
||||||
|
|
||||||
|
(* Constructors *)
|
||||||
|
let mk_formula f = {
|
||||||
|
sign = true;
|
||||||
|
atom = f;
|
||||||
|
f_hash = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dummy = Dummy.atom
|
||||||
|
|
||||||
|
let pred t =
|
||||||
|
if not (Ty.equal Ty.prop t.t_type) then
|
||||||
|
raise (Type_mismatch (t, t.t_type, Ty.prop))
|
||||||
|
else
|
||||||
|
mk_formula (Pred t)
|
||||||
|
|
||||||
|
let fresh () =
|
||||||
|
let id = Id.ty "fresh" Ty.prop in
|
||||||
|
pred (Term.of_id id)
|
||||||
|
|
||||||
|
let neg f =
|
||||||
|
{ f with sign = not f.sign }
|
||||||
|
|
||||||
|
let eq a b =
|
||||||
|
if not (Ty.equal a.t_type b.t_type) then
|
||||||
|
raise (Type_mismatch (b, b.t_type, a.t_type))
|
||||||
|
else if Term.compare a b < 0 then
|
||||||
|
mk_formula (Equal (a, b))
|
||||||
|
else
|
||||||
|
mk_formula (Equal (b, a))
|
||||||
|
|
||||||
|
let norm f =
|
||||||
|
{ f with sign = true },
|
||||||
|
if f.sign then Msat.Formula_intf.Same_sign
|
||||||
|
else Msat.Formula_intf.Negated
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Formula = Msat.Tseitin.Make(Atom)
|
||||||
|
|
||||||
319
src/util/expr.mli
Normal file
319
src/util/expr.mli
Normal file
|
|
@ -0,0 +1,319 @@
|
||||||
|
|
||||||
|
(** Expressions for TabSat *)
|
||||||
|
|
||||||
|
(** {2 Type definitions} *)
|
||||||
|
|
||||||
|
(** These are custom types used in functions later. *)
|
||||||
|
|
||||||
|
(** {3 Identifiers} *)
|
||||||
|
|
||||||
|
(** Identifiers are the basic building blocks used to build types terms and expressions. *)
|
||||||
|
|
||||||
|
type hash
|
||||||
|
type index = private int
|
||||||
|
|
||||||
|
(** Private aliases to provide access. You should not have any need
|
||||||
|
to use these, instead use the functions provided by this module. *)
|
||||||
|
|
||||||
|
type 'ty id = private {
|
||||||
|
id_type : 'ty;
|
||||||
|
id_name : string;
|
||||||
|
index : index; (** unique *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(** The type of identifiers. An ['a id] is an identifier whose solver-type
|
||||||
|
is represented by an inhabitant of type ['a].
|
||||||
|
All identifier have an unique [index] which is used for comparison,
|
||||||
|
so that the name of a variable is only there for tracability
|
||||||
|
and/or pretty-printing. *)
|
||||||
|
|
||||||
|
(** {3 Types} *)
|
||||||
|
|
||||||
|
type ttype = Type
|
||||||
|
|
||||||
|
(** The caml type of solver-types. *)
|
||||||
|
|
||||||
|
type 'ty function_descr = private {
|
||||||
|
fun_vars : ttype id list; (* prenex forall *)
|
||||||
|
fun_args : 'ty list;
|
||||||
|
fun_ret : 'ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
(** This represents the solver-type of a function.
|
||||||
|
Functions can be polymorphic in the variables described in the
|
||||||
|
[fun_vars] field. *)
|
||||||
|
|
||||||
|
type ty_descr = private
|
||||||
|
| TyVar of ttype id
|
||||||
|
(** bound variables (i.e should only appear under a quantifier) *)
|
||||||
|
| TyApp of ttype function_descr id * ty list
|
||||||
|
(** application of a constant to some arguments *)
|
||||||
|
|
||||||
|
and ty = private {
|
||||||
|
ty : ty_descr;
|
||||||
|
mutable ty_hash : hash; (** Use Ty.hash instead *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(** These types defines solver-types, i.e the representation of the types
|
||||||
|
of terms in the solver. Record definition for [type ty] is shown in order
|
||||||
|
to be able to use the [ty.ty] field in patter matches. Other fields shoud not
|
||||||
|
be accessed directly, but throught the functions provided by the [Ty] module. *)
|
||||||
|
|
||||||
|
(** {3 Terms} *)
|
||||||
|
|
||||||
|
type term_descr = private
|
||||||
|
| Var of ty id
|
||||||
|
(** bound variables (i.e should only appear under a quantifier) *)
|
||||||
|
| App of ty function_descr id * ty list * term list
|
||||||
|
(** application of a constant to some arguments *)
|
||||||
|
|
||||||
|
and term = private {
|
||||||
|
term : term_descr;
|
||||||
|
t_type : ty;
|
||||||
|
mutable t_hash : hash; (** Do not use this filed, call Term.hash instead *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(** Types defining terms in the solver. The definition is vary similar to that
|
||||||
|
of solver-types, except for type arguments of polymorphic functions which
|
||||||
|
are explicit. This has the advantage that there is a clear and typed distinction
|
||||||
|
between solver-types and terms, but may lead to some duplication of code
|
||||||
|
in some places. *)
|
||||||
|
|
||||||
|
(** {3 Formulas} *)
|
||||||
|
|
||||||
|
type atom_descr = private
|
||||||
|
(** Atoms *)
|
||||||
|
| Pred of term
|
||||||
|
| Equal of term * term
|
||||||
|
|
||||||
|
and atom = private {
|
||||||
|
sign : bool;
|
||||||
|
atom : atom_descr;
|
||||||
|
mutable f_hash : hash; (** Use Formula.hash instead *)
|
||||||
|
}
|
||||||
|
|
||||||
|
(** The type of atoms in the solver. The list of free arguments in quantifiers
|
||||||
|
is a bit tricky, so you should not touch it (see full doc for further
|
||||||
|
explanations). *)
|
||||||
|
|
||||||
|
(** {3 Exceptions} *)
|
||||||
|
|
||||||
|
exception Type_mismatch of term * ty * ty
|
||||||
|
(* Raised when as Type_mismatch(term, actual_type, expected_type) *)
|
||||||
|
|
||||||
|
exception Bad_arity of ty function_descr id * ty list * term list
|
||||||
|
exception Bad_ty_arity of ttype function_descr id * ty list
|
||||||
|
(** Raised when trying to build an application with wrong arity *)
|
||||||
|
|
||||||
|
(** {2 Printing} *)
|
||||||
|
|
||||||
|
module Print : sig
|
||||||
|
(** Pretty printing functions *)
|
||||||
|
|
||||||
|
val id : Format.formatter -> 'a id -> unit
|
||||||
|
val id_ty : Format.formatter -> ty id -> unit
|
||||||
|
val id_ttype : Format.formatter -> ttype id -> unit
|
||||||
|
|
||||||
|
val const_ty : Format.formatter -> ty function_descr id -> unit
|
||||||
|
val const_ttype : Format.formatter -> ttype function_descr id -> unit
|
||||||
|
|
||||||
|
val ty : Format.formatter -> ty -> unit
|
||||||
|
val fun_ty : Format.formatter -> ty function_descr -> unit
|
||||||
|
|
||||||
|
val ttype : Format.formatter -> ttype -> unit
|
||||||
|
val fun_ttype : Format.formatter -> ttype function_descr -> unit
|
||||||
|
|
||||||
|
val term : Format.formatter -> term -> unit
|
||||||
|
val atom : Format.formatter -> atom -> unit
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {2 Identifiers & Metas} *)
|
||||||
|
|
||||||
|
module Id : sig
|
||||||
|
type 'a t = 'a id
|
||||||
|
(* Type alias *)
|
||||||
|
|
||||||
|
val hash : 'a t -> int
|
||||||
|
val equal : 'a t -> 'a t -> bool
|
||||||
|
val compare : 'a t -> 'a t -> int
|
||||||
|
(** Usual functions for hash/comparison *)
|
||||||
|
|
||||||
|
val print : Format.formatter -> 'a t -> unit
|
||||||
|
(** Printing for variables *)
|
||||||
|
|
||||||
|
val prop : ttype function_descr id
|
||||||
|
val base : ttype function_descr id
|
||||||
|
(** Constants representing the type for propositions and a default type
|
||||||
|
for term, respectively. *)
|
||||||
|
|
||||||
|
val ttype : string -> ttype id
|
||||||
|
(** Create a fresh type variable with the given name. *)
|
||||||
|
|
||||||
|
val ty : string -> ty -> ty id
|
||||||
|
(** Create a fresh variable with given name and type *)
|
||||||
|
|
||||||
|
val ty_fun : string -> int -> ttype function_descr id
|
||||||
|
(** Create a fresh type constructor with given name and arity *)
|
||||||
|
|
||||||
|
val term_fun : string -> ttype id list -> ty list -> ty -> ty function_descr id
|
||||||
|
(** [ty_fun name type_vars arg_types return_type] returns a fresh constant symbol,
|
||||||
|
possibly polymorphic with respect to the variables in [type_vars] (which may appear in the
|
||||||
|
types in [arg_types] and in [return_type]). *)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {2 Substitutions} *)
|
||||||
|
|
||||||
|
module Subst : sig
|
||||||
|
(** Module to handle substitutions *)
|
||||||
|
|
||||||
|
type ('a, 'b) t
|
||||||
|
(** The type of substitutions from values of type ['a] to values of type ['b]. *)
|
||||||
|
|
||||||
|
val empty : ('a, 'b) t
|
||||||
|
(** The empty substitution *)
|
||||||
|
|
||||||
|
val is_empty : ('a, 'b) t -> bool
|
||||||
|
(** Test wether a substitution is empty *)
|
||||||
|
|
||||||
|
val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit
|
||||||
|
(** Iterates over the bindings of the substitution. *)
|
||||||
|
|
||||||
|
val fold : ('a -> 'b -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c
|
||||||
|
(** Fold over the elements *)
|
||||||
|
|
||||||
|
val bindings : ('a, 'b) t -> ('a * 'b) list
|
||||||
|
(** Returns the list of bindings ofa substitution. *)
|
||||||
|
|
||||||
|
val exists : ('a -> 'b -> bool) -> ('a, 'b) t -> bool
|
||||||
|
(** Tests wether the predicate holds for at least one binding. *)
|
||||||
|
|
||||||
|
val for_all : ('a -> 'b -> bool) -> ('a, 'b) t -> bool
|
||||||
|
(** Tests wether the predicate holds for all bindings. *)
|
||||||
|
|
||||||
|
val hash : ('b -> int) -> ('a, 'b) t -> int
|
||||||
|
val compare : ('b -> 'b -> int) -> ('a, 'b) t -> ('a, 'b) t -> int
|
||||||
|
val equal : ('b -> 'b -> bool) -> ('a, 'b) t -> ('a, 'b) t -> bool
|
||||||
|
(** Comparison and hash functions, with a comparison/hash function on values as parameter *)
|
||||||
|
|
||||||
|
val print :
|
||||||
|
(Format.formatter -> 'a -> unit) ->
|
||||||
|
(Format.formatter -> 'b -> unit) ->
|
||||||
|
Format.formatter -> ('a, 'b) t -> unit
|
||||||
|
(** Prints the substitution, using the given functions to print keys and values. *)
|
||||||
|
|
||||||
|
val choose : ('a, 'b) t -> 'a * 'b
|
||||||
|
(** Return one binding of the given substitution, or raise Not_found if the substitution is empty.*)
|
||||||
|
|
||||||
|
(** {5 Concrete subtitutions } *)
|
||||||
|
module type S = sig
|
||||||
|
type 'a key
|
||||||
|
val get : 'a key -> ('a key, 'b) t -> 'b
|
||||||
|
(** [get v subst] returns the value associated with [v] in [subst], if it exists.
|
||||||
|
@raise Not_found if there is no binding for [v]. *)
|
||||||
|
val mem : 'a key -> ('a key, 'b) t -> bool
|
||||||
|
(** [get v subst] returns wether there is a value associated with [v] in [subst]. *)
|
||||||
|
val bind : 'a key -> 'b -> ('a key, 'b) t -> ('a key, 'b) t
|
||||||
|
(** [bind v t subst] returns the same substitution as [subst] with the additional binding from [v] to [t].
|
||||||
|
Erases the previous binding of [v] if it exists. *)
|
||||||
|
val remove : 'a key -> ('a key, 'b) t -> ('a key, 'b) t
|
||||||
|
(** [remove v subst] returns the same substitution as [subst] except for [v] which is unbound in the returned substitution. *)
|
||||||
|
end
|
||||||
|
|
||||||
|
module Id : S with type 'a key = 'a id
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {2 Types} *)
|
||||||
|
|
||||||
|
module Ty : sig
|
||||||
|
type t = ty
|
||||||
|
(** Type alias *)
|
||||||
|
|
||||||
|
type subst = (ttype id, ty) Subst.t
|
||||||
|
(** The type of substitutions over types. *)
|
||||||
|
|
||||||
|
val hash : t -> int
|
||||||
|
val equal : t -> t -> bool
|
||||||
|
val compare : t -> t -> int
|
||||||
|
(** Usual hash/compare functions *)
|
||||||
|
|
||||||
|
val print : Format.formatter -> t -> unit
|
||||||
|
|
||||||
|
val prop : ty
|
||||||
|
val base : ty
|
||||||
|
(** The type of propositions and individuals *)
|
||||||
|
|
||||||
|
val of_id : ttype id -> ty
|
||||||
|
(** Creates a type from a variable *)
|
||||||
|
|
||||||
|
val apply : ttype function_descr id -> ty list -> ty
|
||||||
|
(** Applies a constant to a list of types *)
|
||||||
|
|
||||||
|
val subst : subst -> ty -> ty
|
||||||
|
(** Substitution over types. *)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {2 Terms} *)
|
||||||
|
|
||||||
|
module Term : sig
|
||||||
|
type t = term
|
||||||
|
(** Type alias *)
|
||||||
|
|
||||||
|
type subst = (ty id, term) Subst.t
|
||||||
|
(** The type of substitutions in types. *)
|
||||||
|
|
||||||
|
val hash : t -> int
|
||||||
|
val equal : t -> t -> bool
|
||||||
|
val compare : t -> t -> int
|
||||||
|
(** Usual hash/compare functions *)
|
||||||
|
|
||||||
|
val print : Format.formatter -> t -> unit
|
||||||
|
(** Printing functions *)
|
||||||
|
|
||||||
|
val of_id : ty id -> term
|
||||||
|
(** Create a term from a variable *)
|
||||||
|
|
||||||
|
val apply : ty function_descr id -> ty list -> term list -> term
|
||||||
|
(** Applies a constant function to type arguments, then term arguments *)
|
||||||
|
|
||||||
|
val subst : Ty.subst -> subst -> term -> term
|
||||||
|
(** Substitution over types. *)
|
||||||
|
|
||||||
|
val replace : term * term -> term -> term
|
||||||
|
(** [replace (t, t') t''] returns the term [t''] where every occurence of [t]
|
||||||
|
has been replace by [t']. *)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {2 Formulas} *)
|
||||||
|
|
||||||
|
module Atom : sig
|
||||||
|
type t = atom
|
||||||
|
(** Type alias *)
|
||||||
|
|
||||||
|
val hash : t -> int
|
||||||
|
val equal : t -> t -> bool
|
||||||
|
val compare : t -> t -> int
|
||||||
|
(** Usual hash/compare functions *)
|
||||||
|
|
||||||
|
val print : Format.formatter -> t -> unit
|
||||||
|
(** Printing functions *)
|
||||||
|
|
||||||
|
val eq : term -> term -> atom
|
||||||
|
(** Create an equality over two terms. The two given terms
|
||||||
|
must have the same type [t], which must be different from {!Ty.prop} *)
|
||||||
|
|
||||||
|
val pred : term -> atom
|
||||||
|
(** Create a atom from a term. The given term must have type {!Ty.prop} *)
|
||||||
|
|
||||||
|
val neg : atom -> atom
|
||||||
|
(** Returns the negation of the given atom *)
|
||||||
|
|
||||||
|
val norm : atom -> atom * Msat.Formula_intf.negated
|
||||||
|
(** Normalization functions as required by msat. *)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Formula : Msat.Tseitin.S with type atom = atom
|
||||||
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
exception Syntax_error of int
|
|
||||||
|
|
||||||
type line =
|
|
||||||
| Empty
|
|
||||||
| Comment
|
|
||||||
| Pcnf of int * int
|
|
||||||
| Clause of int list
|
|
||||||
|
|
||||||
let rec _read_word s acc i len =
|
|
||||||
assert (len>0);
|
|
||||||
if i+len=String.length s
|
|
||||||
then String.sub s i len :: acc
|
|
||||||
else match s.[i+len] with
|
|
||||||
| ' ' | '\t' ->
|
|
||||||
let acc = String.sub s i len :: acc in
|
|
||||||
_skip_space s acc (i+len+1)
|
|
||||||
| _ -> _read_word s acc i (len+1)
|
|
||||||
|
|
||||||
and _skip_space s acc i =
|
|
||||||
if i=String.length s
|
|
||||||
then acc
|
|
||||||
else match s.[i] with
|
|
||||||
| ' ' | '\t' -> _skip_space s acc (i+1)
|
|
||||||
| _ -> _read_word s acc i 1
|
|
||||||
|
|
||||||
let ssplit s = List.rev (_skip_space s [] 0)
|
|
||||||
|
|
||||||
let of_input f =
|
|
||||||
match ssplit (input_line f) with
|
|
||||||
| [] -> Empty
|
|
||||||
| "c" :: _ -> Comment
|
|
||||||
| "p" :: "cnf" :: i :: j :: [] ->
|
|
||||||
begin try
|
|
||||||
Pcnf (int_of_string i, int_of_string j)
|
|
||||||
with Failure _ ->
|
|
||||||
raise (Syntax_error (-1))
|
|
||||||
end
|
|
||||||
| l ->
|
|
||||||
begin try
|
|
||||||
begin match List.rev_map int_of_string l with
|
|
||||||
| 0 :: r -> Clause r
|
|
||||||
| _ -> raise (Syntax_error (-1))
|
|
||||||
end
|
|
||||||
with Failure _ -> raise (Syntax_error (-1))
|
|
||||||
end
|
|
||||||
|
|
||||||
let parse_with todo file =
|
|
||||||
let f = open_in file in
|
|
||||||
let line = ref 0 in
|
|
||||||
try
|
|
||||||
while true do
|
|
||||||
incr line;
|
|
||||||
todo (of_input f)
|
|
||||||
done
|
|
||||||
with
|
|
||||||
| Syntax_error _ ->
|
|
||||||
raise (Syntax_error !line)
|
|
||||||
| End_of_file ->
|
|
||||||
close_in f
|
|
||||||
|
|
||||||
let cnf = ref []
|
|
||||||
let parse_line = function
|
|
||||||
| Empty | Comment | Pcnf _ -> ()
|
|
||||||
| Clause l -> cnf := l :: !cnf
|
|
||||||
|
|
||||||
let parse f =
|
|
||||||
cnf := [];
|
|
||||||
parse_with parse_line f;
|
|
||||||
!cnf
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
exception Syntax_error of int
|
|
||||||
|
|
||||||
val parse : string -> int list list
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
S ./
|
|
||||||
S ../
|
|
||||||
S ../../sat/
|
|
||||||
|
|
||||||
B ../../_build/
|
|
||||||
B ../../_build/util/
|
|
||||||
B ../../_build/util/smtlib/
|
|
||||||
B ../../_build/sat/
|
|
||||||
B ../../_build/smt/
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
(* Copyright 2014 INIA *)
|
|
||||||
|
|
||||||
val token : Lexing.lexbuf -> Parsesmtlib.token
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
{
|
|
||||||
(* auto-generated by gt *)
|
|
||||||
|
|
||||||
open Parsesmtlib;;
|
|
||||||
}
|
|
||||||
|
|
||||||
rule token = parse
|
|
||||||
| ['\t' ' ' ]+ { token lexbuf }
|
|
||||||
| ';' (_ # '\n')* { token lexbuf }
|
|
||||||
| ['\n']+ as str { Smtlib_util.line := (!Smtlib_util.line + (String.length str)); token lexbuf }
|
|
||||||
| "_" { UNDERSCORE }
|
|
||||||
| "(" { LPAREN }
|
|
||||||
| ")" { RPAREN }
|
|
||||||
| "as" { AS }
|
|
||||||
| "let" { LET }
|
|
||||||
| "forall" { FORALL }
|
|
||||||
| "exists" { EXISTS }
|
|
||||||
| "!" { EXCLIMATIONPT }
|
|
||||||
| "set-logic" { SETLOGIC }
|
|
||||||
| "set-option" { SETOPTION }
|
|
||||||
| "set-info" { SETINFO }
|
|
||||||
| "declare-sort" { DECLARESORT }
|
|
||||||
| "define-sort" { DEFINESORT }
|
|
||||||
| "declare-fun" { DECLAREFUN }
|
|
||||||
| "define-fun" { DEFINEFUN }
|
|
||||||
| "push" { PUSH }
|
|
||||||
| "pop" { POP }
|
|
||||||
| "assert" { ASSERT }
|
|
||||||
| "check-sat" { CHECKSAT }
|
|
||||||
| "get-assertions" { GETASSERT }
|
|
||||||
| "get-proof" { GETPROOF }
|
|
||||||
| "get-unsat-core" { GETUNSATCORE }
|
|
||||||
| "get-value" { GETVALUE }
|
|
||||||
| "get-assignment" { GETASSIGN }
|
|
||||||
| "get-option" { GETOPTION }
|
|
||||||
| "get-info" { GETINFO }
|
|
||||||
| "exit" { EXIT }
|
|
||||||
| '#' 'x' ['0'-'9' 'A'-'F' 'a'-'f']+ as str { HEXADECIMAL(str) }
|
|
||||||
| '#' 'b' ['0'-'1']+ as str { BINARY(str) }
|
|
||||||
| '|' ([ '!'-'~' ' ' '\n' '\t' '\r'] # ['\\' '|'])* '|' as str { ASCIIWOR(str) }
|
|
||||||
| ':' ['a'-'z' 'A'-'Z' '0'-'9' '+' '-' '/' '*' '=' '%' '?' '!' '.' '$' '_' '~' '&' '^' '<' '>' '@']+ as str { KEYWORD(str) }
|
|
||||||
| ['a'-'z' 'A'-'Z' '+' '-' '/' '*' '=''%' '?' '!' '.' '$' '_' '~' '&' '^' '<' '>' '@'] ['a'-'z' 'A'-'Z' '0'-'9' '+' '-' '/' '*' '=''%' '?' '!' '.' '$' '_' '~' '&' '^' '<' '>' '@']* as str { SYMBOL(str) }
|
|
||||||
| '"' (([ '!'-'~' ' ' '\n' '\t' '\r' ] # ['\\' '"']) | ('\\' ['!'-'~' ' ' '\n' '\t' '\r'] ))* '"' as str { STRINGLIT(str) }
|
|
||||||
| ( '0' | ['1'-'9'] ['0'-'9']* ) as str { NUMERAL(str) }
|
|
||||||
| ( '0' | ['1'-'9'] ['0'-'9']* ) '.' ['0'-'9']+ as str { DECIMAL(str) }
|
|
||||||
| eof { EOF }
|
|
||||||
| _ {failwith((Lexing.lexeme lexbuf) ^
|
|
||||||
": lexing error on line "^(string_of_int !Smtlib_util.line))}{}
|
|
||||||
|
|
@ -1,330 +0,0 @@
|
||||||
%{
|
|
||||||
(* auto-generated by gt *)
|
|
||||||
|
|
||||||
open Smtlib_syntax;;
|
|
||||||
let parse_error s =
|
|
||||||
print_string s;
|
|
||||||
print_string " on line ";
|
|
||||||
print_int !Smtlib_util.line;
|
|
||||||
print_string "\n";;
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%start main
|
|
||||||
|
|
||||||
%token EOF AS ASSERT CHECKSAT DECLAREFUN DECLARESORT DEFINEFUN DEFINESORT EXCLIMATIONPT EXISTS EXIT FORALL GETASSERT GETASSIGN GETINFO GETOPTION GETPROOF GETUNSATCORE GETVALUE LET LPAREN POP PUSH RPAREN SETINFO SETLOGIC SETOPTION UNDERSCORE
|
|
||||||
%token <string> ASCIIWOR BINARY DECIMAL HEXADECIMAL KEYWORD NUMERAL STRINGLIT SYMBOL
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commands option> main
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.an_option> an_option
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.attribute> attribute
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.attributevalsexpr_attributevalue_sexpr5> attributevalsexpr_attributevalue_sexpr5
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.attributevalue> attributevalue
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.command> command
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commanddeclarefun_command_sort13> commanddeclarefun_command_sort13
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commanddefinefun_command_sortedvar15> commanddefinefun_command_sortedvar15
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commanddefinesort_command_symbol11> commanddefinesort_command_symbol11
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commandgetvalue_command_term24> commandgetvalue_command_term24
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commands> commands
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.commands_commands_command30> commands_commands_command30
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.identifier> identifier
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.idunderscoresymnum_identifier_numeral33> idunderscoresymnum_identifier_numeral33
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.infoflag> infoflag
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.qualidentifier> qualidentifier
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.sexpr> sexpr
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.sexprinparen_sexpr_sexpr41> sexprinparen_sexpr_sexpr41
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.sort> sort
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.sortedvar> sortedvar
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.sortidsortmulti_sort_sort44> sortidsortmulti_sort_sort44
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.specconstant> specconstant
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.symbol> symbol
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.term> term
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.termexclimationpt_term_attribute64> termexclimationpt_term_attribute64
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.termexiststerm_term_sortedvar62> termexiststerm_term_sortedvar62
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.termforallterm_term_sortedvar60> termforallterm_term_sortedvar60
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.termletterm_term_varbinding58> termletterm_term_varbinding58
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.termqualidterm_term_term56> termqualidterm_term_term56
|
|
||||||
|
|
||||||
%type <Smtlib_syntax.varbinding> varbinding
|
|
||||||
|
|
||||||
%type <Smtlib_util.pd> cur_position
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
main:
|
|
||||||
| commands { Some($1) }
|
|
||||||
| EOF { None }
|
|
||||||
|
|
||||||
cur_position:
|
|
||||||
| { Smtlib_util.cur_pd() }
|
|
||||||
|
|
||||||
an_option:
|
|
||||||
| attribute { AnOptionAttribute(pd_attribute $1, $1) }
|
|
||||||
|
|
||||||
attribute:
|
|
||||||
| cur_position KEYWORD { AttributeKeyword($1, $2) }
|
|
||||||
|
|
||||||
attribute:
|
|
||||||
| cur_position KEYWORD attributevalue { AttributeKeywordValue($1, $2, $3) }
|
|
||||||
|
|
||||||
attributevalue:
|
|
||||||
| specconstant { AttributeValSpecConst(pd_specconstant $1, $1) }
|
|
||||||
|
|
||||||
attributevalue:
|
|
||||||
| symbol { AttributeValSymbol(pd_symbol $1, $1) }
|
|
||||||
|
|
||||||
attributevalue:
|
|
||||||
| cur_position LPAREN attributevalsexpr_attributevalue_sexpr5 RPAREN { AttributeValSexpr($1, $3) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN SETLOGIC symbol RPAREN { CommandSetLogic($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN SETOPTION an_option RPAREN { CommandSetOption($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN SETINFO attribute RPAREN { CommandSetInfo($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN DECLARESORT symbol NUMERAL RPAREN { CommandDeclareSort($1, $4, $5) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN DEFINESORT symbol LPAREN commanddefinesort_command_symbol11 RPAREN sort RPAREN { CommandDefineSort($1, $4, $6, $8) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN DECLAREFUN symbol LPAREN commanddeclarefun_command_sort13 RPAREN sort RPAREN { CommandDeclareFun($1, $4, $6, $8) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN DEFINEFUN symbol LPAREN commanddefinefun_command_sortedvar15 RPAREN sort term RPAREN { CommandDefineFun($1, $4, $6, $8, $9) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN PUSH NUMERAL RPAREN { CommandPush($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN POP NUMERAL RPAREN { CommandPop($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN ASSERT term RPAREN { CommandAssert($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN CHECKSAT RPAREN { CommandCheckSat($1) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETASSERT RPAREN { CommandGetAssert($1) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETPROOF RPAREN { CommandGetProof($1) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETUNSATCORE RPAREN { CommandGetUnsatCore($1) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETVALUE LPAREN commandgetvalue_command_term24 RPAREN RPAREN { CommandGetValue($1, $5) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETASSIGN RPAREN { CommandGetAssign($1) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETOPTION KEYWORD RPAREN { CommandGetOption($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN GETINFO infoflag RPAREN { CommandGetInfo($1, $4) }
|
|
||||||
|
|
||||||
command:
|
|
||||||
| cur_position LPAREN EXIT RPAREN { CommandExit($1) }
|
|
||||||
|
|
||||||
commands:
|
|
||||||
| commands_commands_command30 { Commands(pd_commands_commands_command30 $1, $1) }
|
|
||||||
|
|
||||||
identifier:
|
|
||||||
| symbol { IdSymbol(pd_symbol $1, $1) }
|
|
||||||
|
|
||||||
identifier:
|
|
||||||
| cur_position LPAREN UNDERSCORE symbol idunderscoresymnum_identifier_numeral33 RPAREN { IdUnderscoreSymNum($1, $4, $5) }
|
|
||||||
|
|
||||||
infoflag:
|
|
||||||
| cur_position KEYWORD { InfoFlagKeyword($1, $2) }
|
|
||||||
|
|
||||||
qualidentifier:
|
|
||||||
| identifier { QualIdentifierId(pd_identifier $1, $1) }
|
|
||||||
|
|
||||||
qualidentifier:
|
|
||||||
| cur_position LPAREN AS identifier sort RPAREN { QualIdentifierAs($1, $4, $5) }
|
|
||||||
|
|
||||||
sexpr:
|
|
||||||
| specconstant { SexprSpecConst(pd_specconstant $1, $1) }
|
|
||||||
|
|
||||||
sexpr:
|
|
||||||
| symbol { SexprSymbol(pd_symbol $1, $1) }
|
|
||||||
|
|
||||||
sexpr:
|
|
||||||
| cur_position KEYWORD { SexprKeyword($1, $2) }
|
|
||||||
|
|
||||||
sexpr:
|
|
||||||
| cur_position LPAREN sexprinparen_sexpr_sexpr41 RPAREN { SexprInParen($1, $3) }
|
|
||||||
|
|
||||||
sort:
|
|
||||||
| identifier { SortIdentifier(pd_identifier $1, $1) }
|
|
||||||
|
|
||||||
sort:
|
|
||||||
| cur_position LPAREN identifier sortidsortmulti_sort_sort44 RPAREN { SortIdSortMulti($1, $3, $4) }
|
|
||||||
|
|
||||||
sortedvar:
|
|
||||||
| cur_position LPAREN symbol sort RPAREN { SortedVarSymSort($1, $3, $4) }
|
|
||||||
|
|
||||||
specconstant:
|
|
||||||
| cur_position DECIMAL { SpecConstsDec($1, $2) }
|
|
||||||
|
|
||||||
specconstant:
|
|
||||||
| cur_position NUMERAL { SpecConstNum($1, $2) }
|
|
||||||
|
|
||||||
specconstant:
|
|
||||||
| cur_position STRINGLIT { SpecConstString($1, $2) }
|
|
||||||
|
|
||||||
specconstant:
|
|
||||||
| cur_position HEXADECIMAL { SpecConstsHex($1, $2) }
|
|
||||||
|
|
||||||
specconstant:
|
|
||||||
| cur_position BINARY { SpecConstsBinary($1, $2) }
|
|
||||||
|
|
||||||
symbol:
|
|
||||||
| cur_position SYMBOL { Symbol($1, $2) }
|
|
||||||
|
|
||||||
symbol:
|
|
||||||
| cur_position ASCIIWOR { SymbolWithOr($1, $2) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| specconstant { TermSpecConst(pd_specconstant $1, $1) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| qualidentifier { TermQualIdentifier(pd_qualidentifier $1, $1) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| cur_position LPAREN qualidentifier termqualidterm_term_term56 RPAREN { TermQualIdTerm($1, $3, $4) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| cur_position LPAREN LET LPAREN termletterm_term_varbinding58 RPAREN term RPAREN { TermLetTerm($1, $5, $7) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| cur_position LPAREN FORALL LPAREN termforallterm_term_sortedvar60 RPAREN term RPAREN { TermForAllTerm($1, $5, $7) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| cur_position LPAREN EXISTS LPAREN termexiststerm_term_sortedvar62 RPAREN term RPAREN { TermExistsTerm($1, $5, $7) }
|
|
||||||
|
|
||||||
term:
|
|
||||||
| cur_position LPAREN EXCLIMATIONPT term termexclimationpt_term_attribute64 RPAREN { TermExclimationPt($1, $4, $5) }
|
|
||||||
|
|
||||||
varbinding:
|
|
||||||
| cur_position LPAREN symbol term RPAREN { VarBindingSymTerm($1, $3, $4) }
|
|
||||||
|
|
||||||
termexclimationpt_term_attribute64:
|
|
||||||
| attribute { (pd_attribute $1, ($1)::[]) }
|
|
||||||
|
|
||||||
termexclimationpt_term_attribute64:
|
|
||||||
| attribute termexclimationpt_term_attribute64 { let (p, ( l1 )) = $2 in (pd_attribute $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
termexiststerm_term_sortedvar62:
|
|
||||||
| sortedvar { (pd_sortedvar $1, ($1)::[]) }
|
|
||||||
|
|
||||||
termexiststerm_term_sortedvar62:
|
|
||||||
| sortedvar termexiststerm_term_sortedvar62 { let (p, ( l1 )) = $2 in (pd_sortedvar $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
termforallterm_term_sortedvar60:
|
|
||||||
| sortedvar { (pd_sortedvar $1, ($1)::[]) }
|
|
||||||
|
|
||||||
termforallterm_term_sortedvar60:
|
|
||||||
| sortedvar termforallterm_term_sortedvar60 { let (p, ( l1 )) = $2 in (pd_sortedvar $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
termletterm_term_varbinding58:
|
|
||||||
| varbinding { (pd_varbinding $1, ($1)::[]) }
|
|
||||||
|
|
||||||
termletterm_term_varbinding58:
|
|
||||||
| varbinding termletterm_term_varbinding58 { let (p, ( l1 )) = $2 in (pd_varbinding $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
termqualidterm_term_term56:
|
|
||||||
| term { (pd_term $1, ($1)::[]) }
|
|
||||||
|
|
||||||
termqualidterm_term_term56:
|
|
||||||
| term termqualidterm_term_term56 { let (p, ( l1 )) = $2 in (pd_term $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
sortidsortmulti_sort_sort44:
|
|
||||||
| sort { (pd_sort $1, ($1)::[]) }
|
|
||||||
|
|
||||||
sortidsortmulti_sort_sort44:
|
|
||||||
| sort sortidsortmulti_sort_sort44 { let (p, ( l1 )) = $2 in (pd_sort $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
sexprinparen_sexpr_sexpr41:
|
|
||||||
| cur_position { ($1, []) }
|
|
||||||
|
|
||||||
sexprinparen_sexpr_sexpr41:
|
|
||||||
| sexpr sexprinparen_sexpr_sexpr41 { let (p, ( l1 )) = $2 in (pd_sexpr $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
idunderscoresymnum_identifier_numeral33:
|
|
||||||
| cur_position NUMERAL { ($1, ($2)::[]) }
|
|
||||||
|
|
||||||
idunderscoresymnum_identifier_numeral33:
|
|
||||||
| cur_position NUMERAL idunderscoresymnum_identifier_numeral33 { let (p, ( l1 )) = $3 in ($1, ($2)::(l1)) }
|
|
||||||
|
|
||||||
commands_commands_command30:
|
|
||||||
| cur_position { ($1, []) }
|
|
||||||
|
|
||||||
commands_commands_command30:
|
|
||||||
| command commands_commands_command30 { let (p, ( l1 )) = $2 in (pd_command $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
commandgetvalue_command_term24:
|
|
||||||
| term { (pd_term $1, ($1)::[]) }
|
|
||||||
|
|
||||||
commandgetvalue_command_term24:
|
|
||||||
| term commandgetvalue_command_term24 { let (p, ( l1 )) = $2 in (pd_term $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
commanddefinefun_command_sortedvar15:
|
|
||||||
| cur_position { ($1, []) }
|
|
||||||
|
|
||||||
commanddefinefun_command_sortedvar15:
|
|
||||||
| sortedvar commanddefinefun_command_sortedvar15 { let (p, ( l1 )) = $2 in (pd_sortedvar $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
commanddeclarefun_command_sort13:
|
|
||||||
| cur_position { ($1, []) }
|
|
||||||
|
|
||||||
commanddeclarefun_command_sort13:
|
|
||||||
| sort commanddeclarefun_command_sort13 { let (p, ( l1 )) = $2 in (pd_sort $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
commanddefinesort_command_symbol11:
|
|
||||||
| cur_position { ($1, []) }
|
|
||||||
|
|
||||||
commanddefinesort_command_symbol11:
|
|
||||||
| symbol commanddefinesort_command_symbol11 { let (p, ( l1 )) = $2 in (pd_symbol $1, ($1)::(l1)) }
|
|
||||||
|
|
||||||
attributevalsexpr_attributevalue_sexpr5:
|
|
||||||
| cur_position { ($1, []) }
|
|
||||||
|
|
||||||
attributevalsexpr_attributevalue_sexpr5:
|
|
||||||
| sexpr attributevalsexpr_attributevalue_sexpr5 { let (p, ( l1 )) = $2 in (pd_sexpr $1, ($1)::(l1)) }
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
open Smtlib_syntax
|
|
||||||
|
|
||||||
module F = Expr
|
|
||||||
module T = Cnf.S
|
|
||||||
|
|
||||||
exception Bad_arity of string
|
|
||||||
exception Unknown_command
|
|
||||||
exception Incomplete_translation
|
|
||||||
|
|
||||||
(* Environment *)
|
|
||||||
let env : (string, T.t) Hashtbl.t = Hashtbl.create 57;;
|
|
||||||
Hashtbl.add env "true" T.f_true;;
|
|
||||||
Hashtbl.add env "false" T.f_false;;
|
|
||||||
|
|
||||||
let get_atom s =
|
|
||||||
try
|
|
||||||
Hashtbl.find env s
|
|
||||||
with Not_found ->
|
|
||||||
let f = T.make_atom (F.fresh ()) in
|
|
||||||
Hashtbl.add env s f;
|
|
||||||
f
|
|
||||||
|
|
||||||
(* Term translation *)
|
|
||||||
let translate_const = function
|
|
||||||
| SpecConstsDec(_, s)
|
|
||||||
| SpecConstNum(_, s)
|
|
||||||
| SpecConstString(_, s)
|
|
||||||
| SpecConstsHex(_, s)
|
|
||||||
| SpecConstsBinary(_, s) -> s
|
|
||||||
|
|
||||||
let translate_symbol = function
|
|
||||||
| Symbol(_, s)
|
|
||||||
| SymbolWithOr(_, s) -> s
|
|
||||||
|
|
||||||
let translate_id = function
|
|
||||||
| IdSymbol(_, s) -> translate_symbol s
|
|
||||||
| IdUnderscoreSymNum(_, s, n) -> raise Incomplete_translation
|
|
||||||
|
|
||||||
let translate_qualid = function
|
|
||||||
| QualIdentifierId(_, id) -> translate_id id
|
|
||||||
| QualIdentifierAs(_, id, s) -> raise Incomplete_translation
|
|
||||||
|
|
||||||
let left_assoc s f = function
|
|
||||||
| x :: r -> List.fold_left f x r
|
|
||||||
| _ -> raise (Bad_arity s)
|
|
||||||
|
|
||||||
let rec right_assoc s f = function
|
|
||||||
| [] -> raise (Bad_arity s)
|
|
||||||
| [x] -> x
|
|
||||||
| x :: r -> f x (right_assoc s f r)
|
|
||||||
|
|
||||||
let translate_atom = function
|
|
||||||
| TermSpecConst(_, const) -> translate_const const
|
|
||||||
| TermQualIdentifier(_, id) -> translate_qualid id
|
|
||||||
| _ -> raise Incomplete_translation
|
|
||||||
|
|
||||||
let rec translate_term = function
|
|
||||||
| TermQualIdTerm(_, f, (_, l)) ->
|
|
||||||
begin match (translate_qualid f) with
|
|
||||||
| "=" ->
|
|
||||||
begin match (List.map translate_atom l) with
|
|
||||||
| [a; b] -> T.make_atom (F.mk_eq a b)
|
|
||||||
| _ -> assert false
|
|
||||||
end
|
|
||||||
| s ->
|
|
||||||
begin match s, (List.map translate_term l) with
|
|
||||||
(* CORE theory translation - 'distinct','ite' not yet implemented *)
|
|
||||||
| "not", [e] -> T.make_not e
|
|
||||||
| "not", _ -> raise (Bad_arity "not")
|
|
||||||
| "and", l -> T.make_and l
|
|
||||||
| "or", l -> T.make_or l
|
|
||||||
| "xor" as s, l -> left_assoc s T.make_xor l
|
|
||||||
| "=>" as s, l -> right_assoc s T.make_imply l
|
|
||||||
| _ ->
|
|
||||||
Format.printf "unknown : %s@." s;
|
|
||||||
raise Unknown_command
|
|
||||||
end
|
|
||||||
end
|
|
||||||
| e -> (get_atom (translate_atom e))
|
|
||||||
|
|
||||||
(* Command Translation *)
|
|
||||||
let translate_command = function
|
|
||||||
| CommandDeclareFun(_, s, (_, []), _) ->
|
|
||||||
None
|
|
||||||
| CommandAssert(_, t) ->
|
|
||||||
Some (translate_term t)
|
|
||||||
| _ -> None
|
|
||||||
|
|
||||||
let rec translate_command_list acc = function
|
|
||||||
| [] -> acc
|
|
||||||
| c :: r ->
|
|
||||||
begin match translate_command c with
|
|
||||||
| None -> translate_command_list acc r
|
|
||||||
| Some t -> translate_command_list (t :: acc) r
|
|
||||||
end
|
|
||||||
|
|
||||||
let translate = function
|
|
||||||
| Some Commands (_, (_, l)) -> List.rev (translate_command_list [] l)
|
|
||||||
| None -> []
|
|
||||||
|
|
||||||
let parse file =
|
|
||||||
let f = open_in file in
|
|
||||||
let lexbuf = Lexing.from_channel f in
|
|
||||||
let commands = Parsesmtlib.main Lexsmtlib.token lexbuf in
|
|
||||||
close_in f;
|
|
||||||
translate commands
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
val parse : string -> Cnf.S.t list
|
|
||||||
|
|
@ -1,229 +0,0 @@
|
||||||
(* auto-generated by gt *)
|
|
||||||
|
|
||||||
open Smtlib_util;;
|
|
||||||
|
|
||||||
type dummy = Dummy
|
|
||||||
and an_option = | AnOptionAttribute of pd * attribute
|
|
||||||
and attribute = | AttributeKeyword of pd * string | AttributeKeywordValue of pd * string * attributevalue
|
|
||||||
and attributevalue = | AttributeValSpecConst of pd * specconstant | AttributeValSymbol of pd * symbol | AttributeValSexpr of pd * attributevalsexpr_attributevalue_sexpr5
|
|
||||||
and command = | CommandSetLogic of pd * symbol | CommandSetOption of pd * an_option | CommandSetInfo of pd * attribute | CommandDeclareSort of pd * symbol * string | CommandDefineSort of pd * symbol * commanddefinesort_command_symbol11 * sort | CommandDeclareFun of pd * symbol * commanddeclarefun_command_sort13 * sort | CommandDefineFun of pd * symbol * commanddefinefun_command_sortedvar15 * sort * term | CommandPush of pd * string | CommandPop of pd * string | CommandAssert of pd * term | CommandCheckSat of pd | CommandGetAssert of pd | CommandGetProof of pd | CommandGetUnsatCore of pd | CommandGetValue of pd * commandgetvalue_command_term24 | CommandGetAssign of pd | CommandGetOption of pd * string | CommandGetInfo of pd * infoflag | CommandExit of pd
|
|
||||||
and commands = | Commands of pd * commands_commands_command30
|
|
||||||
and identifier = | IdSymbol of pd * symbol | IdUnderscoreSymNum of pd * symbol * idunderscoresymnum_identifier_numeral33
|
|
||||||
and infoflag = | InfoFlagKeyword of pd * string
|
|
||||||
and qualidentifier = | QualIdentifierId of pd * identifier | QualIdentifierAs of pd * identifier * sort
|
|
||||||
and sexpr = | SexprSpecConst of pd * specconstant | SexprSymbol of pd * symbol | SexprKeyword of pd * string | SexprInParen of pd * sexprinparen_sexpr_sexpr41
|
|
||||||
and sort = | SortIdentifier of pd * identifier | SortIdSortMulti of pd * identifier * sortidsortmulti_sort_sort44
|
|
||||||
and sortedvar = | SortedVarSymSort of pd * symbol * sort
|
|
||||||
and specconstant = | SpecConstsDec of pd * string | SpecConstNum of pd * string | SpecConstString of pd * string | SpecConstsHex of pd * string | SpecConstsBinary of pd * string
|
|
||||||
and symbol = | Symbol of pd * string | SymbolWithOr of pd * string
|
|
||||||
and term = | TermSpecConst of pd * specconstant | TermQualIdentifier of pd * qualidentifier | TermQualIdTerm of pd * qualidentifier * termqualidterm_term_term56 | TermLetTerm of pd * termletterm_term_varbinding58 * term | TermForAllTerm of pd * termforallterm_term_sortedvar60 * term | TermExistsTerm of pd * termexiststerm_term_sortedvar62 * term | TermExclimationPt of pd * term * termexclimationpt_term_attribute64
|
|
||||||
and varbinding = | VarBindingSymTerm of pd * symbol * term
|
|
||||||
and termexclimationpt_term_attribute64 = pd * ( attribute) list
|
|
||||||
and termexiststerm_term_sortedvar62 = pd * ( sortedvar) list
|
|
||||||
and termforallterm_term_sortedvar60 = pd * ( sortedvar) list
|
|
||||||
and termletterm_term_varbinding58 = pd * ( varbinding) list
|
|
||||||
and termqualidterm_term_term56 = pd * ( term) list
|
|
||||||
and sortidsortmulti_sort_sort44 = pd * ( sort) list
|
|
||||||
and sexprinparen_sexpr_sexpr41 = pd * ( sexpr) list
|
|
||||||
and idunderscoresymnum_identifier_numeral33 = pd * ( string) list
|
|
||||||
and commands_commands_command30 = pd * ( command) list
|
|
||||||
and commandgetvalue_command_term24 = pd * ( term) list
|
|
||||||
and commanddefinefun_command_sortedvar15 = pd * ( sortedvar) list
|
|
||||||
and commanddeclarefun_command_sort13 = pd * ( sort) list
|
|
||||||
and commanddefinesort_command_symbol11 = pd * ( symbol) list
|
|
||||||
and attributevalsexpr_attributevalue_sexpr5 = pd * ( sexpr) list;;
|
|
||||||
|
|
||||||
(* pd stands for pos (position) and extradata *)
|
|
||||||
let dummy () = ()
|
|
||||||
and pd_an_option = function
|
|
||||||
| AnOptionAttribute(d,_) -> d
|
|
||||||
|
|
||||||
and pd_attribute = function
|
|
||||||
| AttributeKeyword(d,_) -> d
|
|
||||||
|
|
||||||
| AttributeKeywordValue(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_attributevalue = function
|
|
||||||
| AttributeValSpecConst(d,_) -> d
|
|
||||||
|
|
||||||
| AttributeValSymbol(d,_) -> d
|
|
||||||
|
|
||||||
| AttributeValSexpr(d,_) -> d
|
|
||||||
|
|
||||||
and pd_command = function
|
|
||||||
| CommandSetLogic(d,_) -> d
|
|
||||||
|
|
||||||
| CommandSetOption(d,_) -> d
|
|
||||||
|
|
||||||
| CommandSetInfo(d,_) -> d
|
|
||||||
|
|
||||||
| CommandDeclareSort(d,_,_) -> d
|
|
||||||
|
|
||||||
| CommandDefineSort(d,_,_,_) -> d
|
|
||||||
|
|
||||||
| CommandDeclareFun(d,_,_,_) -> d
|
|
||||||
|
|
||||||
| CommandDefineFun(d,_,_,_,_) -> d
|
|
||||||
|
|
||||||
| CommandPush(d,_) -> d
|
|
||||||
|
|
||||||
| CommandPop(d,_) -> d
|
|
||||||
|
|
||||||
| CommandAssert(d,_) -> d
|
|
||||||
|
|
||||||
| CommandCheckSat(d) -> d
|
|
||||||
|
|
||||||
| CommandGetAssert(d) -> d
|
|
||||||
|
|
||||||
| CommandGetProof(d) -> d
|
|
||||||
|
|
||||||
| CommandGetUnsatCore(d) -> d
|
|
||||||
|
|
||||||
| CommandGetValue(d,_) -> d
|
|
||||||
|
|
||||||
| CommandGetAssign(d) -> d
|
|
||||||
|
|
||||||
| CommandGetOption(d,_) -> d
|
|
||||||
|
|
||||||
| CommandGetInfo(d,_) -> d
|
|
||||||
|
|
||||||
| CommandExit(d) -> d
|
|
||||||
|
|
||||||
and pd_commands = function
|
|
||||||
| Commands(d,_) -> d
|
|
||||||
|
|
||||||
and pd_identifier = function
|
|
||||||
| IdSymbol(d,_) -> d
|
|
||||||
|
|
||||||
| IdUnderscoreSymNum(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_infoflag = function
|
|
||||||
| InfoFlagKeyword(d,_) -> d
|
|
||||||
|
|
||||||
and pd_qualidentifier = function
|
|
||||||
| QualIdentifierId(d,_) -> d
|
|
||||||
|
|
||||||
| QualIdentifierAs(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_sexpr = function
|
|
||||||
| SexprSpecConst(d,_) -> d
|
|
||||||
|
|
||||||
| SexprSymbol(d,_) -> d
|
|
||||||
|
|
||||||
| SexprKeyword(d,_) -> d
|
|
||||||
|
|
||||||
| SexprInParen(d,_) -> d
|
|
||||||
|
|
||||||
and pd_sort = function
|
|
||||||
| SortIdentifier(d,_) -> d
|
|
||||||
|
|
||||||
| SortIdSortMulti(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_sortedvar = function
|
|
||||||
| SortedVarSymSort(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_specconstant = function
|
|
||||||
| SpecConstsDec(d,_) -> d
|
|
||||||
|
|
||||||
| SpecConstNum(d,_) -> d
|
|
||||||
|
|
||||||
| SpecConstString(d,_) -> d
|
|
||||||
|
|
||||||
| SpecConstsHex(d,_) -> d
|
|
||||||
|
|
||||||
| SpecConstsBinary(d,_) -> d
|
|
||||||
|
|
||||||
and pd_symbol = function
|
|
||||||
| Symbol(d,_) -> d
|
|
||||||
|
|
||||||
| SymbolWithOr(d,_) -> d
|
|
||||||
|
|
||||||
and pd_term = function
|
|
||||||
| TermSpecConst(d,_) -> d
|
|
||||||
|
|
||||||
| TermQualIdentifier(d,_) -> d
|
|
||||||
|
|
||||||
| TermQualIdTerm(d,_,_) -> d
|
|
||||||
|
|
||||||
| TermLetTerm(d,_,_) -> d
|
|
||||||
|
|
||||||
| TermForAllTerm(d,_,_) -> d
|
|
||||||
|
|
||||||
| TermExistsTerm(d,_,_) -> d
|
|
||||||
|
|
||||||
| TermExclimationPt(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_varbinding = function
|
|
||||||
| VarBindingSymTerm(d,_,_) -> d
|
|
||||||
|
|
||||||
and pd_termexclimationpt_term_attribute64 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_termexiststerm_term_sortedvar62 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_termforallterm_term_sortedvar60 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_termletterm_term_varbinding58 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_termqualidterm_term_term56 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_sortidsortmulti_sort_sort44 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_sexprinparen_sexpr_sexpr41 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_idunderscoresymnum_identifier_numeral33 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_commands_commands_command30 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_commandgetvalue_command_term24 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_commanddefinefun_command_sortedvar15 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_commanddeclarefun_command_sort13 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_commanddefinesort_command_symbol11 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
|
|
||||||
and pd_attributevalsexpr_attributevalue_sexpr5 = function
|
|
||||||
| (d,[]) -> d
|
|
||||||
|
|
||||||
| (d,( _ )::f1239o2) -> d
|
|
||||||
;;
|
|
||||||
let pd e = pd_commands e;;
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
type dummy = Dummy
|
|
||||||
and an_option = AnOptionAttribute of Smtlib_util.pd * attribute
|
|
||||||
and attribute =
|
|
||||||
AttributeKeyword of Smtlib_util.pd * string
|
|
||||||
| AttributeKeywordValue of Smtlib_util.pd * string * attributevalue
|
|
||||||
and attributevalue =
|
|
||||||
AttributeValSpecConst of Smtlib_util.pd * specconstant
|
|
||||||
| AttributeValSymbol of Smtlib_util.pd * symbol
|
|
||||||
| AttributeValSexpr of Smtlib_util.pd *
|
|
||||||
attributevalsexpr_attributevalue_sexpr5
|
|
||||||
and command =
|
|
||||||
CommandSetLogic of Smtlib_util.pd * symbol
|
|
||||||
| CommandSetOption of Smtlib_util.pd * an_option
|
|
||||||
| CommandSetInfo of Smtlib_util.pd * attribute
|
|
||||||
| CommandDeclareSort of Smtlib_util.pd * symbol * string
|
|
||||||
| CommandDefineSort of Smtlib_util.pd * symbol *
|
|
||||||
commanddefinesort_command_symbol11 * sort
|
|
||||||
| CommandDeclareFun of Smtlib_util.pd * symbol *
|
|
||||||
commanddeclarefun_command_sort13 * sort
|
|
||||||
| CommandDefineFun of Smtlib_util.pd * symbol *
|
|
||||||
commanddefinefun_command_sortedvar15 * sort * term
|
|
||||||
| CommandPush of Smtlib_util.pd * string
|
|
||||||
| CommandPop of Smtlib_util.pd * string
|
|
||||||
| CommandAssert of Smtlib_util.pd * term
|
|
||||||
| CommandCheckSat of Smtlib_util.pd
|
|
||||||
| CommandGetAssert of Smtlib_util.pd
|
|
||||||
| CommandGetProof of Smtlib_util.pd
|
|
||||||
| CommandGetUnsatCore of Smtlib_util.pd
|
|
||||||
| CommandGetValue of Smtlib_util.pd * commandgetvalue_command_term24
|
|
||||||
| CommandGetAssign of Smtlib_util.pd
|
|
||||||
| CommandGetOption of Smtlib_util.pd * string
|
|
||||||
| CommandGetInfo of Smtlib_util.pd * infoflag
|
|
||||||
| CommandExit of Smtlib_util.pd
|
|
||||||
and commands = Commands of Smtlib_util.pd * commands_commands_command30
|
|
||||||
and identifier =
|
|
||||||
IdSymbol of Smtlib_util.pd * symbol
|
|
||||||
| IdUnderscoreSymNum of Smtlib_util.pd * symbol *
|
|
||||||
idunderscoresymnum_identifier_numeral33
|
|
||||||
and infoflag = InfoFlagKeyword of Smtlib_util.pd * string
|
|
||||||
and qualidentifier =
|
|
||||||
QualIdentifierId of Smtlib_util.pd * identifier
|
|
||||||
| QualIdentifierAs of Smtlib_util.pd * identifier * sort
|
|
||||||
and sexpr =
|
|
||||||
SexprSpecConst of Smtlib_util.pd * specconstant
|
|
||||||
| SexprSymbol of Smtlib_util.pd * symbol
|
|
||||||
| SexprKeyword of Smtlib_util.pd * string
|
|
||||||
| SexprInParen of Smtlib_util.pd * sexprinparen_sexpr_sexpr41
|
|
||||||
and sort =
|
|
||||||
SortIdentifier of Smtlib_util.pd * identifier
|
|
||||||
| SortIdSortMulti of Smtlib_util.pd * identifier *
|
|
||||||
sortidsortmulti_sort_sort44
|
|
||||||
and sortedvar = SortedVarSymSort of Smtlib_util.pd * symbol * sort
|
|
||||||
and specconstant =
|
|
||||||
SpecConstsDec of Smtlib_util.pd * string
|
|
||||||
| SpecConstNum of Smtlib_util.pd * string
|
|
||||||
| SpecConstString of Smtlib_util.pd * string
|
|
||||||
| SpecConstsHex of Smtlib_util.pd * string
|
|
||||||
| SpecConstsBinary of Smtlib_util.pd * string
|
|
||||||
and symbol =
|
|
||||||
Symbol of Smtlib_util.pd * string
|
|
||||||
| SymbolWithOr of Smtlib_util.pd * string
|
|
||||||
and term =
|
|
||||||
TermSpecConst of Smtlib_util.pd * specconstant
|
|
||||||
| TermQualIdentifier of Smtlib_util.pd * qualidentifier
|
|
||||||
| TermQualIdTerm of Smtlib_util.pd * qualidentifier *
|
|
||||||
termqualidterm_term_term56
|
|
||||||
| TermLetTerm of Smtlib_util.pd * termletterm_term_varbinding58 * term
|
|
||||||
| TermForAllTerm of Smtlib_util.pd * termforallterm_term_sortedvar60 * term
|
|
||||||
| TermExistsTerm of Smtlib_util.pd * termexiststerm_term_sortedvar62 * term
|
|
||||||
| TermExclimationPt of Smtlib_util.pd * term *
|
|
||||||
termexclimationpt_term_attribute64
|
|
||||||
and varbinding = VarBindingSymTerm of Smtlib_util.pd * symbol * term
|
|
||||||
and termexclimationpt_term_attribute64 = Smtlib_util.pd * attribute list
|
|
||||||
and termexiststerm_term_sortedvar62 = Smtlib_util.pd * sortedvar list
|
|
||||||
and termforallterm_term_sortedvar60 = Smtlib_util.pd * sortedvar list
|
|
||||||
and termletterm_term_varbinding58 = Smtlib_util.pd * varbinding list
|
|
||||||
and termqualidterm_term_term56 = Smtlib_util.pd * term list
|
|
||||||
and sortidsortmulti_sort_sort44 = Smtlib_util.pd * sort list
|
|
||||||
and sexprinparen_sexpr_sexpr41 = Smtlib_util.pd * sexpr list
|
|
||||||
and idunderscoresymnum_identifier_numeral33 = Smtlib_util.pd * string list
|
|
||||||
and commands_commands_command30 = Smtlib_util.pd * command list
|
|
||||||
and commandgetvalue_command_term24 = Smtlib_util.pd * term list
|
|
||||||
and commanddefinefun_command_sortedvar15 = Smtlib_util.pd * sortedvar list
|
|
||||||
and commanddeclarefun_command_sort13 = Smtlib_util.pd * sort list
|
|
||||||
and commanddefinesort_command_symbol11 = Smtlib_util.pd * symbol list
|
|
||||||
and attributevalsexpr_attributevalue_sexpr5 = Smtlib_util.pd * sexpr list
|
|
||||||
val dummy : unit -> unit
|
|
||||||
val pd_an_option : an_option -> Smtlib_util.pd
|
|
||||||
val pd_attribute : attribute -> Smtlib_util.pd
|
|
||||||
val pd_attributevalue : attributevalue -> Smtlib_util.pd
|
|
||||||
val pd_command : command -> Smtlib_util.pd
|
|
||||||
val pd_commands : commands -> Smtlib_util.pd
|
|
||||||
val pd_identifier : identifier -> Smtlib_util.pd
|
|
||||||
val pd_infoflag : infoflag -> Smtlib_util.pd
|
|
||||||
val pd_qualidentifier : qualidentifier -> Smtlib_util.pd
|
|
||||||
val pd_sexpr : sexpr -> Smtlib_util.pd
|
|
||||||
val pd_sort : sort -> Smtlib_util.pd
|
|
||||||
val pd_sortedvar : sortedvar -> Smtlib_util.pd
|
|
||||||
val pd_specconstant : specconstant -> Smtlib_util.pd
|
|
||||||
val pd_symbol : symbol -> Smtlib_util.pd
|
|
||||||
val pd_term : term -> Smtlib_util.pd
|
|
||||||
val pd_varbinding : varbinding -> Smtlib_util.pd
|
|
||||||
val pd_termexclimationpt_term_attribute64 : 'a * 'b list -> 'a
|
|
||||||
val pd_termexiststerm_term_sortedvar62 : 'a * 'b list -> 'a
|
|
||||||
val pd_termforallterm_term_sortedvar60 : 'a * 'b list -> 'a
|
|
||||||
val pd_termletterm_term_varbinding58 : 'a * 'b list -> 'a
|
|
||||||
val pd_termqualidterm_term_term56 : 'a * 'b list -> 'a
|
|
||||||
val pd_sortidsortmulti_sort_sort44 : 'a * 'b list -> 'a
|
|
||||||
val pd_sexprinparen_sexpr_sexpr41 : 'a * 'b list -> 'a
|
|
||||||
val pd_idunderscoresymnum_identifier_numeral33 : 'a * 'b list -> 'a
|
|
||||||
val pd_commands_commands_command30 : 'a * 'b list -> 'a
|
|
||||||
val pd_commandgetvalue_command_term24 : 'a * 'b list -> 'a
|
|
||||||
val pd_commanddefinefun_command_sortedvar15 : 'a * 'b list -> 'a
|
|
||||||
val pd_commanddeclarefun_command_sort13 : 'a * 'b list -> 'a
|
|
||||||
val pd_commanddefinesort_command_symbol11 : 'a * 'b list -> 'a
|
|
||||||
val pd_attributevalsexpr_attributevalue_sexpr5 : 'a * 'b list -> 'a
|
|
||||||
val pd : commands -> Smtlib_util.pd
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
(* auto-generated by gt *)
|
|
||||||
|
|
||||||
(* no extra data from grammar file. *)
|
|
||||||
type extradata = unit;;
|
|
||||||
let initial_data() = ();;
|
|
||||||
|
|
||||||
let file = ref "stdin";;
|
|
||||||
let line = ref 1;;
|
|
||||||
type pos = int;;
|
|
||||||
let string_of_pos p = "line "^(string_of_int p);;
|
|
||||||
let cur_pd() = (!line, initial_data());; (* "pd": pos + extradata *)
|
|
||||||
type pd = pos * extradata;;
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
(*
|
|
||||||
MSAT is free software, using the Apache license, see file LICENSE
|
|
||||||
Copyright 2014 Guillaume Bury
|
|
||||||
Copyright 2014 Simon Cruanes
|
|
||||||
*)
|
|
||||||
|
|
||||||
type extradata = unit
|
|
||||||
val initial_data : unit -> unit
|
|
||||||
val file : string ref
|
|
||||||
val line : int ref
|
|
||||||
type pos = int
|
|
||||||
val string_of_pos : int -> string
|
|
||||||
val cur_pd : unit -> int * unit
|
|
||||||
type pd = pos * extradata
|
|
||||||
619
src/util/type.ml
Normal file
619
src/util/type.ml
Normal file
|
|
@ -0,0 +1,619 @@
|
||||||
|
|
||||||
|
(* Log&Module Init *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
module Ast = Dolmen.Term
|
||||||
|
module Id = Dolmen.Id
|
||||||
|
module M = Map.Make(Id)
|
||||||
|
module H = Hashtbl.Make(Id)
|
||||||
|
|
||||||
|
(* Types *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
(* The type of potentially expected result type for parsing an expression *)
|
||||||
|
type expect =
|
||||||
|
| Nothing
|
||||||
|
| Type
|
||||||
|
| Typed of Expr.ty
|
||||||
|
|
||||||
|
(* The type returned after parsing an expression. *)
|
||||||
|
type res =
|
||||||
|
| Ttype
|
||||||
|
| Ty of Expr.ty
|
||||||
|
| Term of Expr.term
|
||||||
|
| Formula of Expr.Formula.t
|
||||||
|
|
||||||
|
|
||||||
|
(* The local environments used for type-checking. *)
|
||||||
|
type env = {
|
||||||
|
|
||||||
|
(* local variables (mostly quantified variables) *)
|
||||||
|
type_vars : (Expr.ttype Expr.id) M.t;
|
||||||
|
term_vars : (Expr.ty Expr.id) M.t;
|
||||||
|
|
||||||
|
(* Bound variables (through let constructions) *)
|
||||||
|
term_lets : Expr.term M.t;
|
||||||
|
prop_lets : Expr.Formula.t M.t;
|
||||||
|
|
||||||
|
(* Typing options *)
|
||||||
|
expect : expect;
|
||||||
|
}
|
||||||
|
|
||||||
|
type 'a typer = env -> Dolmen.Term.t -> 'a
|
||||||
|
|
||||||
|
(* Exceptions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
(* Internal exception *)
|
||||||
|
exception Found of Ast.t
|
||||||
|
|
||||||
|
(* Exception for typing errors *)
|
||||||
|
exception Typing_error of string * Ast.t
|
||||||
|
|
||||||
|
(* Convenience functions *)
|
||||||
|
let _expected s t = raise (Typing_error (
|
||||||
|
Format.asprintf "Expected a %s" s, t))
|
||||||
|
let _bad_arity s n t = raise (Typing_error (
|
||||||
|
Format.asprintf "Bad arity for operator '%s' (expected %d arguments)" s n, t))
|
||||||
|
let _type_mismatch t ty ty' ast = raise (Typing_error (
|
||||||
|
Format.asprintf "Type Mismatch: '%a' has type %a, but an expression of type %a was expected"
|
||||||
|
Expr.Print.term t Expr.Print.ty ty Expr.Print.ty ty', ast))
|
||||||
|
let _fo_term s t = raise (Typing_error (
|
||||||
|
Format.asprintf "Let-bound variable '%a' is applied to terms" Id.print s, t))
|
||||||
|
|
||||||
|
(* Global Environment *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
(* Global identifier table; stores declared types and aliases. *)
|
||||||
|
let global_env = H.create 42
|
||||||
|
|
||||||
|
let find_global name =
|
||||||
|
try H.find global_env name
|
||||||
|
with Not_found -> `Not_found
|
||||||
|
|
||||||
|
(* Symbol declarations *)
|
||||||
|
let decl_ty_cstr id c =
|
||||||
|
if H.mem global_env id then
|
||||||
|
Log.debugf 0 "Symbol '%a' has already been defined, overwriting previous definition"
|
||||||
|
(fun k -> k Id.print id);
|
||||||
|
H.add global_env id (`Ty c);
|
||||||
|
Log.debugf 1 "New type constructor : %a" (fun k -> k Expr.Print.const_ttype c)
|
||||||
|
|
||||||
|
let decl_term id c =
|
||||||
|
if H.mem global_env id then
|
||||||
|
Log.debugf 0 "Symbol '%a' has already been defined, overwriting previous definition"
|
||||||
|
(fun k -> k Id.print id);
|
||||||
|
H.add global_env id (`Term c);
|
||||||
|
Log.debugf 1 "New constant : %a" (fun k -> k Expr.Print.const_ty c)
|
||||||
|
|
||||||
|
(* Symbol definitions *)
|
||||||
|
let def_ty id args body =
|
||||||
|
if H.mem global_env id then
|
||||||
|
Log.debugf 0 "Symbol '%a' has already been defined, overwriting previous definition"
|
||||||
|
(fun k -> k Id.print id);
|
||||||
|
H.add global_env id (`Ty_alias (args, body))
|
||||||
|
|
||||||
|
let def_term id ty_args args body =
|
||||||
|
if H.mem global_env id then
|
||||||
|
Log.debugf 0 "Symbol '%a' has already been defined, overwriting previous definition"
|
||||||
|
(fun k -> k Id.print id);
|
||||||
|
H.add global_env id (`Term_alias (ty_args, args, body))
|
||||||
|
|
||||||
|
(* Local Environment *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
(* Make a new empty environment *)
|
||||||
|
let empty_env ?(expect=Nothing) = {
|
||||||
|
type_vars = M.empty;
|
||||||
|
term_vars = M.empty;
|
||||||
|
term_lets = M.empty;
|
||||||
|
prop_lets = M.empty;
|
||||||
|
expect;
|
||||||
|
}
|
||||||
|
|
||||||
|
let expect env expect = { env with expect = expect }
|
||||||
|
|
||||||
|
(* Generate new fresh names for shadowed variables *)
|
||||||
|
let new_name pre =
|
||||||
|
let i = ref 0 in
|
||||||
|
(fun () -> incr i; pre ^ (string_of_int !i))
|
||||||
|
|
||||||
|
let new_ty_name = new_name "ty#"
|
||||||
|
let new_term_name = new_name "term#"
|
||||||
|
|
||||||
|
(* Add local variables to environment *)
|
||||||
|
let add_type_var env id v =
|
||||||
|
let v' =
|
||||||
|
if M.mem id env.type_vars then
|
||||||
|
Expr.Id.ttype (new_ty_name ())
|
||||||
|
else
|
||||||
|
v
|
||||||
|
in
|
||||||
|
Log.debugf 1 "New binding : %a -> %a"
|
||||||
|
(fun k -> k Id.print id Expr.Print.id_ttype v');
|
||||||
|
v', { env with type_vars = M.add id v' env.type_vars }
|
||||||
|
|
||||||
|
let add_type_vars env l =
|
||||||
|
let l', env' = List.fold_left (fun (l, acc) (id, v) ->
|
||||||
|
let v', acc' = add_type_var acc id v in
|
||||||
|
v' :: l, acc') ([], env) l in
|
||||||
|
List.rev l', env'
|
||||||
|
|
||||||
|
let add_term_var env id v =
|
||||||
|
let v' =
|
||||||
|
if M.mem id env.type_vars then
|
||||||
|
Expr.Id.ty (new_term_name ()) Expr.(v.id_type)
|
||||||
|
else
|
||||||
|
v
|
||||||
|
in
|
||||||
|
Log.debugf 1 "New binding : %a -> %a"
|
||||||
|
(fun k -> k Id.print id Expr.Print.id_ty v');
|
||||||
|
v', { env with term_vars = M.add id v' env.term_vars }
|
||||||
|
|
||||||
|
let find_var env name =
|
||||||
|
try `Ty (M.find name env.type_vars)
|
||||||
|
with Not_found ->
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
`Term (M.find name env.term_vars)
|
||||||
|
with Not_found ->
|
||||||
|
`Not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Add local bound variables to env *)
|
||||||
|
let add_let_term env id t =
|
||||||
|
Log.debugf 1 "New let-binding : %s -> %a"
|
||||||
|
(fun k -> k id.Id.name Expr.Print.term t);
|
||||||
|
{ env with term_lets = M.add id t env.term_lets }
|
||||||
|
|
||||||
|
let add_let_prop env id t =
|
||||||
|
Log.debugf 1 "New let-binding : %s -> %a"
|
||||||
|
(fun k -> k id.Id.name Expr.Formula.print t);
|
||||||
|
{ env with prop_lets = M.add id t env.prop_lets }
|
||||||
|
|
||||||
|
let find_let env name =
|
||||||
|
try `Term (M.find name env.term_lets)
|
||||||
|
with Not_found ->
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
`Prop (M.find name env.prop_lets)
|
||||||
|
with Not_found ->
|
||||||
|
`Not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
let pp_expect fmt = function
|
||||||
|
| Nothing -> Format.fprintf fmt "<>"
|
||||||
|
| Type -> Format.fprintf fmt "<tType>"
|
||||||
|
| Typed ty -> Expr.Print.ty fmt ty
|
||||||
|
|
||||||
|
let pp_map pp fmt map =
|
||||||
|
M.iter (fun k v ->
|
||||||
|
Format.fprintf fmt "%s->%a;" k.Id.name pp v) map
|
||||||
|
|
||||||
|
let pp_env fmt env =
|
||||||
|
Format.fprintf fmt "(%a) %a%a%a%a"
|
||||||
|
pp_expect env.expect
|
||||||
|
(pp_map Expr.Print.id_ttype) env.type_vars
|
||||||
|
(pp_map Expr.Print.id_ty) env.term_vars
|
||||||
|
(pp_map Expr.Print.term) env.term_lets
|
||||||
|
(pp_map Expr.Formula.print) env.prop_lets
|
||||||
|
|
||||||
|
(* Some helper functions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
let flat_map f l = List.flatten (List.map f l)
|
||||||
|
|
||||||
|
let take_drop n l =
|
||||||
|
let rec aux acc = function
|
||||||
|
| 0, _ | _, [] -> List.rev acc, []
|
||||||
|
| m, x :: r -> aux (x :: acc) (m - 1, r)
|
||||||
|
in
|
||||||
|
aux [] (n, l)
|
||||||
|
|
||||||
|
let diagonal l =
|
||||||
|
let rec single x acc = function
|
||||||
|
| [] -> acc
|
||||||
|
| y :: r -> single x ((x, y) :: acc) r
|
||||||
|
and aux acc = function
|
||||||
|
| [] -> acc
|
||||||
|
| x :: r -> aux (single x acc r) r
|
||||||
|
in
|
||||||
|
aux [] l
|
||||||
|
|
||||||
|
(* Wrappers for expression building *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
let arity f =
|
||||||
|
List.length Expr.(f.id_type.fun_vars) +
|
||||||
|
List.length Expr.(f.id_type.fun_args)
|
||||||
|
|
||||||
|
let ty_apply env ast f args =
|
||||||
|
try
|
||||||
|
Expr.Ty.apply f args
|
||||||
|
with Expr.Bad_ty_arity _ ->
|
||||||
|
_bad_arity Expr.(f.id_name) (arity f) ast
|
||||||
|
|
||||||
|
let term_apply env ast f ty_args t_args =
|
||||||
|
try
|
||||||
|
Expr.Term.apply f ty_args t_args
|
||||||
|
with
|
||||||
|
| Expr.Bad_arity _ ->
|
||||||
|
_bad_arity Expr.(f.id_name) (arity f) ast
|
||||||
|
| Expr.Type_mismatch (t, ty, ty') ->
|
||||||
|
_type_mismatch t ty ty' ast
|
||||||
|
|
||||||
|
let ty_subst ast_term id args f_args body =
|
||||||
|
let aux s v ty = Expr.Subst.Id.bind v ty s in
|
||||||
|
match List.fold_left2 aux Expr.Subst.empty f_args args with
|
||||||
|
| subst ->
|
||||||
|
Expr.Ty.subst subst body
|
||||||
|
| exception Invalid_argument _ ->
|
||||||
|
_bad_arity id.Id.name (List.length f_args) ast_term
|
||||||
|
|
||||||
|
let term_subst ast_term id ty_args t_args f_ty_args f_t_args body =
|
||||||
|
let aux s v ty = Expr.Subst.Id.bind v ty s in
|
||||||
|
match List.fold_left2 aux Expr.Subst.empty f_ty_args ty_args with
|
||||||
|
| ty_subst ->
|
||||||
|
begin
|
||||||
|
let aux s v t = Expr.Subst.Id.bind v t s in
|
||||||
|
match List.fold_left2 aux Expr.Subst.empty f_t_args t_args with
|
||||||
|
| t_subst ->
|
||||||
|
Expr.Term.subst ty_subst t_subst body
|
||||||
|
| exception Invalid_argument _ ->
|
||||||
|
_bad_arity id.Id.name (List.length f_ty_args + List.length f_t_args) ast_term
|
||||||
|
end
|
||||||
|
| exception Invalid_argument _ ->
|
||||||
|
_bad_arity id.Id.name (List.length f_ty_args + List.length f_t_args) ast_term
|
||||||
|
|
||||||
|
let make_eq ast_term a b =
|
||||||
|
try
|
||||||
|
Expr.Formula.make_atom @@ Expr.Atom.eq a b
|
||||||
|
with Expr.Type_mismatch (t, ty, ty') ->
|
||||||
|
_type_mismatch t ty ty' ast_term
|
||||||
|
|
||||||
|
let make_pred ast_term p =
|
||||||
|
try
|
||||||
|
Expr.Formula.make_atom @@ Expr.Atom.pred p
|
||||||
|
with Expr.Type_mismatch (t, ty, ty') ->
|
||||||
|
_type_mismatch t ty ty' ast_term
|
||||||
|
|
||||||
|
let infer env s args =
|
||||||
|
match env.expect with
|
||||||
|
| Nothing -> `Nothing
|
||||||
|
| Type ->
|
||||||
|
let n = List.length args in
|
||||||
|
let res = Expr.Id.ty_fun s.Id.name n in
|
||||||
|
decl_ty_cstr s res;
|
||||||
|
`Ty res
|
||||||
|
| Typed ty ->
|
||||||
|
let n = List.length args in
|
||||||
|
let rec replicate acc n =
|
||||||
|
if n <= 0 then acc else replicate (Expr.Ty.base :: acc) (n - 1)
|
||||||
|
in
|
||||||
|
let res = Expr.Id.term_fun s.Id.name [] (replicate [] n) ty in
|
||||||
|
decl_term s res;
|
||||||
|
`Term res
|
||||||
|
|
||||||
|
(* Expression parsing *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
let rec parse_expr (env : env) t =
|
||||||
|
match t with
|
||||||
|
|
||||||
|
(* Basic formulas *)
|
||||||
|
| { Ast.term = Ast.App ({ Ast.term = Ast.Builtin Ast.True }, []) }
|
||||||
|
| { Ast.term = Ast.Builtin Ast.True } ->
|
||||||
|
Formula Expr.Formula.f_true
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({ Ast.term = Ast.Builtin Ast.False }, []) }
|
||||||
|
| { Ast.term = Ast.Builtin Ast.False } ->
|
||||||
|
Formula Expr.Formula.f_false
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.And}, l) } ->
|
||||||
|
Formula (Expr.Formula.make_and (List.map (parse_formula env) l))
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Or}, l) } ->
|
||||||
|
Formula (Expr.Formula.make_or (List.map (parse_formula env) l))
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Xor}, l) } as t ->
|
||||||
|
begin match l with
|
||||||
|
| [p; q] ->
|
||||||
|
let f = parse_formula env p in
|
||||||
|
let g = parse_formula env q in
|
||||||
|
Formula (Expr.Formula.make_not (Expr.Formula.make_equiv f g))
|
||||||
|
| _ -> _bad_arity "xor" 2 t
|
||||||
|
end
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Imply}, l) } as t ->
|
||||||
|
begin match l with
|
||||||
|
| [p; q] ->
|
||||||
|
let f = parse_formula env p in
|
||||||
|
let g = parse_formula env q in
|
||||||
|
Formula (Expr.Formula.make_imply f g)
|
||||||
|
| _ -> _bad_arity "=>" 2 t
|
||||||
|
end
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Equiv}, l) } as t ->
|
||||||
|
begin match l with
|
||||||
|
| [p; q] ->
|
||||||
|
let f = parse_formula env p in
|
||||||
|
let g = parse_formula env q in
|
||||||
|
Formula (Expr.Formula.make_equiv f g)
|
||||||
|
| _ -> _bad_arity "<=>" 2 t
|
||||||
|
end
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Not}, l) } as t ->
|
||||||
|
begin match l with
|
||||||
|
| [p] ->
|
||||||
|
Formula (Expr.Formula.make_not (parse_formula env p))
|
||||||
|
| _ -> _bad_arity "not" 1 t
|
||||||
|
end
|
||||||
|
|
||||||
|
(* (Dis)Equality *)
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Eq}, l) } as t ->
|
||||||
|
begin match l with
|
||||||
|
| [a; b] ->
|
||||||
|
Formula (
|
||||||
|
make_eq t
|
||||||
|
(parse_term env a)
|
||||||
|
(parse_term env b)
|
||||||
|
)
|
||||||
|
| _ -> _bad_arity "=" 2 t
|
||||||
|
end
|
||||||
|
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Distinct}, args) } as t ->
|
||||||
|
let l' = List.map (parse_term env) args in
|
||||||
|
let l'' = diagonal l' in
|
||||||
|
Formula (
|
||||||
|
Expr.Formula.make_and
|
||||||
|
(List.map (fun (a, b) ->
|
||||||
|
Expr.Formula.make_not
|
||||||
|
(make_eq t a b)) l'')
|
||||||
|
)
|
||||||
|
|
||||||
|
(* General case: application *)
|
||||||
|
| { Ast.term = Ast.Symbol s } as ast ->
|
||||||
|
parse_app env ast s []
|
||||||
|
| { Ast.term = Ast.App ({ Ast.term = Ast.Symbol s }, l) } as ast ->
|
||||||
|
parse_app env ast s l
|
||||||
|
|
||||||
|
(* Local bindings *)
|
||||||
|
| { Ast.term = Ast.Binder (Ast.Let, vars, f) } ->
|
||||||
|
parse_let env f vars
|
||||||
|
|
||||||
|
(* Other cases *)
|
||||||
|
| ast -> raise (Typing_error ("Couldn't parse the expression", ast))
|
||||||
|
|
||||||
|
and parse_var env = function
|
||||||
|
| { Ast.term = Ast.Colon ({ Ast.term = Ast.Symbol s }, e) } ->
|
||||||
|
begin match parse_expr env e with
|
||||||
|
| Ttype -> `Ty (s, Expr.Id.ttype s.Id.name)
|
||||||
|
| Ty ty -> `Term (s, Expr.Id.ty s.Id.name ty)
|
||||||
|
| _ -> _expected "type (or Ttype)" e
|
||||||
|
end
|
||||||
|
| { Ast.term = Ast.Symbol s } ->
|
||||||
|
begin match env.expect with
|
||||||
|
| Nothing -> assert false
|
||||||
|
| Type -> `Ty (s, Expr.Id.ttype s.Id.name)
|
||||||
|
| Typed ty -> `Term (s, Expr.Id.ty s.Id.name ty)
|
||||||
|
end
|
||||||
|
| t -> _expected "(typed) variable" t
|
||||||
|
|
||||||
|
and parse_quant_vars env l =
|
||||||
|
let ttype_vars, typed_vars, env' = List.fold_left (
|
||||||
|
fun (l1, l2, acc) v ->
|
||||||
|
match parse_var acc v with
|
||||||
|
| `Ty (id, v') ->
|
||||||
|
let v'', acc' = add_type_var acc id v' in
|
||||||
|
(v'' :: l1, l2, acc')
|
||||||
|
| `Term (id, v') ->
|
||||||
|
let v'', acc' = add_term_var acc id v' in
|
||||||
|
(l1, v'' :: l2, acc')
|
||||||
|
) ([], [], env) l in
|
||||||
|
List.rev ttype_vars, List.rev typed_vars, env'
|
||||||
|
|
||||||
|
and parse_let env f = function
|
||||||
|
| [] -> parse_expr env f
|
||||||
|
| x :: r ->
|
||||||
|
begin match x with
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Eq}, [
|
||||||
|
{ Ast.term = Ast.Symbol s }; e]) } ->
|
||||||
|
let t = parse_term env e in
|
||||||
|
let env' = add_let_term env s t in
|
||||||
|
parse_let env' f r
|
||||||
|
| { Ast.term = Ast.App ({Ast.term = Ast.Builtin Ast.Equiv}, [
|
||||||
|
{ Ast.term = Ast.Symbol s }; e]) } ->
|
||||||
|
let t = parse_formula env e in
|
||||||
|
let env' = add_let_prop env s t in
|
||||||
|
parse_let env' f r
|
||||||
|
| { Ast.term = Ast.Colon ({ Ast.term = Ast.Symbol s }, e) } ->
|
||||||
|
begin match parse_expr env e with
|
||||||
|
| Term t ->
|
||||||
|
let env' = add_let_term env s t in
|
||||||
|
parse_let env' f r
|
||||||
|
| Formula t ->
|
||||||
|
let env' = add_let_prop env s t in
|
||||||
|
parse_let env' f r
|
||||||
|
| _ -> _expected "term of formula" e
|
||||||
|
end
|
||||||
|
| t -> _expected "let-binding" t
|
||||||
|
end
|
||||||
|
|
||||||
|
and parse_app env ast s args =
|
||||||
|
match find_let env s with
|
||||||
|
| `Term t ->
|
||||||
|
if args = [] then Term t
|
||||||
|
else _fo_term s ast
|
||||||
|
| `Prop p ->
|
||||||
|
if args = [] then Formula p
|
||||||
|
else _fo_term s ast
|
||||||
|
| `Not_found ->
|
||||||
|
begin match find_var env s with
|
||||||
|
| `Ty f ->
|
||||||
|
if args = [] then Ty (Expr.Ty.of_id f)
|
||||||
|
else _fo_term s ast
|
||||||
|
| `Term f ->
|
||||||
|
if args = [] then Term (Expr.Term.of_id f)
|
||||||
|
else _fo_term s ast
|
||||||
|
| `Not_found ->
|
||||||
|
begin match find_global s with
|
||||||
|
| `Ty f ->
|
||||||
|
parse_app_ty env ast f args
|
||||||
|
| `Term f ->
|
||||||
|
parse_app_term env ast f args
|
||||||
|
| `Ty_alias (f_args, body) ->
|
||||||
|
parse_app_subst_ty env ast s args f_args body
|
||||||
|
| `Term_alias (f_ty_args, f_t_args, body) ->
|
||||||
|
parse_app_subst_term env ast s args f_ty_args f_t_args body
|
||||||
|
| `Not_found ->
|
||||||
|
begin match infer env s args with
|
||||||
|
| `Ty f -> parse_app_ty env ast f args
|
||||||
|
| `Term f -> parse_app_term env ast f args
|
||||||
|
| `Nothing ->
|
||||||
|
raise (Typing_error (
|
||||||
|
Format.asprintf "Scoping error: '%a' not found" Id.print s, ast))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
and parse_app_ty env ast f args =
|
||||||
|
let l = List.map (parse_ty env) args in
|
||||||
|
Ty (ty_apply env ast f l)
|
||||||
|
|
||||||
|
and parse_app_term env ast f args =
|
||||||
|
let n = List.length Expr.(f.id_type.fun_vars) in
|
||||||
|
let ty_l, t_l = take_drop n args in
|
||||||
|
let ty_args = List.map (parse_ty env) ty_l in
|
||||||
|
let t_args = List.map (parse_term env) t_l in
|
||||||
|
Term (term_apply env ast f ty_args t_args)
|
||||||
|
|
||||||
|
and parse_app_subst_ty env ast id args f_args body =
|
||||||
|
let l = List.map (parse_ty env) args in
|
||||||
|
Ty (ty_subst ast id l f_args body)
|
||||||
|
|
||||||
|
and parse_app_subst_term env ast id args f_ty_args f_t_args body =
|
||||||
|
let n = List.length f_ty_args in
|
||||||
|
let ty_l, t_l = take_drop n args in
|
||||||
|
let ty_args = List.map (parse_ty env) ty_l in
|
||||||
|
let t_args = List.map (parse_term env) t_l in
|
||||||
|
Term (term_subst ast id ty_args t_args f_ty_args f_t_args body)
|
||||||
|
|
||||||
|
and parse_ty env ast =
|
||||||
|
match parse_expr { env with expect = Type } ast with
|
||||||
|
| Ty ty -> ty
|
||||||
|
| _ -> _expected "type" ast
|
||||||
|
|
||||||
|
and parse_term env ast =
|
||||||
|
match parse_expr { env with expect = Typed Expr.Ty.base } ast with
|
||||||
|
| Term t -> t
|
||||||
|
| _ -> _expected "term" ast
|
||||||
|
|
||||||
|
and parse_formula env ast =
|
||||||
|
match parse_expr { env with expect = Typed Expr.Ty.prop } ast with
|
||||||
|
| Term t when Expr.(Ty.equal Ty.prop t.t_type) ->
|
||||||
|
make_pred ast t
|
||||||
|
| Formula p -> p
|
||||||
|
| _ -> _expected "formula" ast
|
||||||
|
|
||||||
|
let parse_ttype_var env t =
|
||||||
|
match parse_var env t with
|
||||||
|
| `Ty (id, v) -> (id, v)
|
||||||
|
| `Term _ -> _expected "type variable" t
|
||||||
|
|
||||||
|
let rec parse_sig_quant env = function
|
||||||
|
| { Ast.term = Ast.Binder (Ast.Pi, vars, t) } ->
|
||||||
|
let ttype_vars = List.map (parse_ttype_var env) vars in
|
||||||
|
let ttype_vars', env' = add_type_vars env ttype_vars in
|
||||||
|
let l = List.combine vars ttype_vars' in
|
||||||
|
parse_sig_arrow l [] env' t
|
||||||
|
| t ->
|
||||||
|
parse_sig_arrow [] [] env t
|
||||||
|
|
||||||
|
and parse_sig_arrow ttype_vars (ty_args: (Ast.t * res) list) env = function
|
||||||
|
| { Ast.term = Ast.Binder (Ast.Arrow, args, ret) } ->
|
||||||
|
let t_args = parse_sig_args env args in
|
||||||
|
parse_sig_arrow ttype_vars (ty_args @ t_args) env ret
|
||||||
|
| t ->
|
||||||
|
begin match parse_expr env t with
|
||||||
|
| Ttype ->
|
||||||
|
begin match ttype_vars with
|
||||||
|
| (h, _) :: _ ->
|
||||||
|
raise (Typing_error (
|
||||||
|
"Type constructor signatures cannot have quantified type variables", h))
|
||||||
|
| [] ->
|
||||||
|
let aux n = function
|
||||||
|
| (_, Ttype) -> n + 1
|
||||||
|
| (ast, _) -> raise (Found ast)
|
||||||
|
in
|
||||||
|
begin
|
||||||
|
match List.fold_left aux 0 ty_args with
|
||||||
|
| n -> `Ty_cstr n
|
||||||
|
| exception Found err ->
|
||||||
|
raise (Typing_error (
|
||||||
|
Format.asprintf
|
||||||
|
"Type constructor signatures cannot have non-ttype arguments,", err))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
| Ty ret ->
|
||||||
|
let aux acc = function
|
||||||
|
| (_, Ty t) -> t :: acc
|
||||||
|
| (ast, _) -> raise (Found ast)
|
||||||
|
in
|
||||||
|
begin
|
||||||
|
match List.fold_left aux [] ty_args with
|
||||||
|
| exception Found err -> _expected "type" err
|
||||||
|
| l -> `Fun_ty (List.map snd ttype_vars, List.rev l, ret)
|
||||||
|
end
|
||||||
|
| _ -> _expected "Ttype of type" t
|
||||||
|
end
|
||||||
|
|
||||||
|
and parse_sig_args env l =
|
||||||
|
flat_map (parse_sig_arg env) l
|
||||||
|
|
||||||
|
and parse_sig_arg env = function
|
||||||
|
| { Ast.term = Ast.App ({ Ast.term = Ast.Builtin Ast.Product}, l) } ->
|
||||||
|
List.map (fun x -> x, parse_expr env x) l
|
||||||
|
| t ->
|
||||||
|
[t, parse_expr env t]
|
||||||
|
|
||||||
|
let parse_sig = parse_sig_quant
|
||||||
|
|
||||||
|
let rec parse_fun ty_args t_args env = function
|
||||||
|
| { Ast.term = Ast.Binder (Ast.Fun, l, ret) } ->
|
||||||
|
let ty_args', t_args', env' = parse_quant_vars env l in
|
||||||
|
parse_fun (ty_args @ ty_args') (t_args @ t_args') env' ret
|
||||||
|
| ast ->
|
||||||
|
begin match parse_expr env ast with
|
||||||
|
| Ttype -> raise (Typing_error ("Cannot redefine Ttype", ast))
|
||||||
|
| Ty body ->
|
||||||
|
if t_args = [] then `Ty (ty_args, body)
|
||||||
|
else _expected "term" ast
|
||||||
|
| Term body -> `Term (ty_args, t_args, body)
|
||||||
|
| Formula _ -> _expected "type or term" ast
|
||||||
|
end
|
||||||
|
|
||||||
|
(* High-level parsing functions *)
|
||||||
|
(* ************************************************************************ *)
|
||||||
|
|
||||||
|
let new_decl env t id =
|
||||||
|
Log.debugf 5 "Typing declaration: %s : %a"
|
||||||
|
(fun k -> k id.Id.name Ast.print t);
|
||||||
|
begin match parse_sig env t with
|
||||||
|
| `Ty_cstr n -> decl_ty_cstr id (Expr.Id.ty_fun id.Id.name n)
|
||||||
|
| `Fun_ty (vars, args, ret) ->
|
||||||
|
decl_term id (Expr.Id.term_fun id.Id.name vars args ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
let new_def env t id =
|
||||||
|
Log.debugf 5 "Typing definition: %s = %a"
|
||||||
|
(fun k -> k id.Id.name Ast.print t);
|
||||||
|
begin match parse_fun [] [] env t with
|
||||||
|
| `Ty (ty_args, body) -> def_ty id ty_args body
|
||||||
|
| `Term (ty_args, t_args, body) -> def_term id ty_args t_args body
|
||||||
|
end
|
||||||
|
|
||||||
|
let new_formula env t =
|
||||||
|
Log.debugf 5 "Typing top-level formula: %a" (fun k -> k Ast.print t);
|
||||||
|
let res = parse_formula env t in
|
||||||
|
res
|
||||||
|
|
||||||
15
src/util/type.mli
Normal file
15
src/util/type.mli
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
(** Typechecking of terms from Dolmen.Term.t
|
||||||
|
This module provides functions to parse terms from the untyped syntax tree
|
||||||
|
defined in Dolmen, and generate formulas as defined in the Expr module. *)
|
||||||
|
|
||||||
|
exception Typing_error of string * Dolmen.Term.t
|
||||||
|
|
||||||
|
(** {2 High-level functions} *)
|
||||||
|
|
||||||
|
val new_decl : Dolmen.Id.t -> Dolmen.Term.t -> unit
|
||||||
|
|
||||||
|
val new_def : Dolmen.Id.t -> Dolmen.Term.t -> unit
|
||||||
|
|
||||||
|
val new_formula : Dolmen.Term.t -> Expr.Formula.t
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue