diff --git a/src/main/isabelle/.gitignore b/src/main/isabelle/.gitignore deleted file mode 100644 index c0810538385bb019c4ca5566f2e0a4b28d52b3c5..0000000000000000000000000000000000000000 --- a/src/main/isabelle/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Scratch.thy diff --git a/src/main/isabelle/Leon.thy b/src/main/isabelle/Leon.thy deleted file mode 100644 index 60ffbc20801be58656c2f01f339bd65fdb7f991e..0000000000000000000000000000000000000000 --- a/src/main/isabelle/Leon.thy +++ /dev/null @@ -1,5 +0,0 @@ -theory Leon -imports Leon_Ops Leon_Library -begin - -end \ No newline at end of file diff --git a/src/main/isabelle/Leon_Library.thy b/src/main/isabelle/Leon_Library.thy deleted file mode 100644 index 4327381f8b44ca5855f23aa86e9e9af689409a60..0000000000000000000000000000000000000000 --- a/src/main/isabelle/Leon_Library.thy +++ /dev/null @@ -1,31 +0,0 @@ -theory Leon_Library -imports Leon_Ops -begin - -axiomatization - error :: "nat \<Rightarrow> 'a" - -typedecl string - -declare [[code abort: error]] - -declare null_rec[simp] -declare List.null_def[simp] -declare List.bind_def[simp] -declare Let_def[leon_unfold] -declare Product_Type.split[leon_unfold] -declare comp_apply[simp del] -declare comp_def[simp] -declare member_rec[simp] - -lemma [simp]: "list_ex P xs = (\<not> list_all (Not \<circ> P) xs)" -by (induct xs) auto - -syntax "_leon_var" :: "idt \<Rightarrow> 'a" ("<var _>") -syntax "_leon_const" :: "idt \<Rightarrow> 'a" ("<const _>") - -ML_file "leon_syntax.ML" - -setup \<open>Leon_Syntax.setup\<close> - -end \ No newline at end of file diff --git a/src/main/isabelle/Leon_Ops.thy b/src/main/isabelle/Leon_Ops.thy deleted file mode 100644 index 8ed524cc66c6dd60bf5284f686f36f7097453423..0000000000000000000000000000000000000000 --- a/src/main/isabelle/Leon_Ops.thy +++ /dev/null @@ -1,47 +0,0 @@ -theory Leon_Ops -imports - Protocol - Codec_Class - "~~/src/HOL/Word/Word" - "~~/src/HOL/Library/Simps_Case_Conv" - Complex_Main -begin - -named_theorems leon_unfold - -ML_file "~~/src/HOL/TPTP/sledgehammer_tactics.ML" - -sledgehammer_params [timeout = 5, provers = cvc4 z3 spass e] - -lemma if_to_cond_simps: - assumes "f = (if p then x else y)" - shows "p \<Longrightarrow> f = x" "\<not> p \<Longrightarrow> f = y" -using assms by auto - -ML_file "tactics.ML" -ML_file "util.ML" -ML_file "stateless_ops.ML" -ML_file "stateful_ops.ML" - -operation_setup (auto) numeral_literal = \<open>Stateless_Ops.numeral\<close> -operation_setup (auto) word_literal = \<open>Stateless_Ops.word\<close> -operation_setup (auto) map_literal = \<open>Stateless_Ops.map\<close> -operation_setup (auto) serial_nat = \<open>Stateless_Ops.serial_nat\<close> -operation_setup (auto) load = \<open>Stateful_Ops.load\<close> -operation_setup (auto) "oracle" = \<open>Stateful_Ops.oracle\<close> -operation_setup (auto) fresh = \<open>Stateful_Ops.fresh\<close> -operation_setup (auto) prove = \<open>Stateful_Ops.prove\<close> -operation_setup (auto) equivalences = \<open>Stateful_Ops.equivalences\<close> -operation_setup (auto) assume_equivalences = \<open>Stateful_Ops.assume_equivalences\<close> -operation_setup (auto) "lemmas" = \<open>Stateful_Ops.lemmas\<close> -operation_setup (auto) assume_lemmas = \<open>Stateful_Ops.assume_lemmas\<close> -operation_setup (auto) "declare" = \<open>Stateful_Ops.declare\<close> -operation_setup (auto) pretty = \<open>Stateful_Ops.pretty\<close> -operation_setup (auto) report = \<open>Stateful_Ops.report\<close> -operation_setup (auto) dump = \<open>Stateful_Ops.dump\<close> -operation_setup (auto) lookup_datatype = \<open>Stateful_Ops.lookup_datatype\<close> -operation_setup (auto) "datatypes" = \<open>Stateful_Ops.datatypes\<close> -operation_setup (auto) "functions" = \<open>Stateful_Ops.functions\<close> -operation_setup (auto) cases = \<open>Stateful_Ops.cases\<close> - -end \ No newline at end of file diff --git a/src/main/isabelle/ROOT b/src/main/isabelle/ROOT deleted file mode 100644 index d95bef0c4a3bcacb7ab56a1767280e54a749e285..0000000000000000000000000000000000000000 --- a/src/main/isabelle/ROOT +++ /dev/null @@ -1,8 +0,0 @@ -session Leon_Deps = "HOL-Protocol" + - theories - "~~/src/HOL/Word/Word" - "~~/src/HOL/Library/Simps_Case_Conv" - -session Leon = Leon_Deps + - theories - Leon diff --git a/src/main/isabelle/leon_syntax.ML b/src/main/isabelle/leon_syntax.ML deleted file mode 100644 index cc0c704a08cdbe12de2c6c061f4228e4098afaaa..0000000000000000000000000000000000000000 --- a/src/main/isabelle/leon_syntax.ML +++ /dev/null @@ -1,82 +0,0 @@ -signature LEON_SYNTAX = sig - val setup: theory -> theory -end - -structure Leon_Syntax: LEON_SYNTAX = struct - -fun is_digit #"0" = true - | is_digit #"1" = true - | is_digit #"2" = true - | is_digit #"3" = true - | is_digit #"4" = true - | is_digit #"5" = true - | is_digit #"6" = true - | is_digit #"7" = true - | is_digit #"8" = true - | is_digit #"9" = true - | is_digit _ = false - -fun is_leon_name base id name = - let - val prefix = Long_Name.append base (id ^ "'") - val exploded = String.explode name - in - String.isPrefix prefix name andalso List.all is_digit (drop (String.size prefix) exploded) - end - -fun find_leon_name base id names = - case filter (is_leon_name base id) names of - [name] => SOME name - | _ => NONE - -fun translation const ctxt args = - let - val thy = Proof_Context.theory_of ctxt - val thy_name = Context.theory_name thy - val fixes = Variable.dest_fixes ctxt - val {constants = consts, ...} = Consts.dest (Sign.consts_of thy) - fun guess id = - if const then - case find_leon_name thy_name id (map fst consts) of - SOME name => Const (name, dummyT) - | NONE => raise TERM ("unknown or ambiguous Leon constant " ^ id, args) - else - case find_leon_name "" id (map fst fixes) of - SOME name => Free (name, dummyT) - | NONE => raise TERM ("unknown or ambiguous Leon variable " ^ id, args) - in - case args of - [(Const (@{syntax_const "_constrain"}, _)) $ Free (s, _) $ _] => guess s - | _ => impossible "Leon_Syntax.translation" @{here} - end - -val const_translation = translation true -val var_translation = translation false - -val translation_setup = Sign.parse_translation - [(@{syntax_const "_leon_var"}, var_translation), - (@{syntax_const "_leon_const"}, const_translation)] - - -fun get_induct id thy = - let - val functions = Stateful_Ops.get_functions thy - val names = Symtab.keys functions - in - case find_leon_name "" id names of - SOME name => - (case the (Symtab.lookup functions name) of - (NONE, _) => error ("no induction rule for " ^ id) - | (SOME thm, _) => thm) - | NONE => error ("unknown or ambiguous Leon function " ^ id) - end - -val attrib_setup = - Attrib.setup @{binding leon_induct} - (Scan.lift Args.name >> - (fn name => Thm.mixed_attribute (fn (context, _) => (context, get_induct name (Context.theory_of context))))) - "induction rule for Leon function" - -val setup = translation_setup #> attrib_setup - -end \ No newline at end of file diff --git a/src/main/isabelle/stateful_ops.ML b/src/main/isabelle/stateful_ops.ML deleted file mode 100644 index 88ee8478f2653d69619fa15ff6dfb04a712aa6d1..0000000000000000000000000000000000000000 --- a/src/main/isabelle/stateful_ops.ML +++ /dev/null @@ -1,580 +0,0 @@ -signature STATEFUL_OPS = sig - val load: string * string * (string * string) list -> string list - val oracle: unit -> unit - val fresh: string -> string - val prove: term list * string option -> string option - val declare: string list -> unit - val cases: (term * (string * typ) list) * (typ * (term * term) list) -> term - val equivalences: (string * string) list -> string list - val assume_equivalences: (string * string) list -> unit - val lemmas: (string * term) list -> string list - val assume_lemmas: (string * term) list -> unit - val functions: (string * (string * typ) list * (term * typ)) list -> string option - val datatypes: (string * string list * (string * (string * typ) list) list) list -> string option - val lookup_datatype: string * (string * string) list -> (string, (string * (term * term * term list)) list) Codec.either - val pretty: term -> string - val report: unit -> (string * string) list - val dump: unit -> (string * string) list - - (* internal *) - val reset: theory option -> unit - val peek: unit -> local_theory option - val get_functions: theory -> (thm option * thm list) Symtab.table -end - -structure Stateful_Ops: STATEFUL_OPS = struct - -fun try_timeout' f = try_timeout 5 f (* global timeout for auxiliary operations *) - -fun err_timeout msg f x = - case try_timeout 5 f x of - Exn.Res r => r - | Exn.Exn TimeLimit.TimeOut => raise Timeout msg - | Exn.Exn exn => reraise exn - -datatype report = - Function of {heads: (string * string) list, raws: string list, specs: string list, inducts: (string * string) list} | - Datatype of string | - Theory of {import: string, scripts: (string * string) list} | - Equivalence of string | - Lemma of {name: string, prop: string} | - Oracle | - End - -structure Reports = Theory_Data -( - type T = report list - val empty = [] - fun merge _ = impossible "Reports.merge" @{here} - val extend = I -) - -structure Functions = Theory_Data -( - type T = (thm option * thm list) Symtab.table - val empty = Symtab.empty - fun merge _ = impossible "Functions.merge" @{here} - val extend = I -) - -structure Oracle = Theory_Data -( - type T = (cterm -> thm) option - val empty = NONE - fun merge _ = impossible "Oracle.merge" @{here} - val extend = I -) - -fun add_report report = Reports.map (fn list => report :: list) -val add_fun = Functions.map o Symtab.update_new -val add_funs = fold add_fun -fun set_oracle thy = - let - val ((_, oracle), thy') = Thm.add_oracle (@{binding leon_oracle}, I) thy - in - Oracle.map (K (SOME oracle)) thy' - |> add_report Oracle - end -val get_oracle = - Proof_Context.theory_of - #> Oracle.get - #> the_error "expected oracle" @{here} - -val get_functions = Functions.get - -type state = local_theory option -val empty_state = NONE: state - -val state = Synchronized.var "libisabelle.leon_state" empty_state - -fun unset_parallel_proofs () = - Goal.parallel_proofs := 0 - -fun reset thy = - (unset_parallel_proofs (); Synchronized.change state (K (Option.map (Named_Target.theory_init) thy))) - -fun peek () = - Synchronized.value state - -local - fun not_loaded pos = - invalid_state "no theory loaded" pos - fun already_loaded lthy = - invalid_state ("theory " ^ Context.theory_name (Proof_Context.theory_of lthy) ^ "already loaded") -in - -fun access_loaded f = - case Synchronized.value state of - SOME thy => f thy - | NONE => not_loaded @{here} - -fun update_loaded f = - let - fun upd NONE = not_loaded @{here} - | upd (SOME thy) = let val (a, thy') = f thy in (a, SOME thy') end - in - Synchronized.change_result state upd - end - -fun load (root_name, thy_name, scripts) = - let - val _ = unset_parallel_proofs () - val _ = - if Execution.is_running_exec Document_ID.none then () - else invalid_state "Must not be running in interactive mode" @{here} - val root = Thy_Info.get_theory root_name - - fun load_script (name, txt) = - let - val thy = Theory.begin_theory (name, Position.none) [root] - in (name, Exn.interruptible_capture (script_thy Position.none txt) thy) end - - fun classify (_, Exn.Res thy) = ([thy], []) - | classify (name, Exn.Exn _) = ([], [name]) - - fun upd (SOME lthy) = already_loaded lthy @{here} - | upd NONE = - let - val (good, bad) = map classify (Par_List.map load_script scripts) - |> split_list ||> flat |>> flat - - fun thy () = - Theory.begin_theory (thy_name, Position.none) (root :: good) - |> add_report (Theory {import = root_name, scripts = scripts}) - - val res = - if null bad then - SOME (Named_Target.theory_init (thy ())) - else - NONE - in (bad, res) end - in Synchronized.change_result state upd end - -end - -fun oracle () = - update_loaded (Local_Theory.background_theory set_oracle #> pair ()) - -fun fresh n = - update_loaded (Variable.variant_fixes [n] #>> hd) - -fun prove (ts, method) = - access_loaded (fn lthy => - let - val (ts', lthy) = register_terms ts lthy - val prop = Balanced_Tree.make HOLogic.mk_disj ts' - fun tac ctxt = - case method of - NONE => prove_tac ctxt - | SOME src => HEADGOAL (method_tac @{here} src ctxt) - in - (* Assumption: all proofs are sequential *) - try (Goal.prove lthy [] [] prop) (fn {context, ...} => tac context) - |> Option.map (print_thm lthy) - end) - -fun gen_lemmas prove props = - update_loaded (fn lthy => - let - fun process (name, prop) lthy = - let - val ([prop'], lthy') = register_terms [prop] lthy - val binding = Binding.qualified true "lemma" (Binding.make (name, @{here})) - in - case prove lthy' prop' of - NONE => ([name], lthy) - | SOME thm => - lthy (* sic *) - |> Local_Theory.note ((binding, @{attributes [simp]}), [thm]) |> snd - |> Local_Theory.background_theory (add_report (Lemma {name = name, prop = print_thm lthy thm})) - |> pair [] - end - in - fold_map process props lthy - |>> flat - end) - -val lemmas = - gen_lemmas (fn ctxt => fn goal => - try_timeout' (Goal.prove ctxt [] [] goal) (fn {context, ...} => prove_tac context) |> Exn.get_res) - -val assume_lemmas = - gen_lemmas (fn ctxt => fn goal => - SOME (get_oracle ctxt (Thm.cterm_of ctxt goal))) - #> K () - -fun declare names = - update_loaded (fold Variable.declare_names (map (Free o rpair dummyT) names) #> pair ()) - -fun cases ((raw_scr, bounds), (expected_typ, clauses)) = - access_loaded (fn ctxt => - let - fun dest_abs (name, typ) t = Term.dest_abs (name, typ, t) - val unbound = fold_map dest_abs bounds #> snd - - val scr = Syntax.check_term ctxt (unbound raw_scr) - val scr_typ = fastype_of scr - val names = Variable.names_of ctxt - - fun process_clause (raw_pat, raw_rhs) = - let - val pat = Syntax.check_term ctxt (Type.constraint scr_typ raw_pat) - val frees = all_undeclared_frees ctxt pat - val (free_names', ctxt') = Variable.add_fixes (map fst frees) ctxt - val frees' = map Free (free_names' ~~ map snd frees) - val frees = map Free frees - val (pat', raw_rhs') = apply2 (subst_free (frees ~~ frees')) (pat, unbound raw_rhs) - - val rhs' = - Type.constraint expected_typ raw_rhs' - |> Syntax.check_term (Variable.declare_term pat' ctxt') - in - (pat', rhs') - end - - val term = - map process_clause clauses - |> Case_Translation.make_case ctxt Case_Translation.Quiet names scr - |> Syntax.check_term ctxt - - fun find_type (t $ u) name = merge_options (find_type t name, find_type u name) - | find_type (Abs (_, _, t)) name = find_type t name - | find_type (Free (name', typ)) name = if name = name' then SOME typ else NONE - | find_type _ _ = NONE - - fun get_type (name, typ) = - if typ = dummyT then - the_default dummyT (find_type term name) - else - typ - - val new_bounds = map fst bounds ~~ map get_type bounds - in - fold (Term.lambda o Free) new_bounds term |> strip_abs_body - end) - -fun gen_equivalences prove eqs = - update_loaded (fn lthy => - let - fun prepare (lhs, rhs) = - let - val lhs' = qualify lthy lhs - - val (rule, specs) = - Symtab.lookup (Functions.get (Proof_Context.theory_of lthy)) lhs - |> the_error "equivalences" @{here} - - val goal = mk_untyped_eq (Const (lhs', dummyT), Syntax.parse_term lthy rhs) - |> HOLogic.mk_Trueprop - |> Syntax.check_term lthy - in - (lhs, specs, goal, rule) - end - - val prepared = map prepare eqs - - fun process (name, specs, goal, rule) lthy = - let - val binding = Binding.qualified true "equiv" (Binding.make (name, @{here})) - in - case prove lthy goal rule of - NONE => (([name], []), lthy) - | SOME thm => - lthy - |> Local_Theory.note ((Binding.empty, @{attributes [simp del]}), specs) |> snd - |> Local_Theory.note ((binding, @{attributes [simp]}), [thm]) |> snd - |> pair ([], [thm]) - end - - val ((bad, good), lthy') = - fold_map process prepared lthy - |>> split_list |>> apfst flat |>> apsnd flat - - val lthy'' = - Local_Theory.background_theory (fold (add_report o Equivalence o print_thm lthy') good) lthy' - in - (bad, lthy'') - end) - -val assume_equivalences = - gen_equivalences (fn lthy => fn goal => fn _ => - SOME (get_oracle lthy (Thm.cterm_of lthy goal))) - #> K () - -val equivalences = - gen_equivalences (fn lthy => fn goal => fn rule => - try_timeout' (Goal.prove lthy [] [] goal) (fn {context, ...} => equiv_tac rule context) |> Exn.get_res) - -fun functions raw_funs = - update_loaded (fn lthy => - let - fun transform (name, raw_args, (raw_rhs, expected_typ)) = - let - val lhs = list_comb (Free (name, dummyT), map Free raw_args) - val rhs = Type.constraint expected_typ raw_rhs - in - ((Binding.make (name, @{here}), NONE, NoSyn), - HOLogic.mk_Trueprop (Const (@{const_name HOL.eq}, dummyT) $ lhs $ rhs)) - end - - val no_args = exists (equal 0 o length o #2) raw_funs - - val specs = - map transform raw_funs - |> split_list - ||> map (Syntax.check_term lthy) - ||> length raw_funs > 1 ? homogenize_raw_types lthy - ||> map (pair (Binding.empty, [])) - |> op ~~ - - val recursive = - case specs of - [(_, (_, prop))] => - let - val ((f, _), rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop prop) |>> strip_comb - in - exists (equal f o Free) (all_frees rhs) - end - | _ => true - - fun fun_construction lthy = - let - val (heads, props) = split_list specs - val construction = Function.add_function heads props Function_Fun.fun_config pat_completeness_auto_tac - val (_, lthy) = err_timeout "function construction" construction lthy - val (info, lthy) = err_timeout "termination proof" (Function.prove_termination NONE (termination_tac lthy)) lthy - in - #simps info - |> the_error "simps of function definition" @{here} - |> rpair lthy - end - fun def_construction lthy = - let val [(head, prop)] = specs in - Specification.definition (SOME head, prop) lthy - |>> snd |>> snd |>> single - end - - fun construction lthy = lthy |> - (case (recursive, no_args) of - (true, true) => raise Unsupported ("Mutual definition without arguments: " ^ commas (map #1 raw_funs)) - | (true, false) => fun_construction - | (false, _) => def_construction) - in - case Exn.interruptible_capture construction lthy of - Exn.Res (thms, lthy) => - let - val names = map #1 raw_funs - val get_typ = - Thm.prop_of #> HOLogic.dest_Trueprop #> HOLogic.dest_eq #> fst - #> strip_comb #> fst - #> fastype_of - #> print_typ lthy - val typs = map get_typ thms - val lthy' = Local_Theory.restore lthy - val thms = Proof_Context.export lthy lthy' thms - val simpss = thms - |> map (try_case_to_simps lthy' o restore_eq o full_simplify (mk_simp_ctxt lthy')) - |> map (homogenize_spec_types lthy') - val simps = maps if_to_cond_simps (flat simpss) - val specs = names ~~ map (`(try_timeout' (mk_induction_schema lthy') #> Exn.get_res)) simpss - fun print_induct (_, (NONE, _)) = NONE - | print_induct (name, (SOME rule, _)) = SOME (name, print_thm lthy' rule) - val binding = Binding.qualified true "spec" (Binding.make (hd names, @{here})) - val report = - Function - {heads = names ~~ typs, - inducts = map_filter print_induct specs, - specs = map (print_thm lthy') simps, - raws = map (print_thm lthy') thms} - val lthy'' = lthy' - |> Local_Theory.note ((Binding.empty, @{attributes [simp del]}), thms) |> snd - |> Local_Theory.note ((binding, @{attributes [simp]}), simps) |> snd - |> Local_Theory.background_theory (add_funs specs #> add_report report) - in - (NONE, lthy'') - end - | Exn.Exn (exn as Impossible _) => - reraise exn - | Exn.Exn exn => - (SOME (print_exn exn), lthy) - end) - -fun datatypes raw_dts = - update_loaded (fn lthy => - let - val raw_dts = map (apfst (qualify lthy o #1) o dupl) raw_dts - - fun mk_edges (qname, (_, _, constrs)) = - let - fun collect_types (Type (name, typs)) = name :: maps collect_types typs - | collect_types _ = [] - val deps = constrs |> maps snd |> maps (collect_types o snd) - in map (pair qname) deps end - - fun free tp = TFree ("'" ^ tp, @{sort type}) - - fun homogenize ((dt as (_, tps, _)) :: dts) = - let - fun subst tps' = typ_subst_atomic (map free tps' ~~ map free tps) - fun replace (name, tps', constrs) = (name, tps, map (apsnd (map (apsnd (subst tps')))) constrs) - in - dt :: map replace dts - end - - val sccs = compute_sccs raw_dts (maps mk_edges raw_dts) - - fun check_arity_dts dts = length (distinct op = (map (length o #2) dts)) = 1 - val check_arity = not (exists (equal false) (map check_arity_dts sccs)) - - fun transform_tp raw_tp = - (SOME (Binding.name raw_tp), (free raw_tp, @{sort type})) - fun transform_field (name, typ) = - (Binding.name ("s" ^ name), typ) - fun transform_constr (name, raw_fields) = - (((Binding.name ("d" ^ name), Binding.name ("c" ^ name)), map transform_field raw_fields), NoSyn) - fun transform (name, raw_tps, raw_constrs) = - let - val dt = ((map transform_tp raw_tps, Binding.make (name, @{here})), NoSyn) - val constrs = map transform_constr raw_constrs - in - (((dt, constrs), (@{binding map}, @{binding rel})), []) - end - - fun print lthy dts = - let - fun print_tp tp = "'" ^ tp - fun print_tps [] = "" - | print_tps tps = enclose "(" ")" (commas (map print_tp tps)) - fun print_field (name, typ) = - "(s" ^ name ^ ": " ^ quote (print_typ lthy typ) ^ ")" - fun print_constr (name, fields) = - "d" ^ name ^ ": c" ^ name ^ " " ^ space_implode " " (map print_field fields) - fun print_one (name, tps, constrs) = - print_tps tps ^ " " ^ name ^ " = " ^ space_implode " | " (map print_constr constrs) - in - "datatype " ^ space_implode " and " (map print_one dts) - end - - fun setup_dts scc lthy = - let - val input = (Ctr_Sugar.default_ctr_options, map transform scc) - val lthy = - BNF_FP_Def_Sugar.co_datatypes BNF_Util.Least_FP BNF_LFP.construct_lfp input lthy - |> Local_Theory.restore - - fun get_sugar (name, _, _) = - qualify lthy name |> Ctr_Sugar.ctr_sugar_of lthy - |> the_error ("ctr_sugar of " ^ name) @{here} - - val sugars = map get_sugar scc - - fun get_splits {split, split_asm, ...} = [split, split_asm] - fun get_cases {case_thms, ...} = case_thms - in - lthy - |> Local_Theory.note ((Binding.empty, @{attributes [split]}), maps get_splits sugars) |> snd - |> Local_Theory.note ((Binding.empty, @{attributes [leon_unfold]}), maps get_cases sugars) |> snd - end - in - if check_arity then - let - val sccs = map homogenize sccs - val lthy' = fold setup_dts sccs lthy - val lthy'' = Local_Theory.background_theory (fold (add_report o Datatype o print lthy') sccs) lthy' - in (NONE, lthy'') end - else - (SOME "Unsupported feature: mismatched datatype arity", lthy) - end) - -fun lookup_datatype (name, raw_constructors) = - update_loaded (fn lthy => - case Ctr_Sugar.ctr_sugar_of lthy name of - NONE => - (Codec.Left ("unknown datatype " ^ name), lthy) - | SOME {ctrs, discs, selss, split, split_asm, case_thms, ...} => - let - val raw_constructors = sort_by snd (raw_constructors) - val (names, terms) = - map (fst o dest_Const) ctrs ~~ (discs ~~ selss) - |> sort_by fst - |> split_list - fun process (internal_name, name) (disc, sels) = - (internal_name, (Const (name, dummyT), dummify_types disc, map dummify_types sels)) - - val lthy' = - lthy - |> Local_Theory.note ((Binding.empty, @{attributes [split]}), [split, split_asm]) |> snd - |> Local_Theory.note ((Binding.empty, @{attributes [leon_unfold]}), case_thms) |> snd - in - if map snd raw_constructors <> names then - (Codec.Left ("constructor name mismatch: declared constructors are " ^ commas names), lthy) - else - (Codec.Right (map2 process raw_constructors terms), lthy') - end) - -fun pretty t = - access_loaded (fn lthy => print_term lthy t) - -fun report () = - access_loaded (fn lthy => - let - fun print_report (Theory {scripts, ...}) = map (pair "Script" o fst) scripts - | print_report (Equivalence prop) = [("Equivalence", prop)] - | print_report (Datatype spec) = [("Datatype", spec)] - | print_report (Lemma {name, prop}) = [("Lemma", name ^ ": " ^ prop)] - | print_report (Function {raws, inducts, specs, ...}) = - map (pair "Function (raw)") raws @ - map (pair "Function (spec)") specs @ - map (fn (name, induct) => ("Function (induct)", name ^ ": " ^ induct)) inducts - | print_report Oracle = [("Oracle", "enabled")] - in - Proof_Context.theory_of lthy - |> Reports.get - |> rev - |> maps print_report - end) - -fun dump () = - access_loaded (fn lthy => - let - fun print_thy_header name imports = - "theory " ^ name ^ "\n" ^ - "imports " ^ space_implode " " imports ^ "\n" ^ - "begin\n" - - fun print_thy name import text = - print_thy_header name [import] ^ text ^ "\nend\n" - - val name = Context.theory_name (Proof_Context.theory_of lthy) - - fun print_report (Theory {scripts, import}) = - (map (fn (script_name, text) => (script_name, print_thy script_name import text)) scripts, - print_thy_header name (import :: map fst scripts)) - | print_report (Equivalence prop) = ([], "lemma [simp]: " ^ quote prop ^ "\nsorry") - | print_report (Lemma {prop, ...}) = ([], "lemma [simp]: " ^ quote prop ^ "\nsorry") - | print_report (Datatype spec) = ([], spec) - | print_report Oracle = ([], "") - | print_report End = ([], "\nend\n") - | print_report (Function {heads, specs, ...}) = - let - fun mk_head (name, typ) = quote name ^ " :: " ^ quote typ - val head = "fun " ^ space_implode " and " (map mk_head heads) ^ " where\n" - val body = space_implode "|\n" (map quote specs) - in - ([], head ^ body) - end - in - Proof_Context.theory_of lthy - |> Reports.get - |> cons End - |> rev - |> map print_report - |> split_list - |>> flat - ||> space_implode "\n\n" - ||> pair name - |> swap - |> op :: - end) - -end \ No newline at end of file diff --git a/src/main/isabelle/stateless_ops.ML b/src/main/isabelle/stateless_ops.ML deleted file mode 100644 index 31fc63999570922f63dac1972289bd43b1044a5b..0000000000000000000000000000000000000000 --- a/src/main/isabelle/stateless_ops.ML +++ /dev/null @@ -1,40 +0,0 @@ -signature STATELESS_OPS = sig - val numeral: (int * typ) -> term - val serial_nat: unit -> term - val word: int -> typ - val map: ((term * term) list * (typ * typ)) -> term -end - -structure Stateless_Ops: STATELESS_OPS = struct - -fun numeral (n, typ) = - let - fun wrap numeral = HOLogic.numeral_const typ $ numeral - in - if n = 0 then - Const (@{const_name "zero_class.zero"}, typ) - else if n > 0 then - wrap (HOLogic.mk_numeral n) - else - Const (@{const_name "uminus"}, dummyT) $ wrap (HOLogic.mk_numeral (~n)) - end - -val serial_nat = - numeral o rpair @{typ nat} o serial - -fun word n = - Type (@{type_name word}, [Syntax.read_typ @{context} (Markup.print_int n)]) - -fun map (xs, (fty, tty)) = - let - val opt_tty = Type (@{type_name option}, [tty]) - val fun_ty = fty --> opt_tty - val init = Abs ("x", fty, Const (@{const_name None}, opt_tty)) - fun aux (f, t) acc = - Const (@{const_name fun_upd}, fun_ty --> fty --> opt_tty --> fun_ty) $ acc $ f $ - (Const (@{const_name Some}, tty --> opt_tty) $ t) - in - fold aux xs init - end - -end \ No newline at end of file diff --git a/src/main/isabelle/tactics.ML b/src/main/isabelle/tactics.ML deleted file mode 100644 index d2a5ce83b8499bcc45bd0037a992e56f9f7d30c7..0000000000000000000000000000000000000000 --- a/src/main/isabelle/tactics.ML +++ /dev/null @@ -1,66 +0,0 @@ -fun mk_simp_ctxt ctxt = - (put_simpset HOL_ss ctxt) addsimps Named_Theorems.get ctxt @{named_theorems leon_unfold} - -fun prove_tac ctxt = - HEADGOAL - (SELECT_GOAL (TRY (auto_tac ctxt)) THEN_ALL_NEW - (FIRST' - [Cooper.tac false [] [] ctxt, - Sledgehammer_Tactics.sledgehammer_with_metis_tac ctxt [] Sledgehammer_Fact.no_fact_override []])) - -fun equiv_tac rule ctxt = - let - val solve_tac = - TRY (ALLGOALS (REPEAT_ALL_NEW (resolve_tac ctxt @{thms ext}))) THEN - Local_Defs.unfold_tac ctxt (Named_Theorems.get ctxt @{named_theorems leon_unfold}) THEN - auto_tac ctxt - - fun ext_tac 0 _ = all_tac - | ext_tac n k = resolve_tac ctxt @{thms ext} k THEN ext_tac (n - 1) k - - fun induct rule = CSUBGOAL (fn (concl, n) => - let - val (p, args) = strip_comb (HOLogic.dest_Trueprop (Thm.concl_of rule)) - - val p_inst = Thm.term_of concl - |> HOLogic.dest_Trueprop |> HOLogic.dest_eq - |> apply2 (rpair (map Bound (length args - 1 downto 0))) - |> apply2 list_comb - |> HOLogic.mk_eq - |> fold (fn _ => fn t => Abs ("x", dummyT, t)) (1 upto length args) - |> Syntax.check_term ctxt - |> Thm.cterm_of ctxt - - val insts = [(fst (dest_Var p), p_inst)] - val rule = Drule.infer_instantiate ctxt insts rule - in ext_tac (length args) n THEN resolve_tac ctxt [rule] n end) - - val maybe_induct = - case rule of - NONE => K all_tac - | SOME rule => induct rule - in - HEADGOAL maybe_induct THEN solve_tac - end - -fun method_tac pos src = Subgoal.FOCUS (fn {context = ctxt, concl, ...} => - let - val scan = Scan.finite Token.stopper Method.parse; - val ((m, _), []) = - src - |> Token.explode (Thy_Header.get_keywords (Proof_Context.theory_of ctxt)) pos - |> filter_out Token.is_space - |> Scan.catch scan - val state = - Proof.theorem NONE (K I) [[(Thm.term_of concl, [])]] ctxt - |> Proof.refine_singleton m - val {goal, ...} = Proof.simple_goal state - in - HEADGOAL (resolve_tac ctxt [Goal.conclude goal]) - end) - -fun pat_completeness_auto_tac ctxt = - Pat_Completeness.pat_completeness_tac ctxt 1 THEN auto_tac ctxt - -fun termination_tac ctxt = - Function_Common.termination_prover_tac true ctxt \ No newline at end of file diff --git a/src/main/isabelle/util.ML b/src/main/isabelle/util.ML deleted file mode 100644 index 55be31d116b0e3be15c4ffb19b30b38946213996..0000000000000000000000000000000000000000 --- a/src/main/isabelle/util.ML +++ /dev/null @@ -1,281 +0,0 @@ -fun map_result_exn _ (Exn.Res r) = Exn.Res r - | map_result_exn f (Exn.Exn exn) = Exn.Exn (f exn) - -fun print_position pos = - let - val print_file = Path.implode o Path.base o Path.explode - in - case (Position.file_of pos, Position.line_of pos) of - (SOME file, SOME line) => print_file file ^ ":" ^ Markup.print_int line - | (SOME file, NONE) => print_file file - | _ => "<unknown>" - end - -exception Unsupported of string -exception Construction of string * exn -exception Impossible of string -exception Invalid_State of string -exception Timeout of string - -local - fun format_message msg pos = msg ^ " (at " ^ print_position pos ^ ")" -in - -fun impossible msg pos = - raise Impossible (format_message msg pos) - -fun invalid_state msg pos = - raise Invalid_State (format_message msg pos) - -fun the_error msg pos NONE = impossible ("expected SOME: " ^ msg) pos - | the_error _ _ (SOME x) = x - -fun single_error _ _ [t] = t - | single_error msg pos _ = impossible ("expected singleton list: " ^ msg) pos - -end - -fun print_exn (exn: exn) = - YXML.content_of (@{make_string} exn) - -fun check true _ = () - | check false f = error (f ()) - -fun dupl x = (x, x) - -val unvarify_typ = - let - fun aux (TVar ((name, idx), sort)) = TFree (name ^ Markup.print_int idx, sort) - | aux t = t - in map_atyps aux end - -val unvarify = - let - fun aux (Var ((name, idx), typ)) = Free (name ^ Markup.print_int idx, typ) - | aux t = t - in map_aterms aux o map_types unvarify_typ end - -fun print_term ctxt = - let - val ctxt' = Config.put show_markup false ctxt - in YXML.content_of o Syntax.string_of_term ctxt' o unvarify end - -fun print_typ ctxt = - let - val ctxt' = Config.put show_markup false ctxt - in YXML.content_of o Syntax.string_of_typ ctxt' o unvarify_typ end - -fun print_thm ctxt thm = - let - val t = Thm.prop_of thm - val {oracle, ...} = Thm.peek_status thm - val suffix = if oracle then " [!]" else "" - in - print_term ctxt t ^ suffix - end - -fun all_consts (Const (name, typ)) = [(name, typ)] - | all_consts (t $ u) = all_consts t @ all_consts u - | all_consts (Abs (_, _, t)) = all_consts t - | all_consts _ = [] - -fun all_frees (Free (name, typ)) = [(name, typ)] - | all_frees (t $ u) = all_frees t @ all_frees u - | all_frees (Abs (_, _, t)) = all_frees t - | all_frees _ = [] - -fun all_undeclared_frees ctxt = - all_frees - #> distinct op = - #> filter (not o Variable.is_declared ctxt o fst) - -fun register_terms ts lthy = - let - val ts' = Syntax.check_terms lthy ts |> map HOLogic.mk_Trueprop - val frees = distinct op = (maps (all_undeclared_frees lthy) ts') - val (free_names', lthy) = Variable.add_fixes (map fst frees) lthy - val frees' = map Free (free_names' ~~ map snd frees) - val frees = map Free frees - val ts'' = map (subst_free (frees ~~ frees')) ts' - in - (ts'', fold Variable.declare_term ts'' lthy) - end - -fun qualify ctxt name = - Context.theory_name (Proof_Context.theory_of ctxt) ^ "." ^ name - -fun compute_sccs nodes edges = - Graph.empty - |> fold Graph.new_node nodes - |> fold (fn edge => perhaps (try (Graph.add_edge edge))) edges - |> (fn graph => map (map (Graph.get_node graph)) (Graph.strong_conn graph)) - |> rev - -val dummify_types = map_types (K dummyT) - -fun fold_opt _ [] y = SOME y - | fold_opt f (x :: xs) y = Option.mapPartial (fold_opt f xs) (f x y) - -fun fold_res _ [] y = Exn.Res y - | fold_res f (x :: xs) y = Exn.maps_res (fold_res f xs) (f x y) - -fun map_generalized f t = - case t of - Const (@{const_name Pure.all}, typ) $ Abs (name, typ', t) => - (Const (@{const_name Pure.all}, typ) $ Abs (name, typ', map_generalized f t)) - | _ => - f t - -fun mk_untyped_eq (x, y) = - HOLogic.eq_const dummyT $ x $ y - -fun strip_first_prem t = - let - val prems = tl (Logic.strip_imp_prems t) - val concl = Logic.strip_imp_concl t - in Logic.list_implies (prems, concl) end - -fun map_prems f t = - let - val prems = Logic.strip_imp_prems t - val concl = Logic.strip_imp_concl t - in Logic.list_implies (map f prems, concl) end - -fun mk_induction_schema lthy thms = - let - val props = map (unvarify o Thm.prop_of) thms - - val ((heads, argss), rhss) = - props - |> map (HOLogic.dest_eq o HOLogic.dest_Trueprop) - |> split_list - |>> map strip_comb |>> split_list - - val names = - map (fst o dest_Const) heads - |> distinct op = - |> Name.invent_names (Variable.names_of (fold Variable.declare_names (flat argss) lthy)) "temp" - |> map swap - - fun subst (t as Const (name, _)) = - (case AList.lookup op = names name of SOME new => Free (new, dummyT) | NONE => t) - | subst t = t - - fun mk_prop head args rhs = - map_aterms subst rhs - |> pair (list_comb (subst head, args)) - |> mk_untyped_eq - |> HOLogic.mk_Trueprop - - fun mk_head name = (Binding.name name, NONE, NoSyn) - val props = map (pair (Binding.empty, [])) (Syntax.check_terms lthy (@{map 3} mk_prop heads argss rhss)) - val heads = map (mk_head o snd) names - - val (info, _) = - (* FIXME funny warning *) - Function.add_function heads props Function_Common.default_config pat_completeness_auto_tac lthy - - val raw_prop = unvarify (Thm.prop_of (hd (#pinducts info))) - val prop = map_prems (map_generalized strip_first_prem) (strip_first_prem raw_prop) - val frees = distinct op = (map fst (all_frees prop)) - - fun tac ctxt = - Induction_Schema.induction_schema_tac ctxt [] THEN - HEADGOAL (Pat_Completeness.pat_completeness_tac ctxt) THEN - Lexicographic_Order.lexicographic_order_tac false ctxt - - val thm = Goal.prove lthy frees [] prop (fn {context, ...} => tac context) - val lthy' = Local_Theory.restore lthy - in - Morphism.thm (Proof_Context.export_morphism lthy lthy') thm - end - -(* based on Thy_Info.script_thy *) -fun script_thy pos txt thy = - let - val trs = flat - [[Toplevel.init_theory (K thy) Toplevel.empty], - Outer_Syntax.parse thy pos txt, - [Toplevel.exit Toplevel.empty]] - val end_state = fold (Toplevel.command_exception true) trs Toplevel.toplevel; - in - Toplevel.end_theory pos end_state - end - -fun try_timeout secs f x = - let - val time = Time.fromSeconds secs - in - Exn.capture (TimeLimit.timeLimit time f) x - end - -fun try_case_to_simps ctxt thm = - the_default [thm] (try (Simps_Case_Conv.to_simps ctxt) thm) - -fun restore_eq thm = - case Thm.prop_of thm of - @{term Trueprop} $ (Const (@{const_name HOL.eq}, _) $ _ $ _) => thm - | _ => @{lemma "P \<Longrightarrow> P = True" by simp} OF [thm] - -fun homogenize_spec_types ctxt thms = - let - val get_head = dest_Const o fst o strip_comb o fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of - val paired = map (`get_head) thms - - val head = map (fst o fst) paired - |> distinct op = - |> single_error "heads" @{here} - - val typ = Sign.the_const_type (Proof_Context.theory_of ctxt) head - - fun mk_subst (iname, (sort, inst)) = - ((iname, sort), Thm.ctyp_of ctxt inst) - - fun instantiate ((_, ttyp), thm) = - let - val subst = Type.raw_match (ttyp, typ) Vartab.empty |> Vartab.dest |> map mk_subst - in - Thm.instantiate (subst, []) thm - end - in - map instantiate paired - end - -fun unify_all_types ctxt ts = - let - val unif = Pattern.unify_types (Context.Proof ctxt) - fun aux (t1 :: t2 :: ts) env = aux (t2 :: ts) (unif (t1, t2) env) - | aux _ env = env - in - aux ts - end - -fun homogenize_raw_types ctxt terms = - let - val terms = map Logic.varify_types_global terms - - val get_head = fst o dest_Free o fst o strip_comb o fst o HOLogic.dest_eq o HOLogic.dest_Trueprop - val heads = map get_head terms - - fun typ_occurences head = - maps all_frees terms - |> filter (equal head o fst) - |> map snd - - val problem = map typ_occurences heads - val env = Envir.empty (maxidx_of_typs (flat problem)) - - val env' = fold (unify_all_types ctxt) problem env - - val solution = map_types (unvarify_typ o Envir.norm_type (Envir.type_env env')) - in - map solution terms - |> Syntax.check_terms ctxt (* fail early if something's wrong *) - end - -fun if_to_cond_simps thm = - case Thm.concl_of thm of - @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ _ $ (Const (@{const_name If}, _) $ _ $ _ $ _)) => - maps (fn s => if_to_cond_simps (s OF [thm])) @{thms if_to_cond_simps} - | _ => - [thm] \ No newline at end of file diff --git a/src/main/scala/inox/InoxContext.scala b/src/main/scala/inox/InoxContext.scala index fa49102840a559fbb0f3d30b827ac64547d902b4..1c3554235ab2dc9a8e721a7c4010850b9f822a8a 100644 --- a/src/main/scala/inox/InoxContext.scala +++ b/src/main/scala/inox/InoxContext.scala @@ -16,8 +16,10 @@ case class InoxContext( def build(opts: Seq[InoxOption[Any]]) = InoxContext(reporter, interruptManager, opts, timers) - def toSolver: solvers.SolverOptions = ??? - def toEvaluator: evaluators.EvaluatorOptions = ??? + def toSolver: solvers.SolverOptions = solvers.SolverOptions( + options.filter(opt => solvers.SolverOptions.options.exists(_ == opt.optionDef))) + def toEvaluator: evaluators.EvaluatorOptions = evaluators.EvaluatorOptions( + options.filter(opt => evaluators.EvaluatorOptions.options.exists(_ == opt.optionDef))) } object InoxContext { diff --git a/src/main/scala/inox/ast/Constructors.scala b/src/main/scala/inox/ast/Constructors.scala index 2ba2c15118fd6d4d7ef5b61b318a228b3acf0d1a..e9bf6c88568941cde347ea2f98810b6392ef121a 100644 --- a/src/main/scala/inox/ast/Constructors.scala +++ b/src/main/scala/inox/ast/Constructors.scala @@ -280,8 +280,4 @@ trait Constructors { IsInstanceOf(expr, tpe) } } - - def finiteLambda(cases: Seq[(Expr, Expr)], default: Expr, ft: FunctionType): Expr = { - ??? - } } diff --git a/src/main/scala/inox/evaluators/Evaluator.scala b/src/main/scala/inox/evaluators/Evaluator.scala index c7f271d2769467e7b9d05852ee57adcfdb734ca2..af3fc771fcfd6e516ea4177fec393e2cad57e4cb 100644 --- a/src/main/scala/inox/evaluators/Evaluator.scala +++ b/src/main/scala/inox/evaluators/Evaluator.scala @@ -9,8 +9,14 @@ case class EvaluatorOptions(options: Seq[InoxOption[Any]]) extends InoxOptions[E object EvaluatorOptions { def empty = EvaluatorOptions(Seq()) + + val options = Seq( + optIgnoreContracts + ) } +object optIgnoreContracts extends InoxFlagOptionDef("ignorecontracts", "Don't fail on invalid contracts during evaluation", false) + trait Evaluator { val program: Program val options: EvaluatorOptions diff --git a/src/main/scala/inox/evaluators/RecursiveEvaluator.scala b/src/main/scala/inox/evaluators/RecursiveEvaluator.scala index 983bc3a49c9583c96595a225f234767fa3e7129c..745b7e1e7a0a949979add45d19b88bc972282527 100644 --- a/src/main/scala/inox/evaluators/RecursiveEvaluator.scala +++ b/src/main/scala/inox/evaluators/RecursiveEvaluator.scala @@ -17,6 +17,8 @@ trait RecursiveEvaluator val name = "Recursive Evaluator" + lazy val ignoreContracts = options.findOptionOrDefault(optIgnoreContracts) + private def shift(b: BitSet, size: Int, i: Int): BitSet = b.map(_ + i).filter(bit => bit >= 1 && bit <= size) @@ -50,7 +52,7 @@ trait RecursiveEvaluator e(b)(rctx.withNewVar(i, first), gctx) case Assume(cond, body) => - if (e(cond) != BooleanLiteral(true)) + if (!ignoreContracts && e(cond) != BooleanLiteral(true)) throw RuntimeError("Assumption did not hold @" + expr.getPos) e(body) diff --git a/src/main/scala/inox/evaluators/SolvingEvaluator.scala b/src/main/scala/inox/evaluators/SolvingEvaluator.scala index 554f6a44a4bfd55580d32d9b888bc2b4519e5900..cbe03bda120b01fbf3ec4d0d6d5641c19c2f7cf8 100644 --- a/src/main/scala/inox/evaluators/SolvingEvaluator.scala +++ b/src/main/scala/inox/evaluators/SolvingEvaluator.scala @@ -12,7 +12,7 @@ trait SolvingEvaluator extends Evaluator { import program.trees._ import program.symbols._ - object optForallCache extends InoxOptionDef[MutableMap[program.trees.Forall, Boolean]] { + private object optForallCache extends InoxOptionDef[MutableMap[program.trees.Forall, Boolean]] { val parser = { (_: String) => throw FatalError("Unparsable option \"bankOption\"") } val name = "bank-option" val description = "Evaluation bank shared between solver and evaluator" diff --git a/src/main/scala/inox/solvers/Solver.scala b/src/main/scala/inox/solvers/Solver.scala index c85ed8688d578e091a1cc040f7f5897f766f8449..b6874bea60ef94735202f6963474757b8ee2b6b5 100644 --- a/src/main/scala/inox/solvers/Solver.scala +++ b/src/main/scala/inox/solvers/Solver.scala @@ -11,6 +11,15 @@ case class SolverOptions(options: Seq[InoxOption[Any]]) extends InoxOptions[Solv object SolverOptions { def empty = SolverOptions(Seq()) + + val options = Seq( + optCheckModels, + optSilentErrors, + unrolling.optUnrollFactor, + unrolling.optFeelingLucky, + unrolling.optUnrollCores, + smtlib.optCVC4Options + ) } case object DebugSectionSolver extends DebugSection("solver") diff --git a/src/main/scala/inox/solvers/smtlib/CVC4Target.scala b/src/main/scala/inox/solvers/smtlib/CVC4Target.scala index e9961b45169429b8a625e11b4b3b677952a3a0d4..b4a788bfe305f63a8019cf41d33f62acb87ad3c3 100644 --- a/src/main/scala/inox/solvers/smtlib/CVC4Target.scala +++ b/src/main/scala/inox/solvers/smtlib/CVC4Target.scala @@ -54,44 +54,18 @@ trait CVC4Target extends SMTLIBTarget { case (QualifiedIdentifier(SMTIdentifier(SSymbol("emptyset"), Seq()), _), Some(SetType(base))) => FiniteSet(Seq(), base) - case (FunctionApplication(QualifiedIdentifier(SMTIdentifier(SSymbol("const"), _), _), Seq(elem)), Some(tpe)) => - tpe match { - case ft @ FunctionType(from, to) => - finiteLambda(Seq.empty, fromSMT(elem, to), ft) - - case MapType(k, v) => - FiniteMap(Seq(), fromSMT(elem, v), k) - } - - case (FunctionApplication(SimpleSymbol(SSymbol("__array_store_all__")), Seq(_, elem)), Some(tpe)) => - tpe match { - case ft @ FunctionType(from, to) => - finiteLambda(Seq.empty, fromSMT(elem, to), ft) - - case MapType(k, v) => - FiniteMap(Seq(), fromSMT(elem, v), k) - } - - case (FunctionApplication(SimpleSymbol(SSymbol("store")), Seq(arr, key, elem)), Some(tpe)) => - tpe match { - case FunctionType(from, v) => - val Lambda(args, bd) = fromSMT(arr, otpe) - Lambda(args, IfExpr( - Equals( - tupleWrap(args.map(_.toVariable)), - fromSMT(key, tupleTypeWrap(from)) - ), - fromSMT(elem, v), - bd - )) - - case MapType(kT, vT) => - val FiniteMap(elems, default, _) = fromSMT(arr, otpe) - val newKey = fromSMT(key, kT) - val newV = fromSMT(elem, vT) - val newElems = elems.filterNot(_._1 == newKey) :+ (newKey -> newV) - FiniteMap(newElems, default, kT) - } + case (FunctionApplication(QualifiedIdentifier(SMTIdentifier(SSymbol("const"), _), _), Seq(elem)), Some(MapType(k, v))) => + FiniteMap(Seq(), fromSMT(elem, v), k) + + case (FunctionApplication(SimpleSymbol(SSymbol("__array_store_all__")), Seq(_, elem)), Some(MapType(k, v))) => + FiniteMap(Seq(), fromSMT(elem, v), k) + + case (FunctionApplication(SimpleSymbol(SSymbol("store")), Seq(arr, key, elem)), Some(MapType(kT, vT))) => + val FiniteMap(elems, default, _) = fromSMT(arr, otpe) + val newKey = fromSMT(key, kT) + val newV = fromSMT(elem, vT) + val newElems = elems.filterNot(_._1 == newKey) :+ (newKey -> newV) + FiniteMap(newElems, default, kT) case (FunctionApplication(SimpleSymbol(SSymbol("singleton")), elems), Some(SetType(base))) => FiniteSet(elems.map(fromSMT(_, base)), base) diff --git a/src/main/scala/inox/solvers/unrolling/UnrollingSolver.scala b/src/main/scala/inox/solvers/unrolling/UnrollingSolver.scala index 887e008442e78b99421f3e0470910f94c6e42992..9650c3903bcace2ad71b15955d1374cce682bbd9 100644 --- a/src/main/scala/inox/solvers/unrolling/UnrollingSolver.scala +++ b/src/main/scala/inox/solvers/unrolling/UnrollingSolver.scala @@ -12,7 +12,6 @@ import evaluators._ object optUnrollFactor extends InoxLongOptionDef("unrollfactor", "Number of unfoldings to perform in each unfold step", default = 1, "<PosInt>") object optFeelingLucky extends InoxFlagOptionDef("feelinglucky", "Use evaluator to find counter-examples early", false) object optUnrollCores extends InoxFlagOptionDef("unrollcores", "Use unsat-cores to drive unfolding while remaining fair", false) -object optAssumePre extends InoxFlagOptionDef("assumepre", "Assume precondition holds (pre && f(x) = body) when unfolding", false) trait AbstractUnrollingSolver extends Solver { @@ -42,12 +41,11 @@ trait AbstractUnrollingSolver type Cores = Set[Encoded] } - val unfoldFactor = options.findOptionOrDefault(optUnrollFactor) - val feelingLucky = options.findOptionOrDefault(optFeelingLucky) - val checkModels = options.findOptionOrDefault(optCheckModels) - val unrollUnsatCores = options.findOptionOrDefault(optUnrollCores) - val assumePreHolds = options.findOptionOrDefault(optAssumePre) - val silentErrors = options.findOptionOrDefault(optSilentErrors) + lazy val unfoldFactor = options.findOptionOrDefault(optUnrollFactor) + lazy val feelingLucky = options.findOptionOrDefault(optFeelingLucky) + lazy val checkModels = options.findOptionOrDefault(optCheckModels) + lazy val unrollUnsatCores = options.findOptionOrDefault(optUnrollCores) + lazy val silentErrors = options.findOptionOrDefault(optSilentErrors) def check(config: Configuration): config.Response[Model, Cores] = checkAssumptions(config)(Set.empty)