summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaulMeng <baolmeng@gmail.com>2016-04-20 14:43:18 -0500
committerPaulMeng <baolmeng@gmail.com>2016-04-20 14:43:18 -0500
commit904ffb6e73402bae537aa89e7fd8f0ab2e9d60e2 (patch)
treed96bb0c974bdea6170957d3e39d47a98f5c85ca0 /src
parenta0054e9cc78822416d745e955c30f69cbb2a3aa7 (diff)
update from the master
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am52
-rw-r--r--src/base/configuration.cpp12
-rw-r--r--src/base/configuration.h12
-rw-r--r--src/base/configuration_private.h12
-rw-r--r--src/base/cvc4_assert.cpp12
-rw-r--r--src/base/cvc4_assert.h12
-rw-r--r--src/base/exception.cpp12
-rw-r--r--src/base/exception.h12
-rw-r--r--src/base/listener.cpp14
-rw-r--r--src/base/listener.h12
-rw-r--r--src/base/modal_exception.h12
-rw-r--r--src/base/output.cpp12
-rw-r--r--src/base/output.h12
-rw-r--r--src/base/tls.h.in12
-rw-r--r--src/bindings/java_iterator_adapter.h12
-rw-r--r--src/bindings/java_stream_adapters.h12
-rw-r--r--src/bindings/swig.h12
-rw-r--r--src/compat/cvc3_compat.cpp15
-rw-r--r--src/compat/cvc3_compat.h12
-rw-r--r--src/context/backtrackable.h12
-rw-r--r--src/context/cdchunk_list.h12
-rw-r--r--src/context/cddense_set.h12
-rw-r--r--src/context/cdhashmap.h12
-rw-r--r--src/context/cdhashmap_forward.h12
-rw-r--r--src/context/cdhashset.h12
-rw-r--r--src/context/cdhashset_forward.h12
-rw-r--r--src/context/cdinsert_hashmap.h12
-rw-r--r--src/context/cdinsert_hashmap_forward.h12
-rw-r--r--src/context/cdlist.h12
-rw-r--r--src/context/cdlist_forward.h12
-rw-r--r--src/context/cdmaybe.h12
-rw-r--r--src/context/cdo.h12
-rw-r--r--src/context/cdqueue.h12
-rw-r--r--src/context/cdtrail_hashmap.h12
-rw-r--r--src/context/cdtrail_hashmap_forward.h12
-rw-r--r--src/context/cdtrail_queue.h12
-rw-r--r--src/context/cdvector.h12
-rw-r--r--src/context/context.cpp12
-rw-r--r--src/context/context.h12
-rw-r--r--src/context/context_mm.cpp12
-rw-r--r--src/context/context_mm.h12
-rw-r--r--src/context/stacking_vector.h12
-rw-r--r--src/decision/decision_attributes.h12
-rw-r--r--src/decision/decision_engine.cpp12
-rw-r--r--src/decision/decision_engine.h12
-rw-r--r--src/decision/decision_strategy.h12
-rw-r--r--src/decision/justification_heuristic.cpp12
-rw-r--r--src/decision/justification_heuristic.h12
-rw-r--r--src/expr/array.h12
-rw-r--r--src/expr/array_store_all.cpp12
-rw-r--r--src/expr/array_store_all.h12
-rw-r--r--src/expr/ascription_type.h12
-rw-r--r--src/expr/attribute.cpp12
-rw-r--r--src/expr/attribute.h12
-rw-r--r--src/expr/attribute_internals.h12
-rw-r--r--src/expr/attribute_unique_id.h12
-rw-r--r--src/expr/chain.h12
-rw-r--r--src/expr/convenience_node_builders.h12
-rw-r--r--src/expr/datatype.cpp76
-rw-r--r--src/expr/datatype.h29
-rw-r--r--src/expr/emptyset.cpp12
-rw-r--r--src/expr/emptyset.h12
-rw-r--r--src/expr/expr.i6
-rw-r--r--src/expr/expr_iomanip.cpp12
-rw-r--r--src/expr/expr_iomanip.h12
-rw-r--r--src/expr/expr_manager.i23
-rw-r--r--src/expr/expr_manager_scope.h12
-rw-r--r--src/expr/expr_manager_template.cpp19
-rw-r--r--src/expr/expr_manager_template.h15
-rw-r--r--src/expr/expr_stream.h12
-rw-r--r--src/expr/expr_template.cpp12
-rw-r--r--src/expr/expr_template.h12
-rw-r--r--src/expr/kind_map.h12
-rw-r--r--src/expr/kind_template.h12
-rw-r--r--src/expr/matcher.h12
-rw-r--r--src/expr/metakind_template.h12
-rw-r--r--src/expr/node.cpp12
-rw-r--r--src/expr/node.h12
-rw-r--r--src/expr/node_builder.h12
-rw-r--r--src/expr/node_manager.cpp110
-rw-r--r--src/expr/node_manager.h31
-rw-r--r--src/expr/node_manager_attributes.h18
-rw-r--r--src/expr/node_manager_listeners.cpp14
-rw-r--r--src/expr/node_manager_listeners.h12
-rw-r--r--src/expr/node_self_iterator.h12
-rw-r--r--src/expr/node_value.cpp12
-rw-r--r--src/expr/node_value.h12
-rw-r--r--src/expr/pickle_data.cpp12
-rw-r--r--src/expr/pickle_data.h12
-rw-r--r--src/expr/pickler.cpp12
-rw-r--r--src/expr/pickler.h12
-rw-r--r--src/expr/predicate.cpp12
-rw-r--r--src/expr/predicate.h12
-rw-r--r--src/expr/record.cpp12
-rw-r--r--src/expr/record.h12
-rw-r--r--src/expr/symbol_table.cpp12
-rw-r--r--src/expr/symbol_table.h12
-rw-r--r--src/expr/type.cpp23
-rw-r--r--src/expr/type.h31
-rw-r--r--src/expr/type_checker.h12
-rw-r--r--src/expr/type_checker_template.cpp12
-rw-r--r--src/expr/type_node.cpp249
-rw-r--r--src/expr/type_node.h14
-rw-r--r--src/expr/type_properties_template.h12
-rw-r--r--src/expr/uninterpreted_constant.cpp12
-rw-r--r--src/expr/uninterpreted_constant.h12
-rw-r--r--src/expr/variable_type_map.h12
-rw-r--r--src/include/cvc4.h12
-rw-r--r--src/include/cvc4_private.h12
-rw-r--r--src/include/cvc4_private_library.h12
-rw-r--r--src/include/cvc4_public.h12
-rw-r--r--src/include/cvc4parser_private.h12
-rw-r--r--src/include/cvc4parser_public.h12
-rw-r--r--src/lib/clock_gettime.c14
-rw-r--r--src/lib/clock_gettime.h12
-rw-r--r--src/lib/ffs.c12
-rw-r--r--src/lib/ffs.h12
-rw-r--r--src/lib/replacements.h12
-rw-r--r--src/lib/strtok_r.c12
-rw-r--r--src/lib/strtok_r.h12
-rw-r--r--src/main/command_executor.cpp16
-rw-r--r--src/main/command_executor.h12
-rw-r--r--src/main/command_executor_portfolio.cpp15
-rw-r--r--src/main/command_executor_portfolio.h12
-rw-r--r--src/main/driver_unified.cpp14
-rw-r--r--src/main/interactive_shell.cpp12
-rw-r--r--src/main/interactive_shell.h12
-rw-r--r--src/main/main.cpp12
-rw-r--r--src/main/main.h12
-rw-r--r--src/main/portfolio.cpp12
-rw-r--r--src/main/portfolio.h12
-rw-r--r--src/main/portfolio_util.cpp14
-rw-r--r--src/main/portfolio_util.h12
-rw-r--r--src/main/util.cpp12
-rw-r--r--src/options/Makefile.am3
-rw-r--r--src/options/argument_extender.cpp74
-rw-r--r--src/options/argument_extender.h110
-rw-r--r--src/options/argument_extender_implementation.cpp114
-rw-r--r--src/options/argument_extender_implementation.h115
-rw-r--r--src/options/arith_heuristic_pivot_rule.cpp12
-rw-r--r--src/options/arith_heuristic_pivot_rule.h12
-rw-r--r--src/options/arith_options3
-rw-r--r--src/options/arith_propagation_mode.cpp12
-rw-r--r--src/options/arith_propagation_mode.h12
-rw-r--r--src/options/arith_unate_lemma_mode.cpp12
-rw-r--r--src/options/arith_unate_lemma_mode.h12
-rw-r--r--src/options/base_handlers.h12
-rw-r--r--src/options/base_options_template.cpp12
-rw-r--r--src/options/base_options_template.h12
-rw-r--r--src/options/boolean_term_conversion_mode.cpp12
-rw-r--r--src/options/boolean_term_conversion_mode.h12
-rw-r--r--src/options/bv_bitblast_mode.cpp14
-rw-r--r--src/options/bv_bitblast_mode.h14
-rw-r--r--src/options/bv_options20
-rw-r--r--src/options/datatypes_options4
-rw-r--r--src/options/decision_mode.cpp12
-rw-r--r--src/options/decision_mode.h12
-rw-r--r--src/options/decision_weight.h12
-rw-r--r--src/options/didyoumean.cpp12
-rw-r--r--src/options/didyoumean.h12
-rw-r--r--src/options/didyoumean_test.cpp12
-rw-r--r--src/options/language.cpp12
-rw-r--r--src/options/language.h12
-rw-r--r--src/options/main_options4
-rwxr-xr-xsrc/options/mkoptions14
-rw-r--r--src/options/open_ostream.cpp12
-rw-r--r--src/options/open_ostream.h14
-rw-r--r--src/options/option_exception.h12
-rw-r--r--src/options/options.h45
-rw-r--r--src/options/options_get_option_template.cpp14
-rw-r--r--src/options/options_handler.cpp97
-rw-r--r--src/options/options_handler.h16
-rw-r--r--src/options/options_holder_template.h12
-rw-r--r--src/options/options_public_functions.cpp14
-rw-r--r--src/options/options_set_option_template.cpp14
-rw-r--r--src/options/options_template.cpp345
-rw-r--r--src/options/printer_modes.cpp12
-rw-r--r--src/options/printer_modes.h12
-rw-r--r--src/options/quantifiers_modes.cpp12
-rw-r--r--src/options/quantifiers_modes.h38
-rw-r--r--src/options/quantifiers_options36
-rw-r--r--src/options/set_language.cpp14
-rw-r--r--src/options/set_language.h14
-rw-r--r--src/options/sets_options8
-rw-r--r--src/options/simplification_mode.cpp12
-rw-r--r--src/options/simplification_mode.h12
-rw-r--r--src/options/strings_options12
-rw-r--r--src/options/theoryof_mode.cpp17
-rw-r--r--src/options/theoryof_mode.h12
-rw-r--r--src/options/ufss_mode.h12
-rw-r--r--src/parser/antlr_input.cpp12
-rw-r--r--src/parser/antlr_input.h12
-rw-r--r--src/parser/antlr_line_buffered_input.cpp12
-rw-r--r--src/parser/antlr_line_buffered_input.h12
-rw-r--r--src/parser/antlr_tracing.h12
-rw-r--r--src/parser/antlr_undefines.h12
-rw-r--r--src/parser/bounded_token_buffer.cpp12
-rw-r--r--src/parser/bounded_token_buffer.h12
-rw-r--r--src/parser/bounded_token_factory.cpp12
-rw-r--r--src/parser/bounded_token_factory.h12
-rw-r--r--src/parser/cvc/Cvc.g89
-rw-r--r--src/parser/cvc/cvc_input.cpp12
-rw-r--r--src/parser/cvc/cvc_input.h12
-rw-r--r--src/parser/input.cpp12
-rw-r--r--src/parser/input.h12
-rw-r--r--src/parser/memory_mapped_input_buffer.cpp12
-rw-r--r--src/parser/memory_mapped_input_buffer.h12
-rw-r--r--src/parser/parser.cpp12
-rw-r--r--src/parser/parser.h12
-rw-r--r--src/parser/parser_builder.cpp12
-rw-r--r--src/parser/parser_builder.h12
-rw-r--r--src/parser/parser_exception.h12
-rw-r--r--src/parser/smt1/Smt1.g12
-rw-r--r--src/parser/smt1/smt1.cpp12
-rw-r--r--src/parser/smt1/smt1.h12
-rw-r--r--src/parser/smt1/smt1_input.cpp12
-rw-r--r--src/parser/smt1/smt1_input.h12
-rw-r--r--src/parser/smt2/Smt2.g24
-rw-r--r--src/parser/smt2/smt2.cpp13
-rw-r--r--src/parser/smt2/smt2.h12
-rw-r--r--src/parser/smt2/smt2_input.cpp12
-rw-r--r--src/parser/smt2/smt2_input.h12
-rw-r--r--src/parser/smt2/sygus_input.cpp12
-rw-r--r--src/parser/smt2/sygus_input.h12
-rw-r--r--src/parser/tptp/Tptp.g12
-rw-r--r--src/parser/tptp/tptp.cpp12
-rw-r--r--src/parser/tptp/tptp.h12
-rw-r--r--src/parser/tptp/tptp_input.cpp12
-rw-r--r--src/parser/tptp/tptp_input.h12
-rw-r--r--src/printer/ast/ast_printer.cpp12
-rw-r--r--src/printer/ast/ast_printer.h12
-rw-r--r--src/printer/cvc/cvc_printer.cpp19
-rw-r--r--src/printer/cvc/cvc_printer.h12
-rw-r--r--src/printer/dagification_visitor.cpp12
-rw-r--r--src/printer/dagification_visitor.h12
-rw-r--r--src/printer/printer.cpp12
-rw-r--r--src/printer/printer.h12
-rw-r--r--src/printer/smt1/smt1_printer.cpp12
-rw-r--r--src/printer/smt1/smt1_printer.h12
-rw-r--r--src/printer/smt2/smt2_printer.cpp20
-rw-r--r--src/printer/smt2/smt2_printer.h12
-rw-r--r--src/printer/tptp/tptp_printer.cpp12
-rw-r--r--src/printer/tptp/tptp_printer.h12
-rw-r--r--src/proof/arith_proof.cpp833
-rw-r--r--src/proof/arith_proof.h82
-rw-r--r--src/proof/array_proof.cpp1269
-rw-r--r--src/proof/array_proof.h91
-rw-r--r--src/proof/bitvector_proof.cpp94
-rw-r--r--src/proof/bitvector_proof.h28
-rw-r--r--src/proof/clause_id.h33
-rw-r--r--src/proof/cnf_proof.cpp108
-rw-r--r--src/proof/cnf_proof.h45
-rw-r--r--src/proof/proof.h12
-rw-r--r--src/proof/proof_manager.cpp206
-rw-r--r--src/proof/proof_manager.h58
-rw-r--r--src/proof/proof_utils.cpp26
-rw-r--r--src/proof/proof_utils.h26
-rw-r--r--src/proof/sat_proof.h29
-rw-r--r--src/proof/sat_proof_implementation.h217
-rw-r--r--src/proof/skolemization_manager.cpp68
-rw-r--r--src/proof/skolemization_manager.h55
-rw-r--r--src/proof/theory_proof.cpp244
-rw-r--r--src/proof/theory_proof.h166
-rw-r--r--src/proof/uf_proof.cpp345
-rw-r--r--src/proof/uf_proof.h24
-rw-r--r--src/proof/unsat_core.cpp12
-rw-r--r--src/proof/unsat_core.h12
-rw-r--r--src/prop/bvminisat/bvminisat.cpp1
-rw-r--r--src/prop/bvminisat/bvminisat.h1
-rw-r--r--src/prop/bvminisat/core/Solver.cc5
-rw-r--r--src/prop/bvminisat/core/Solver.h15
-rw-r--r--src/prop/bvminisat/simp/SimpSolver.cc3
-rw-r--r--src/prop/bvminisat/simp/SimpSolver.h1
-rw-r--r--src/prop/cnf_stream.cpp27
-rw-r--r--src/prop/cnf_stream.h24
-rw-r--r--src/prop/minisat/core/Solver.cc79
-rw-r--r--src/prop/minisat/core/Solver.h2
-rw-r--r--src/prop/minisat/minisat.cpp1
-rw-r--r--src/prop/minisat/simp/SimpSolver.cc4
-rw-r--r--src/prop/minisat/simp/SimpSolver.h1
-rw-r--r--src/prop/prop_engine.cpp15
-rw-r--r--src/prop/prop_engine.h14
-rw-r--r--src/prop/registrar.h12
-rw-r--r--src/prop/sat_solver.h15
-rw-r--r--src/prop/sat_solver_factory.cpp12
-rw-r--r--src/prop/sat_solver_factory.h12
-rw-r--r--src/prop/sat_solver_types.h12
-rw-r--r--src/prop/theory_proxy.cpp39
-rw-r--r--src/prop/theory_proxy.h12
-rw-r--r--src/smt/boolean_terms.cpp32
-rw-r--r--src/smt/boolean_terms.h12
-rw-r--r--src/smt/command.cpp119
-rw-r--r--src/smt/command.h49
-rw-r--r--src/smt/command_list.cpp12
-rw-r--r--src/smt/command_list.h12
-rw-r--r--src/smt/dump.cpp15
-rw-r--r--src/smt/dump.h12
-rw-r--r--src/smt/ite_removal.cpp12
-rw-r--r--src/smt/ite_removal.h12
-rw-r--r--src/smt/logic_exception.h12
-rw-r--r--src/smt/logic_request.cpp12
-rw-r--r--src/smt/logic_request.h12
-rw-r--r--src/smt/managed_ostreams.cpp12
-rw-r--r--src/smt/managed_ostreams.h12
-rw-r--r--src/smt/model.cpp12
-rw-r--r--src/smt/model.h12
-rw-r--r--src/smt/model_postprocessor.cpp12
-rw-r--r--src/smt/model_postprocessor.h12
-rw-r--r--src/smt/smt_engine.cpp420
-rw-r--r--src/smt/smt_engine.h29
-rw-r--r--src/smt/smt_engine_check_proof.cpp35
-rw-r--r--src/smt/smt_engine_scope.cpp12
-rw-r--r--src/smt/smt_engine_scope.h12
-rw-r--r--src/smt/smt_statistics_registry.cpp14
-rw-r--r--src/smt/smt_statistics_registry.h14
-rw-r--r--src/smt/update_ostream.h12
-rw-r--r--src/smt_util/boolean_simplification.cpp12
-rw-r--r--src/smt_util/boolean_simplification.h12
-rw-r--r--src/smt_util/lemma_channels.cpp12
-rw-r--r--src/smt_util/lemma_channels.h12
-rw-r--r--src/smt_util/lemma_input_channel.h12
-rw-r--r--src/smt_util/lemma_output_channel.h12
-rw-r--r--src/smt_util/nary_builder.cpp12
-rw-r--r--src/smt_util/nary_builder.h12
-rw-r--r--src/smt_util/node_visitor.h12
-rw-r--r--src/theory/arith/approx_simplex.cpp12
-rw-r--r--src/theory/arith/approx_simplex.h12
-rw-r--r--src/theory/arith/arith_ite_utils.cpp12
-rw-r--r--src/theory/arith/arith_ite_utils.h12
-rw-r--r--src/theory/arith/arith_rewriter.cpp12
-rw-r--r--src/theory/arith/arith_rewriter.h12
-rw-r--r--src/theory/arith/arith_static_learner.cpp12
-rw-r--r--src/theory/arith/arith_static_learner.h12
-rw-r--r--src/theory/arith/arith_utilities.h12
-rw-r--r--src/theory/arith/arithvar.cpp12
-rw-r--r--src/theory/arith/arithvar.h12
-rw-r--r--src/theory/arith/arithvar_node_map.h12
-rw-r--r--src/theory/arith/attempt_solution_simplex.cpp12
-rw-r--r--src/theory/arith/attempt_solution_simplex.h12
-rw-r--r--src/theory/arith/bound_counts.h12
-rw-r--r--src/theory/arith/callbacks.cpp12
-rw-r--r--src/theory/arith/callbacks.h12
-rw-r--r--src/theory/arith/congruence_manager.cpp107
-rw-r--r--src/theory/arith/congruence_manager.h27
-rw-r--r--src/theory/arith/constraint.cpp12
-rw-r--r--src/theory/arith/constraint.h12
-rw-r--r--src/theory/arith/constraint_forward.h12
-rw-r--r--src/theory/arith/cut_log.cpp12
-rw-r--r--src/theory/arith/cut_log.h12
-rw-r--r--src/theory/arith/delta_rational.cpp12
-rw-r--r--src/theory/arith/delta_rational.h12
-rw-r--r--src/theory/arith/dio_solver.cpp12
-rw-r--r--src/theory/arith/dio_solver.h12
-rw-r--r--src/theory/arith/dual_simplex.cpp12
-rw-r--r--src/theory/arith/dual_simplex.h12
-rw-r--r--src/theory/arith/error_set.cpp12
-rw-r--r--src/theory/arith/error_set.h12
-rw-r--r--src/theory/arith/fc_simplex.cpp12
-rw-r--r--src/theory/arith/fc_simplex.h12
-rw-r--r--src/theory/arith/infer_bounds.cpp12
-rw-r--r--src/theory/arith/infer_bounds.h12
-rw-r--r--src/theory/arith/linear_equality.cpp12
-rw-r--r--src/theory/arith/linear_equality.h12
-rw-r--r--src/theory/arith/matrix.cpp12
-rw-r--r--src/theory/arith/matrix.h12
-rw-r--r--src/theory/arith/normal_form.cpp12
-rw-r--r--src/theory/arith/normal_form.h12
-rw-r--r--src/theory/arith/partial_model.cpp12
-rw-r--r--src/theory/arith/partial_model.h12
-rw-r--r--src/theory/arith/pseudoboolean_proc.cpp12
-rw-r--r--src/theory/arith/pseudoboolean_proc.h12
-rw-r--r--src/theory/arith/simplex.cpp12
-rw-r--r--src/theory/arith/simplex.h12
-rw-r--r--src/theory/arith/simplex_update.cpp12
-rw-r--r--src/theory/arith/simplex_update.h12
-rw-r--r--src/theory/arith/soi_simplex.cpp12
-rw-r--r--src/theory/arith/soi_simplex.h12
-rw-r--r--src/theory/arith/tableau.cpp12
-rw-r--r--src/theory/arith/tableau.h12
-rw-r--r--src/theory/arith/tableau_sizes.cpp12
-rw-r--r--src/theory/arith/tableau_sizes.h12
-rw-r--r--src/theory/arith/theory_arith.cpp12
-rw-r--r--src/theory/arith/theory_arith.h12
-rw-r--r--src/theory/arith/theory_arith_private.cpp12
-rw-r--r--src/theory/arith/theory_arith_private.h12
-rw-r--r--src/theory/arith/theory_arith_private_forward.h12
-rw-r--r--src/theory/arith/theory_arith_type_rules.h12
-rw-r--r--src/theory/arith/type_enumerator.h12
-rw-r--r--src/theory/arrays/array_info.cpp36
-rw-r--r--src/theory/arrays/array_info.h15
-rw-r--r--src/theory/arrays/array_proof_reconstruction.cpp134
-rw-r--r--src/theory/arrays/array_proof_reconstruction.h58
-rw-r--r--src/theory/arrays/kinds5
-rw-r--r--src/theory/arrays/static_fact_manager.cpp12
-rw-r--r--src/theory/arrays/static_fact_manager.h12
-rw-r--r--src/theory/arrays/theory_arrays.cpp193
-rw-r--r--src/theory/arrays/theory_arrays.h30
-rw-r--r--src/theory/arrays/theory_arrays_rewriter.cpp12
-rw-r--r--src/theory/arrays/theory_arrays_rewriter.h12
-rw-r--r--src/theory/arrays/theory_arrays_type_rules.h21
-rw-r--r--src/theory/arrays/type_enumerator.h12
-rw-r--r--src/theory/arrays/union_find.cpp12
-rw-r--r--src/theory/arrays/union_find.h12
-rw-r--r--src/theory/atom_requests.cpp12
-rw-r--r--src/theory/atom_requests.h12
-rw-r--r--src/theory/booleans/circuit_propagator.cpp12
-rw-r--r--src/theory/booleans/circuit_propagator.h12
-rw-r--r--src/theory/booleans/theory_bool.cpp12
-rw-r--r--src/theory/booleans/theory_bool.h12
-rw-r--r--src/theory/booleans/theory_bool_rewriter.cpp12
-rw-r--r--src/theory/booleans/theory_bool_rewriter.h12
-rw-r--r--src/theory/booleans/theory_bool_type_rules.h12
-rw-r--r--src/theory/booleans/type_enumerator.h12
-rw-r--r--src/theory/builtin/theory_builtin.cpp12
-rw-r--r--src/theory/builtin/theory_builtin.h12
-rw-r--r--src/theory/builtin/theory_builtin_rewriter.cpp12
-rw-r--r--src/theory/builtin/theory_builtin_rewriter.h12
-rw-r--r--src/theory/builtin/theory_builtin_type_rules.h12
-rw-r--r--src/theory/builtin/type_enumerator.h12
-rw-r--r--src/theory/bv/abstraction.cpp12
-rw-r--r--src/theory/bv/abstraction.h12
-rw-r--r--src/theory/bv/aig_bitblaster.cpp12
-rw-r--r--src/theory/bv/bitblast_strategies_template.h12
-rw-r--r--src/theory/bv/bitblast_utils.h12
-rw-r--r--src/theory/bv/bitblaster_template.h14
-rw-r--r--src/theory/bv/bv_eager_solver.cpp12
-rw-r--r--src/theory/bv/bv_eager_solver.h12
-rw-r--r--src/theory/bv/bv_inequality_graph.cpp12
-rw-r--r--src/theory/bv/bv_inequality_graph.h12
-rw-r--r--src/theory/bv/bv_quick_check.cpp12
-rw-r--r--src/theory/bv/bv_quick_check.h12
-rw-r--r--src/theory/bv/bv_subtheory.h12
-rw-r--r--src/theory/bv/bv_subtheory_algebraic.cpp12
-rw-r--r--src/theory/bv/bv_subtheory_algebraic.h12
-rw-r--r--src/theory/bv/bv_subtheory_bitblast.cpp12
-rw-r--r--src/theory/bv/bv_subtheory_bitblast.h12
-rw-r--r--src/theory/bv/bv_subtheory_core.cpp12
-rw-r--r--src/theory/bv/bv_subtheory_core.h12
-rw-r--r--src/theory/bv/bv_subtheory_inequality.cpp12
-rw-r--r--src/theory/bv/bv_subtheory_inequality.h12
-rw-r--r--src/theory/bv/bv_to_bool.cpp12
-rw-r--r--src/theory/bv/bv_to_bool.h12
-rw-r--r--src/theory/bv/bvintropow2.cpp12
-rw-r--r--src/theory/bv/bvintropow2.h12
-rw-r--r--src/theory/bv/cd_set_collection.h12
-rw-r--r--src/theory/bv/eager_bitblaster.cpp30
-rw-r--r--src/theory/bv/lazy_bitblaster.cpp68
-rw-r--r--src/theory/bv/slicer.cpp12
-rw-r--r--src/theory/bv/slicer.h12
-rw-r--r--src/theory/bv/theory_bv.cpp12
-rw-r--r--src/theory/bv/theory_bv.h12
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules.h12
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h12
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_core.h12
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_normalization.h12
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h12
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_simplification.h12
-rw-r--r--src/theory/bv/theory_bv_rewriter.cpp12
-rw-r--r--src/theory/bv/theory_bv_rewriter.h12
-rw-r--r--src/theory/bv/theory_bv_type_rules.h12
-rw-r--r--src/theory/bv/theory_bv_utils.cpp12
-rw-r--r--src/theory/bv/theory_bv_utils.h12
-rw-r--r--src/theory/bv/type_enumerator.h12
-rw-r--r--src/theory/datatypes/datatypes_rewriter.h44
-rw-r--r--src/theory/datatypes/datatypes_sygus.cpp14
-rw-r--r--src/theory/datatypes/datatypes_sygus.h14
-rw-r--r--src/theory/datatypes/kinds22
-rw-r--r--src/theory/datatypes/theory_datatypes.cpp184
-rw-r--r--src/theory/datatypes/theory_datatypes.h30
-rw-r--r--src/theory/datatypes/theory_datatypes_type_rules.h73
-rw-r--r--src/theory/datatypes/type_enumerator.cpp12
-rw-r--r--src/theory/datatypes/type_enumerator.h98
-rw-r--r--src/theory/example/ecdata.cpp12
-rw-r--r--src/theory/example/ecdata.h12
-rw-r--r--src/theory/example/theory_uf_tim.cpp12
-rw-r--r--src/theory/example/theory_uf_tim.h12
-rw-r--r--src/theory/fp/theory_fp.cpp17
-rw-r--r--src/theory/fp/theory_fp.h17
-rw-r--r--src/theory/fp/theory_fp_rewriter.cpp13
-rw-r--r--src/theory/fp/theory_fp_rewriter.h17
-rw-r--r--src/theory/fp/theory_fp_type_rules.h17
-rw-r--r--src/theory/idl/idl_assertion.cpp12
-rw-r--r--src/theory/idl/idl_assertion.h12
-rw-r--r--src/theory/idl/idl_assertion_db.cpp12
-rw-r--r--src/theory/idl/idl_assertion_db.h12
-rw-r--r--src/theory/idl/idl_model.cpp12
-rw-r--r--src/theory/idl/idl_model.h12
-rw-r--r--src/theory/idl/theory_idl.cpp12
-rw-r--r--src/theory/idl/theory_idl.h12
-rw-r--r--src/theory/interrupted.h12
-rw-r--r--src/theory/ite_utilities.cpp243
-rw-r--r--src/theory/ite_utilities.h41
-rw-r--r--src/theory/logic_info.cpp12
-rw-r--r--src/theory/logic_info.h12
-rw-r--r--src/theory/output_channel.h13
-rw-r--r--src/theory/quantifiers/alpha_equivalence.cpp38
-rw-r--r--src/theory/quantifiers/alpha_equivalence.h20
-rw-r--r--src/theory/quantifiers/ambqi_builder.cpp16
-rw-r--r--src/theory/quantifiers/ambqi_builder.h12
-rw-r--r--src/theory/quantifiers/anti_skolem.cpp269
-rw-r--r--src/theory/quantifiers/anti_skolem.h75
-rw-r--r--src/theory/quantifiers/bounded_integers.cpp12
-rw-r--r--src/theory/quantifiers/bounded_integers.h12
-rw-r--r--src/theory/quantifiers/candidate_generator.cpp134
-rw-r--r--src/theory/quantifiers/candidate_generator.h28
-rw-r--r--src/theory/quantifiers/ce_guided_instantiation.cpp104
-rw-r--r--src/theory/quantifiers/ce_guided_instantiation.h50
-rw-r--r--src/theory/quantifiers/ce_guided_single_inv.cpp147
-rw-r--r--src/theory/quantifiers/ce_guided_single_inv.h83
-rw-r--r--src/theory/quantifiers/ce_guided_single_inv_ei.cpp12
-rw-r--r--src/theory/quantifiers/ce_guided_single_inv_ei.h12
-rw-r--r--src/theory/quantifiers/ce_guided_single_inv_sol.cpp14
-rw-r--r--src/theory/quantifiers/ce_guided_single_inv_sol.h12
-rw-r--r--src/theory/quantifiers/ceg_instantiator.cpp310
-rw-r--r--src/theory/quantifiers/ceg_instantiator.h25
-rw-r--r--src/theory/quantifiers/conjecture_generator.cpp37
-rw-r--r--src/theory/quantifiers/conjecture_generator.h14
-rw-r--r--src/theory/quantifiers/equality_infer.cpp427
-rw-r--r--src/theory/quantifiers/equality_infer.h103
-rw-r--r--src/theory/quantifiers/first_order_model.cpp127
-rw-r--r--src/theory/quantifiers/first_order_model.h34
-rw-r--r--src/theory/quantifiers/full_model_check.cpp96
-rw-r--r--src/theory/quantifiers/full_model_check.h12
-rw-r--r--src/theory/quantifiers/fun_def_engine.cpp14
-rw-r--r--src/theory/quantifiers/fun_def_engine.h12
-rw-r--r--src/theory/quantifiers/fun_def_process.cpp12
-rw-r--r--src/theory/quantifiers/fun_def_process.h12
-rw-r--r--src/theory/quantifiers/inst_match.cpp131
-rw-r--r--src/theory/quantifiers/inst_match.h74
-rw-r--r--src/theory/quantifiers/inst_match_generator.cpp207
-rw-r--r--src/theory/quantifiers/inst_match_generator.h17
-rw-r--r--src/theory/quantifiers/inst_propagator.cpp761
-rw-r--r--src/theory/quantifiers/inst_propagator.h163
-rw-r--r--src/theory/quantifiers/inst_strategy_cbqi.cpp130
-rw-r--r--src/theory/quantifiers/inst_strategy_cbqi.h18
-rw-r--r--src/theory/quantifiers/inst_strategy_e_matching.cpp197
-rw-r--r--src/theory/quantifiers/inst_strategy_e_matching.h18
-rw-r--r--src/theory/quantifiers/instantiation_engine.cpp61
-rw-r--r--src/theory/quantifiers/instantiation_engine.h15
-rw-r--r--src/theory/quantifiers/local_theory_ext.cpp125
-rw-r--r--src/theory/quantifiers/local_theory_ext.h16
-rw-r--r--src/theory/quantifiers/macros.cpp86
-rw-r--r--src/theory/quantifiers/macros.h12
-rw-r--r--src/theory/quantifiers/model_builder.cpp59
-rw-r--r--src/theory/quantifiers/model_builder.h12
-rw-r--r--src/theory/quantifiers/model_engine.cpp113
-rw-r--r--src/theory/quantifiers/model_engine.h12
-rw-r--r--src/theory/quantifiers/quant_conflict_find.cpp437
-rw-r--r--src/theory/quantifiers/quant_conflict_find.h53
-rw-r--r--src/theory/quantifiers/quant_equality_engine.cpp151
-rw-r--r--src/theory/quantifiers/quant_equality_engine.h21
-rw-r--r--src/theory/quantifiers/quant_split.cpp134
-rw-r--r--src/theory/quantifiers/quant_split.h54
-rw-r--r--src/theory/quantifiers/quant_util.cpp147
-rw-r--r--src/theory/quantifiers/quant_util.h76
-rw-r--r--src/theory/quantifiers/quantifiers_attributes.cpp22
-rw-r--r--src/theory/quantifiers/quantifiers_attributes.h14
-rw-r--r--src/theory/quantifiers/quantifiers_rewriter.cpp590
-rw-r--r--src/theory/quantifiers/quantifiers_rewriter.h32
-rw-r--r--src/theory/quantifiers/relevant_domain.cpp19
-rw-r--r--src/theory/quantifiers/relevant_domain.h19
-rw-r--r--src/theory/quantifiers/rewrite_engine.cpp32
-rw-r--r--src/theory/quantifiers/rewrite_engine.h12
-rw-r--r--src/theory/quantifiers/symmetry_breaking.cpp12
-rw-r--r--src/theory/quantifiers/symmetry_breaking.h12
-rw-r--r--src/theory/quantifiers/term_database.cpp627
-rw-r--r--src/theory/quantifiers/term_database.h164
-rw-r--r--src/theory/quantifiers/theory_quantifiers.cpp14
-rw-r--r--src/theory/quantifiers/theory_quantifiers.h12
-rw-r--r--src/theory/quantifiers/theory_quantifiers_type_rules.h12
-rw-r--r--src/theory/quantifiers/trigger.cpp447
-rw-r--r--src/theory/quantifiers/trigger.h151
-rw-r--r--src/theory/quantifiers_engine.cpp746
-rw-r--r--src/theory/quantifiers_engine.h153
-rw-r--r--src/theory/rep_set.cpp12
-rw-r--r--src/theory/rep_set.h12
-rw-r--r--src/theory/rewriter.cpp12
-rw-r--r--src/theory/rewriter.h12
-rw-r--r--src/theory/rewriter_attributes.h12
-rw-r--r--src/theory/rewriter_tables_template.h12
-rw-r--r--src/theory/sets/card_unused_implementation.cpp312
-rw-r--r--src/theory/sets/expr_patterns.h16
-rw-r--r--src/theory/sets/kinds5
-rw-r--r--src/theory/sets/normal_form.h12
-rw-r--r--src/theory/sets/scrutinize.h12
-rw-r--r--src/theory/sets/term_info.h12
-rw-r--r--src/theory/sets/theory_sets.cpp16
-rw-r--r--src/theory/sets/theory_sets.h14
-rw-r--r--src/theory/sets/theory_sets_private.cpp1218
-rw-r--r--src/theory/sets/theory_sets_private.h104
-rw-r--r--src/theory/sets/theory_sets_rewriter.cpp409
-rw-r--r--src/theory/sets/theory_sets_rewriter.h16
-rw-r--r--src/theory/sets/theory_sets_type_enumerator.h12
-rw-r--r--src/theory/sets/theory_sets_type_rules.h32
-rw-r--r--src/theory/shared_terms_database.cpp14
-rw-r--r--src/theory/shared_terms_database.h12
-rw-r--r--src/theory/sort_inference.cpp584
-rw-r--r--src/theory/sort_inference.h19
-rw-r--r--src/theory/strings/regexp_operation.cpp12
-rw-r--r--src/theory/strings/regexp_operation.h12
-rw-r--r--src/theory/strings/theory_strings.cpp883
-rw-r--r--src/theory/strings/theory_strings.h49
-rw-r--r--src/theory/strings/theory_strings_preprocess.cpp12
-rw-r--r--src/theory/strings/theory_strings_preprocess.h12
-rw-r--r--src/theory/strings/theory_strings_rewriter.cpp12
-rw-r--r--src/theory/strings/theory_strings_rewriter.h12
-rw-r--r--src/theory/strings/theory_strings_type_rules.h38
-rw-r--r--src/theory/strings/type_enumerator.h12
-rw-r--r--src/theory/substitutions.cpp12
-rw-r--r--src/theory/substitutions.h12
-rw-r--r--src/theory/term_registration_visitor.cpp12
-rw-r--r--src/theory/term_registration_visitor.h12
-rw-r--r--src/theory/theory.cpp16
-rw-r--r--src/theory/theory.h16
-rw-r--r--src/theory/theory_engine.cpp85
-rw-r--r--src/theory/theory_engine.h45
-rw-r--r--src/theory/theory_model.cpp16
-rw-r--r--src/theory/theory_model.h12
-rw-r--r--src/theory/theory_registrar.h12
-rw-r--r--src/theory/theory_test_utils.h12
-rw-r--r--src/theory/theory_traits_template.h12
-rw-r--r--src/theory/type_enumerator.h12
-rw-r--r--src/theory/type_enumerator_template.cpp12
-rw-r--r--src/theory/uf/equality_engine.cpp210
-rw-r--r--src/theory/uf/equality_engine.h55
-rw-r--r--src/theory/uf/equality_engine_types.h26
-rw-r--r--src/theory/uf/symmetry_breaker.cpp12
-rw-r--r--src/theory/uf/symmetry_breaker.h12
-rw-r--r--src/theory/uf/theory_uf.cpp27
-rw-r--r--src/theory/uf/theory_uf.h14
-rw-r--r--src/theory/uf/theory_uf_model.cpp12
-rw-r--r--src/theory/uf/theory_uf_model.h12
-rw-r--r--src/theory/uf/theory_uf_rewriter.h12
-rw-r--r--src/theory/uf/theory_uf_strong_solver.cpp561
-rw-r--r--src/theory/uf/theory_uf_strong_solver.h215
-rw-r--r--src/theory/uf/theory_uf_type_rules.h12
-rw-r--r--src/theory/unconstrained_simplifier.cpp12
-rw-r--r--src/theory/unconstrained_simplifier.h12
-rw-r--r--src/theory/valuation.cpp12
-rw-r--r--src/theory/valuation.h12
-rw-r--r--src/util/abstract_value.cpp12
-rw-r--r--src/util/abstract_value.h12
-rw-r--r--src/util/bin_heap.h12
-rw-r--r--src/util/bitvector.h12
-rw-r--r--src/util/bool.h12
-rw-r--r--src/util/cache.h12
-rw-r--r--src/util/cardinality.cpp12
-rw-r--r--src/util/cardinality.h12
-rw-r--r--src/util/debug.h12
-rw-r--r--src/util/dense_map.h12
-rw-r--r--src/util/divisible.cpp12
-rw-r--r--src/util/divisible.h12
-rw-r--r--src/util/dynamic_array.h12
-rw-r--r--src/util/floatingpoint.cpp13
-rw-r--r--src/util/floatingpoint.h13
-rw-r--r--src/util/gmp_util.h12
-rw-r--r--src/util/hash.h12
-rw-r--r--src/util/index.h12
-rw-r--r--src/util/integer.h.in12
-rw-r--r--src/util/integer_cln_imp.cpp12
-rw-r--r--src/util/integer_cln_imp.h12
-rw-r--r--src/util/integer_gmp_imp.cpp12
-rw-r--r--src/util/integer_gmp_imp.h12
-rw-r--r--src/util/maybe.h12
-rw-r--r--src/util/ntuple.h12
-rw-r--r--src/util/proof.h12
-rw-r--r--src/util/rational.h.in12
-rw-r--r--src/util/rational_cln_imp.cpp12
-rw-r--r--src/util/rational_cln_imp.h12
-rw-r--r--src/util/rational_gmp_imp.cpp12
-rw-r--r--src/util/rational_gmp_imp.h12
-rw-r--r--src/util/regexp.cpp12
-rw-r--r--src/util/regexp.h12
-rw-r--r--src/util/resource_manager.cpp25
-rw-r--r--src/util/resource_manager.h25
-rw-r--r--src/util/result.cpp12
-rw-r--r--src/util/result.h12
-rw-r--r--src/util/sexpr.cpp12
-rw-r--r--src/util/sexpr.h12
-rw-r--r--src/util/sexpr.i1
-rw-r--r--src/util/smt2_quote_string.cpp12
-rw-r--r--src/util/smt2_quote_string.h12
-rw-r--r--src/util/statistics.cpp12
-rw-r--r--src/util/statistics.h12
-rw-r--r--src/util/statistics_registry.cpp12
-rw-r--r--src/util/statistics_registry.h12
-rw-r--r--src/util/subrange_bound.cpp12
-rw-r--r--src/util/subrange_bound.h12
-rw-r--r--src/util/tuple.h12
-rw-r--r--src/util/unsafe_interrupt_exception.h12
-rw-r--r--src/util/utility.h12
691 files changed, 18931 insertions, 9004 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 26a677d90..3ffda9f28 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -76,35 +76,41 @@ libcvc4_la_SOURCES = \
printer/cvc/cvc_printer.cpp \
printer/tptp/tptp_printer.h \
printer/tptp/tptp_printer.cpp \
+ proof/arith_proof.cpp \
+ proof/arith_proof.h \
+ proof/array_proof.cpp \
+ proof/array_proof.h \
+ proof/bitvector_proof.cpp \
+ proof/bitvector_proof.h \
+ proof/clause_id.h \
+ proof/cnf_proof.cpp \
+ proof/cnf_proof.h \
proof/proof.h \
+ proof/proof_manager.cpp \
+ proof/proof_manager.h \
+ proof/proof_utils.cpp \
+ proof/proof_utils.h \
proof/sat_proof.h \
proof/sat_proof_implementation.h \
- proof/cnf_proof.h \
- proof/cnf_proof.cpp \
- proof/theory_proof.h \
+ proof/skolemization_manager.cpp \
+ proof/skolemization_manager.h \
proof/theory_proof.cpp \
- proof/uf_proof.h \
+ proof/theory_proof.h \
proof/uf_proof.cpp \
- proof/array_proof.h \
- proof/bitvector_proof.h \
- proof/bitvector_proof.cpp \
- proof/proof_manager.h \
- proof/proof_manager.cpp \
- proof/proof_utils.h \
- proof/proof_utils.cpp \
+ proof/uf_proof.h \
proof/unsat_core.cpp \
proof/unsat_core.h \
- prop/registrar.h \
+ prop/cnf_stream.cpp \
+ prop/cnf_stream.h \
prop/prop_engine.cpp \
prop/prop_engine.h \
- prop/theory_proxy.h \
- prop/theory_proxy.cpp \
- prop/cnf_stream.h \
- prop/cnf_stream.cpp \
+ prop/registrar.h \
prop/sat_solver.h \
- prop/sat_solver_types.h \
- prop/sat_solver_factory.h \
prop/sat_solver_factory.cpp \
+ prop/sat_solver_factory.h \
+ prop/sat_solver_types.h \
+ prop/theory_proxy.cpp \
+ prop/theory_proxy.h \
smt/boolean_terms.cpp \
smt/boolean_terms.h \
smt/command.cpp \
@@ -284,6 +290,8 @@ libcvc4_la_SOURCES = \
theory/arrays/array_info.cpp \
theory/arrays/static_fact_manager.h \
theory/arrays/static_fact_manager.cpp \
+ theory/arrays/array_proof_reconstruction.cpp \
+ theory/arrays/array_proof_reconstruction.h \
theory/quantifiers/theory_quantifiers_type_rules.h \
theory/quantifiers/theory_quantifiers.h \
theory/quantifiers/quantifiers_rewriter.h \
@@ -353,6 +361,14 @@ libcvc4_la_SOURCES = \
theory/quantifiers/quant_equality_engine.cpp \
theory/quantifiers/ceg_instantiator.h \
theory/quantifiers/ceg_instantiator.cpp \
+ theory/quantifiers/quant_split.h \
+ theory/quantifiers/quant_split.cpp \
+ theory/quantifiers/anti_skolem.h \
+ theory/quantifiers/anti_skolem.cpp \
+ theory/quantifiers/equality_infer.h \
+ theory/quantifiers/equality_infer.cpp \
+ theory/quantifiers/inst_propagator.h \
+ theory/quantifiers/inst_propagator.cpp \
theory/arith/theory_arith_type_rules.h \
theory/arith/type_enumerator.h \
theory/arith/arithvar.h \
diff --git a/src/base/configuration.cpp b/src/base/configuration.cpp
index c3ba39075..ce8967a18 100644
--- a/src/base/configuration.cpp
+++ b/src/base/configuration.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file configuration.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Liana Hadarean, Tim King, ACSYS, Christopher L. Conway, Dejan Jovanovic, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Francois Bobot, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of Configuration class, which provides compile-time
** configuration information about the CVC4 library
diff --git a/src/base/configuration.h b/src/base/configuration.h
index 818652db0..498337c4c 100644
--- a/src/base/configuration.h
+++ b/src/base/configuration.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file configuration.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): ACSYS, Liana Hadarean, Tim King, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interface to a public class that provides compile-time information
** about the CVC4 library.
diff --git a/src/base/configuration_private.h b/src/base/configuration_private.h
index 902fdad09..74ce00bdf 100644
--- a/src/base/configuration_private.h
+++ b/src/base/configuration_private.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file configuration_private.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: ACSYS, Morgan Deters
- ** Minor contributors (to current version): Liana Hadarean, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, ACSYS
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Provides compile-time configuration information about the
** CVC4 library.
diff --git a/src/base/cvc4_assert.cpp b/src/base/cvc4_assert.cpp
index efc71c986..8d5b9e508 100644
--- a/src/base/cvc4_assert.cpp
+++ b/src/base/cvc4_assert.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4_assert.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Assertion utility classes, functions, and exceptions.
**
diff --git a/src/base/cvc4_assert.h b/src/base/cvc4_assert.h
index 63ed6d53e..5f67ba57d 100644
--- a/src/base/cvc4_assert.h
+++ b/src/base/cvc4_assert.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4_assert.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): ACSYS
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Assertion utility classes, functions, exceptions, and macros.
**
diff --git a/src/base/exception.cpp b/src/base/exception.cpp
index cdad92d5d..4f62f68db 100644
--- a/src/base/exception.cpp
+++ b/src/base/exception.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file exception.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief CVC4's exception base class and some associated utilities
**
diff --git a/src/base/exception.h b/src/base/exception.h
index 38bbe47a4..8f3016e4e 100644
--- a/src/base/exception.h
+++ b/src/base/exception.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file exception.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief CVC4's exception base class and some associated utilities
**
diff --git a/src/base/listener.cpp b/src/base/listener.cpp
index 2daced1f5..1f7c6158b 100644
--- a/src/base/listener.cpp
+++ b/src/base/listener.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file managed_listener.h
+/*! \file listener.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Output utility classes and functions
**
diff --git a/src/base/listener.h b/src/base/listener.h
index 8094c634d..724935ae7 100644
--- a/src/base/listener.h
+++ b/src/base/listener.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file listener.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Utility classes for listeners and collections of listeners.
**
diff --git a/src/base/modal_exception.h b/src/base/modal_exception.h
index 44f133372..c662da2c8 100644
--- a/src/base/modal_exception.h
+++ b/src/base/modal_exception.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file modal_exception.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An exception that is thrown when an interactive-only
** feature while CVC4 is being used in a non-interactive setting
diff --git a/src/base/output.cpp b/src/base/output.cpp
index be0f10fda..1d4525701 100644
--- a/src/base/output.cpp
+++ b/src/base/output.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file output.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Output utility classes and functions
**
diff --git a/src/base/output.h b/src/base/output.h
index 9d1ab03ae..30b5c8ea5 100644
--- a/src/base/output.h
+++ b/src/base/output.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file output.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Output utility classes and functions
**
diff --git a/src/base/tls.h.in b/src/base/tls.h.in
index 88969e250..a61eb79be 100644
--- a/src/base/tls.h.in
+++ b/src/base/tls.h.in
@@ -1,13 +1,13 @@
/********************* */
/*! \file tls.h.in
** \verbatim
- ** Original author: ACSYS
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, ACSYS, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Header to define CVC4_THREAD whether or not TLS is
** supported by the compiler/runtime platform
diff --git a/src/bindings/java_iterator_adapter.h b/src/bindings/java_iterator_adapter.h
index 473e056f9..2688f9520 100644
--- a/src/bindings/java_iterator_adapter.h
+++ b/src/bindings/java_iterator_adapter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file java_iterator_adapter.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An iterator adapter for the Java bindings, giving Java iterators
** the ability to access elements from STL iterators.
diff --git a/src/bindings/java_stream_adapters.h b/src/bindings/java_stream_adapters.h
index c198b95aa..12f8713a3 100644
--- a/src/bindings/java_stream_adapters.h
+++ b/src/bindings/java_stream_adapters.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file java_stream_adapters.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An OutputStream adapter for the Java bindings
**
diff --git a/src/bindings/swig.h b/src/bindings/swig.h
index 9bece4ecd..7d8f7494e 100644
--- a/src/bindings/swig.h
+++ b/src/bindings/swig.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file swig.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Common swig checks and definitions
**
diff --git a/src/compat/cvc3_compat.cpp b/src/compat/cvc3_compat.cpp
index 52174dce0..50da4e412 100644
--- a/src/compat/cvc3_compat.cpp
+++ b/src/compat/cvc3_compat.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc3_compat.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds, Tim King, Dejan Jovanovic, Tianyi Liang
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief CVC3 compatibility layer for CVC4
**
@@ -1818,8 +1818,7 @@ Expr ValidityChecker::recordExpr(const std::vector<std::string>& fields,
Expr ValidityChecker::recSelectExpr(const Expr& record, const std::string& field) {
Type t = record.getType();
const CVC4::Datatype& dt = ((CVC4::DatatypeType)t).getDatatype();
- const CVC4::Record& rec = ((CVC4::DatatypeType)t).getRecord();
- unsigned index = rec.getIndex(field);
+ unsigned index = CVC4::Datatype::indexOf( dt[0].getSelector(field) );
return d_em->mkExpr(CVC4::kind::APPLY_SELECTOR_TOTAL, dt[0][index].getSelector(), record);
}
diff --git a/src/compat/cvc3_compat.h b/src/compat/cvc3_compat.h
index 5fefa6871..d51670985 100644
--- a/src/compat/cvc3_compat.h
+++ b/src/compat/cvc3_compat.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc3_compat.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief CVC3 compatibility layer for CVC4
**
diff --git a/src/context/backtrackable.h b/src/context/backtrackable.h
index 5492dd8b5..131fabd7c 100644
--- a/src/context/backtrackable.h
+++ b/src/context/backtrackable.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file backtrackable.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Contains a backtrackable list
**
diff --git a/src/context/cdchunk_list.h b/src/context/cdchunk_list.h
index 62a87ffcc..3fa3c6b5d 100644
--- a/src/context/cdchunk_list.h
+++ b/src/context/cdchunk_list.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdchunk_list.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent list class designed for use with a
** context memory allocator.
diff --git a/src/context/cddense_set.h b/src/context/cddense_set.h
index e717adaee..edc5ea558 100644
--- a/src/context/cddense_set.h
+++ b/src/context/cddense_set.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cddense_set.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an abstraction of a set of unsigned integers.
**
diff --git a/src/context/cdhashmap.h b/src/context/cdhashmap.h
index 0eb1d03c9..d080da333 100644
--- a/src/context/cdhashmap.h
+++ b/src/context/cdhashmap.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdhashmap.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent map class.
**
diff --git a/src/context/cdhashmap_forward.h b/src/context/cdhashmap_forward.h
index 23346435a..b8a361dbb 100644
--- a/src/context/cdhashmap_forward.h
+++ b/src/context/cdhashmap_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdhashmap_forward.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Tim King, Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a forward declaration header to declare the CDHashMap<>
** template
diff --git a/src/context/cdhashset.h b/src/context/cdhashset.h
index 533a09a0a..8c450f1ab 100644
--- a/src/context/cdhashset.h
+++ b/src/context/cdhashset.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdhashset.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Tim King, Morgan Deters
- ** Minor contributors (to current version): Francois Bobot, Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent set class.
**
diff --git a/src/context/cdhashset_forward.h b/src/context/cdhashset_forward.h
index e96387c06..06ea9c471 100644
--- a/src/context/cdhashset_forward.h
+++ b/src/context/cdhashset_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdhashset_forward.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a forward declaration header to declare the CDSet<>
** template
diff --git a/src/context/cdinsert_hashmap.h b/src/context/cdinsert_hashmap.h
index b65784ddf..6e772068b 100644
--- a/src/context/cdinsert_hashmap.h
+++ b/src/context/cdinsert_hashmap.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdinsert_hashmap.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent insert only hashmap built using trail of edits
**
diff --git a/src/context/cdinsert_hashmap_forward.h b/src/context/cdinsert_hashmap_forward.h
index 184b27a3d..5bc6e8fda 100644
--- a/src/context/cdinsert_hashmap_forward.h
+++ b/src/context/cdinsert_hashmap_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdinsert_hashmap_forward.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a forward declaration header to declare the CDInsertHashMap<>
** template
diff --git a/src/context/cdlist.h b/src/context/cdlist.h
index dbc00bd69..4e42c4688 100644
--- a/src/context/cdlist.h
+++ b/src/context/cdlist.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdlist.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): Kshitij Bansal, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent list class (only supports append)
**
diff --git a/src/context/cdlist_forward.h b/src/context/cdlist_forward.h
index dd4213f64..101117c23 100644
--- a/src/context/cdlist_forward.h
+++ b/src/context/cdlist_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdlist_forward.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a forward declaration header to declare the
** CDList<> template
diff --git a/src/context/cdmaybe.h b/src/context/cdmaybe.h
index d47f617a9..458a124ad 100644
--- a/src/context/cdmaybe.h
+++ b/src/context/cdmaybe.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdmaybe.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A context-dependent "maybe" template type
**
diff --git a/src/context/cdo.h b/src/context/cdo.h
index 860648b27..e2fdcf9bd 100644
--- a/src/context/cdo.h
+++ b/src/context/cdo.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdo.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Clark Barrett, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A context-dependent object.
**
diff --git a/src/context/cdqueue.h b/src/context/cdqueue.h
index 0e57a7cdb..5aa890d53 100644
--- a/src/context/cdqueue.h
+++ b/src/context/cdqueue.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdqueue.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Francois Bobot, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent queue class
**
diff --git a/src/context/cdtrail_hashmap.h b/src/context/cdtrail_hashmap.h
index befd396a9..e89c1b528 100644
--- a/src/context/cdtrail_hashmap.h
+++ b/src/context/cdtrail_hashmap.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdtrail_hashmap.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent hashmap built using trail of elements
**
diff --git a/src/context/cdtrail_hashmap_forward.h b/src/context/cdtrail_hashmap_forward.h
index 2bfb32539..926c85872 100644
--- a/src/context/cdtrail_hashmap_forward.h
+++ b/src/context/cdtrail_hashmap_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdtrail_hashmap_forward.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a forward declaration header to declare the
** CDTrailHashMap<> template
diff --git a/src/context/cdtrail_queue.h b/src/context/cdtrail_queue.h
index dff68a161..825557f36 100644
--- a/src/context/cdtrail_queue.h
+++ b/src/context/cdtrail_queue.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdtrail_queue.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context-dependent queue class with an explicit trail of elements
**
diff --git a/src/context/cdvector.h b/src/context/cdvector.h
index fe8f77c6d..2449d78b0 100644
--- a/src/context/cdvector.h
+++ b/src/context/cdvector.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cdvector.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/context/context.cpp b/src/context/context.cpp
index 99a98e63f..9c0416ce8 100644
--- a/src/context/context.cpp
+++ b/src/context/context.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file context.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of base context operations.
**
diff --git a/src/context/context.h b/src/context/context.h
index b88f36786..4f45e8954 100644
--- a/src/context/context.h
+++ b/src/context/context.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file context.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Tim King, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context class and context manager.
**
diff --git a/src/context/context_mm.cpp b/src/context/context_mm.cpp
index f30413650..0a6b08b6a 100644
--- a/src/context/context_mm.cpp
+++ b/src/context/context_mm.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file context_mm.cpp
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of Context Memory Manager.
**
diff --git a/src/context/context_mm.h b/src/context/context_mm.h
index 4594ac253..99b448cf2 100644
--- a/src/context/context_mm.h
+++ b/src/context/context_mm.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file context_mm.h
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Region-based memory manager with stack-based push and pop.
**
diff --git a/src/context/stacking_vector.h b/src/context/stacking_vector.h
index 578a2e3ae..b737c40ae 100644
--- a/src/context/stacking_vector.h
+++ b/src/context/stacking_vector.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file stacking_vector.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Backtrackable vector using an undo stack
**
diff --git a/src/decision/decision_attributes.h b/src/decision/decision_attributes.h
index 03229ac84..cc2c766e3 100644
--- a/src/decision/decision_attributes.h
+++ b/src/decision/decision_attributes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_attributes.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter attributes
**
diff --git a/src/decision/decision_engine.cpp b/src/decision/decision_engine.cpp
index 12400a3b1..71e4f4ec3 100644
--- a/src/decision/decision_engine.cpp
+++ b/src/decision/decision_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_engine.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King, Morgan Deters
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Decision engine
**
diff --git a/src/decision/decision_engine.h b/src/decision/decision_engine.h
index de8a67413..92d203cb3 100644
--- a/src/decision/decision_engine.h
+++ b/src/decision/decision_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_engine.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Clark Barrett, Dejan Jovanovic, Morgan Deters, Tim King
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Decision engine
**
diff --git a/src/decision/decision_strategy.h b/src/decision/decision_strategy.h
index fca48ced1..591f018d8 100644
--- a/src/decision/decision_strategy.h
+++ b/src/decision/decision_strategy.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_strategy.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Decision strategy
**
diff --git a/src/decision/justification_heuristic.cpp b/src/decision/justification_heuristic.cpp
index bdde41b52..cfa478c7d 100644
--- a/src/decision/justification_heuristic.cpp
+++ b/src/decision/justification_heuristic.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file justification_heuristic.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Justification heuristic for decision making
**
diff --git a/src/decision/justification_heuristic.h b/src/decision/justification_heuristic.h
index 5b0deca1b..c03bba0c0 100644
--- a/src/decision/justification_heuristic.h
+++ b/src/decision/justification_heuristic.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file justification_heuristic.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King, Morgan Deters
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Justification heuristic for decision making
**
diff --git a/src/expr/array.h b/src/expr/array.h
index ab554171f..cf050e077 100644
--- a/src/expr/array.h
+++ b/src/expr/array.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file array.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Array types.
**
diff --git a/src/expr/array_store_all.cpp b/src/expr/array_store_all.cpp
index 6ac07c81d..c8e346e48 100644
--- a/src/expr/array_store_all.cpp
+++ b/src/expr/array_store_all.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file array_store_all.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of a constant array (an array in which the
** element is the same for all indices)
diff --git a/src/expr/array_store_all.h b/src/expr/array_store_all.h
index 293b785a9..0a9c8344a 100644
--- a/src/expr/array_store_all.h
+++ b/src/expr/array_store_all.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file array_store_all.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of a constant array (an array in which the
** element is the same for all indices)
diff --git a/src/expr/ascription_type.h b/src/expr/ascription_type.h
index 42906e557..46d2871ff 100644
--- a/src/expr/ascription_type.h
+++ b/src/expr/ascription_type.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ascription_type.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class representing a type ascription
**
diff --git a/src/expr/attribute.cpp b/src/expr/attribute.cpp
index cd5b35384..3cf242988 100644
--- a/src/expr/attribute.cpp
+++ b/src/expr/attribute.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file attribute.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief AttributeManager implementation.
**
diff --git a/src/expr/attribute.h b/src/expr/attribute.h
index 432fbbac9..13bedeaf8 100644
--- a/src/expr/attribute.h
+++ b/src/expr/attribute.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file attribute.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): Christopher L. Conway, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Node attributes.
**
diff --git a/src/expr/attribute_internals.h b/src/expr/attribute_internals.h
index dae11fd74..60d2069e7 100644
--- a/src/expr/attribute_internals.h
+++ b/src/expr/attribute_internals.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file attribute_internals.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Node attributes' internals.
**
diff --git a/src/expr/attribute_unique_id.h b/src/expr/attribute_unique_id.h
index 45dc368a5..4875bdf50 100644
--- a/src/expr/attribute_unique_id.h
+++ b/src/expr/attribute_unique_id.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file attribute_unique_id.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/expr/chain.h b/src/expr/chain.h
index e052a2ed8..703aa76ed 100644
--- a/src/expr/chain.h
+++ b/src/expr/chain.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file chain.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/expr/convenience_node_builders.h b/src/expr/convenience_node_builders.h
index 0c3b690b2..611a88e6f 100644
--- a/src/expr/convenience_node_builders.h
+++ b/src/expr/convenience_node_builders.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file convenience_node_builders.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Convenience node builders.
**
diff --git a/src/expr/datatype.cpp b/src/expr/datatype.cpp
index 32c0bb6dd..d14ac26d4 100644
--- a/src/expr/datatype.cpp
+++ b/src/expr/datatype.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file datatype.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class representing a Datatype definition
**
@@ -51,6 +51,10 @@ typedef expr::Attribute<expr::attr::DatatypeFiniteComputedTag, bool> DatatypeFin
typedef expr::Attribute<expr::attr::DatatypeUFiniteTag, bool> DatatypeUFiniteAttr;
typedef expr::Attribute<expr::attr::DatatypeUFiniteComputedTag, bool> DatatypeUFiniteComputedAttr;
+Datatype::~Datatype(){
+ delete d_record;
+}
+
const Datatype& Datatype::datatypeOf(Expr item) {
ExprManagerScope ems(item);
TypeNode t = Node::fromExpr(item).getType();
@@ -133,6 +137,14 @@ void Datatype::resolve(ExprManager* em,
d_involvesUt = true;
}
}
+
+ if( d_isRecord ){
+ std::vector< std::pair<std::string, Type> > fields;
+ for( unsigned i=0; i<(*this)[0].getNumArgs(); i++ ){
+ fields.push_back( std::pair<std::string, Type>( (*this)[0][i].getName(), (*this)[0][i].getRangeType() ) );
+ }
+ d_record = new Record(fields);
+ }
}
void Datatype::addConstructor(const DatatypeConstructor& c) {
@@ -152,10 +164,12 @@ void Datatype::setSygus( Type st, Expr bvl, bool allow_const, bool allow_all ){
}
void Datatype::setTuple() {
+ PrettyCheckArgument(!d_resolved, this, "cannot set tuple to a finalized Datatype");
d_isTuple = true;
}
void Datatype::setRecord() {
+ PrettyCheckArgument(!d_resolved, this, "cannot set record to a finalized Datatype");
d_isRecord = true;
}
@@ -185,20 +199,24 @@ Cardinality Datatype::computeCardinality( std::vector< Type >& processing ) cons
bool Datatype::isRecursiveSingleton() const throw(IllegalArgumentException) {
PrettyCheckArgument(isResolved(), this, "this datatype is not yet resolved");
if( d_card_rec_singleton==0 ){
- Assert( d_card_u_assume.empty() );
- std::vector< Type > processing;
- if( computeCardinalityRecSingleton( processing, d_card_u_assume ) ){
- d_card_rec_singleton = 1;
+ if( isCodatatype() ){
+ Assert( d_card_u_assume.empty() );
+ std::vector< Type > processing;
+ if( computeCardinalityRecSingleton( processing, d_card_u_assume ) ){
+ d_card_rec_singleton = 1;
+ }else{
+ d_card_rec_singleton = -1;
+ }
+ if( d_card_rec_singleton==1 ){
+ Trace("dt-card") << "Datatype " << getName() << " is recursive singleton, dependent upon " << d_card_u_assume.size() << " uninterpreted sorts: " << std::endl;
+ for( unsigned i=0; i<d_card_u_assume.size(); i++ ){
+ Trace("dt-card") << " " << d_card_u_assume [i] << std::endl;
+ }
+ Trace("dt-card") << std::endl;
+ }
}else{
d_card_rec_singleton = -1;
}
- if( d_card_rec_singleton==1 ){
- Trace("dt-card") << "Datatype " << getName() << " is recursive singleton, dependent upon " << d_card_u_assume.size() << " uninterpreted sorts: " << std::endl;
- for( unsigned i=0; i<d_card_u_assume.size(); i++ ){
- Trace("dt-card") << " " << d_card_u_assume [i] << std::endl;
- }
- Trace("dt-card") << std::endl;
- }
}
return d_card_rec_singleton==1;
}
@@ -288,10 +306,11 @@ bool Datatype::isUFinite() const throw(IllegalArgumentException) {
if(self.getAttribute(DatatypeUFiniteComputedAttr())) {
return self.getAttribute(DatatypeUFiniteAttr());
}
+ //start by assuming it is not
+ self.setAttribute(DatatypeUFiniteComputedAttr(), true);
+ self.setAttribute(DatatypeUFiniteAttr(), false);
for(const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
if(! (*i).isUFinite()) {
- self.setAttribute(DatatypeUFiniteComputedAttr(), true);
- self.setAttribute(DatatypeUFiniteAttr(), false);
return false;
}
}
@@ -820,7 +839,7 @@ bool DatatypeConstructor::isFinite() const throw(IllegalArgumentException) {
return self.getAttribute(DatatypeFiniteAttr());
}
for(const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
- if(! SelectorType((*i).getSelector().getType()).getRangeType().getCardinality().isFinite()) {
+ if(! (*i).getRangeType().getCardinality().isFinite()) {
self.setAttribute(DatatypeFiniteComputedAttr(), true);
self.setAttribute(DatatypeFiniteAttr(), false);
return false;
@@ -840,9 +859,18 @@ bool DatatypeConstructor::isUFinite() const throw(IllegalArgumentException) {
if(self.getAttribute(DatatypeUFiniteComputedAttr())) {
return self.getAttribute(DatatypeUFiniteAttr());
}
+ bool success = true;
for(const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
- Type t = SelectorType((*i).getSelector().getType()).getRangeType();
- if(!t.isSort() && !t.getCardinality().isFinite()) {
+ Type t = (*i).getRangeType();
+ if( t.isDatatype() ){
+ const Datatype& dt = ((DatatypeType)t).getDatatype();
+ if( !dt.isUFinite() ){
+ success = false;
+ }
+ }else if(!t.isSort() && !t.getCardinality().isFinite()) {
+ success = false;
+ }
+ if(!success ){
self.setAttribute(DatatypeUFiniteComputedAttr(), true);
self.setAttribute(DatatypeUFiniteAttr(), false);
return false;
@@ -974,6 +1002,10 @@ SelectorType DatatypeConstructorArg::getType() const {
return getSelector().getType();
}
+Type DatatypeConstructorArg::getRangeType() const {
+ return getType().getRangeType();
+}
+
bool DatatypeConstructorArg::isUnresolvedSelf() const throw() {
return d_selector.isNull() && d_name.size() == d_name.find('\0') + 1;
}
diff --git a/src/expr/datatype.h b/src/expr/datatype.h
index 625fbb5d4..1197b4a3b 100644
--- a/src/expr/datatype.h
+++ b/src/expr/datatype.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file datatype.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class representing a Datatype definition
**
@@ -155,6 +155,11 @@ public:
SelectorType getType() const;
/**
+ * Get the range type of this argument.
+ */
+ Type getRangeType() const;
+
+ /**
* Get the name of the type of this constructor argument
* (Datatype field). Can be used for not-yet-resolved Datatypes
* (in which case the name of the unresolved type, or "[self]"
@@ -474,6 +479,7 @@ private:
bool d_isCo;
bool d_isTuple;
bool d_isRecord;
+ Record * d_record;
std::vector<DatatypeConstructor> d_constructors;
bool d_resolved;
Type d_self;
@@ -553,6 +559,8 @@ public:
*/
inline Datatype(std::string name, const std::vector<Type>& params, bool isCo = false);
+ ~Datatype();
+
/**
* Add a constructor to this Datatype. Constructor names need not
* be unique; they are for convenience and pretty-printing only.
@@ -602,6 +610,9 @@ public:
/** is this a record datatype? */
inline bool isRecord() const;
+ /** get the record representation for this datatype */
+ inline Record * getRecord() const;
+
/**
* Return the cardinality of this datatype (the sum of the
* cardinalities of its constructors). The Datatype must be
@@ -772,6 +783,7 @@ inline Datatype::Datatype(std::string name, bool isCo) :
d_isCo(isCo),
d_isTuple(false),
d_isRecord(false),
+ d_record(NULL),
d_constructors(),
d_resolved(false),
d_self(),
@@ -788,6 +800,7 @@ inline Datatype::Datatype(std::string name, const std::vector<Type>& params, boo
d_isCo(isCo),
d_isTuple(false),
d_isRecord(false),
+ d_record(NULL),
d_constructors(),
d_resolved(false),
d_self(),
@@ -844,6 +857,10 @@ inline bool Datatype::isRecord() const {
return d_isRecord;
}
+inline Record * Datatype::getRecord() const {
+ return d_record;
+}
+
inline bool Datatype::operator!=(const Datatype& other) const throw() {
return !(*this == other);
}
diff --git a/src/expr/emptyset.cpp b/src/expr/emptyset.cpp
index a6e2c1ece..23e6df7dc 100644
--- a/src/expr/emptyset.cpp
+++ b/src/expr/emptyset.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file emptyset.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Kshitij Bansal, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/expr/emptyset.h b/src/expr/emptyset.h
index cf9d050f8..a606951f0 100644
--- a/src/expr/emptyset.h
+++ b/src/expr/emptyset.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file emptyset.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Kshitij Bansal, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/expr/expr.i b/src/expr/expr.i
index b50686f52..354cacdc0 100644
--- a/src/expr/expr.i
+++ b/src/expr/expr.i
@@ -130,7 +130,13 @@ namespace CVC4 {
%include "expr/expr.h"
+#ifdef SWIGPYTHON
+/* The python bindings on Mac OS X have trouble with this one - leave it
+ * out for now. */
+//%template(getConstTypeConstant) CVC4::Expr::getConst<CVC4::TypeConstant>;
+#else
%template(getConstTypeConstant) CVC4::Expr::getConst<CVC4::TypeConstant>;
+#endif
%template(getConstArrayStoreAll) CVC4::Expr::getConst<CVC4::ArrayStoreAll>;
%template(getConstBitVectorSize) CVC4::Expr::getConst<CVC4::BitVectorSize>;
%template(getConstAscriptionType) CVC4::Expr::getConst<CVC4::AscriptionType>;
diff --git a/src/expr/expr_iomanip.cpp b/src/expr/expr_iomanip.cpp
index 4c7ab3c8b..1d6df2a4e 100644
--- a/src/expr/expr_iomanip.cpp
+++ b/src/expr/expr_iomanip.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_iomanip.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Expr IO manipulation classes.
**
diff --git a/src/expr/expr_iomanip.h b/src/expr/expr_iomanip.h
index b3370e75a..94e2b46ea 100644
--- a/src/expr/expr_iomanip.h
+++ b/src/expr/expr_iomanip.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_iomanip.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Expr IO manipulation classes.
**
diff --git a/src/expr/expr_manager.i b/src/expr/expr_manager.i
index 66930cf55..11c1e284d 100644
--- a/src/expr/expr_manager.i
+++ b/src/expr/expr_manager.i
@@ -40,7 +40,6 @@
%include "expr/expr_manager.h"
-%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TypeConstant>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::ArrayStoreAll>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::BitVectorSize>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::AscriptionType>;
@@ -67,10 +66,7 @@
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::UninterpretedConstant>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::kind::Kind_t>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::Datatype>;
-%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TupleSelect>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TupleUpdate>;
-%template(mkConst) CVC4::ExprManager::mkConst<CVC4::Record>;
-%template(mkConst) CVC4::ExprManager::mkConst<CVC4::RecordSelect>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::RecordUpdate>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::Rational>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::BitVector>;
@@ -78,6 +74,25 @@
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::EmptySet>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::String>;
%template(mkConst) CVC4::ExprManager::mkConst<CVC4::RegExp>;
+#ifdef SWIGPYTHON
+/* The python bindings cannot differentiate between bool and other basic
+ * types like enum and int. Therefore, we rename mkConst for the bool
+ * case into mkBoolConst.
+*/
+%template(mkBoolConst) CVC4::ExprManager::mkConst<bool>;
+
+// These cases have trouble too. Remove them for now.
+//%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TypeConstant>;
+//%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TupleSelect>;
+//%template(mkConst) CVC4::ExprManager::mkConst<CVC4::Record>;
+//%template(mkConst) CVC4::ExprManager::mkConst<CVC4::RecordSelect>;
+
+#else
+%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TypeConstant>;
+%template(mkConst) CVC4::ExprManager::mkConst<CVC4::TupleSelect>;
+%template(mkConst) CVC4::ExprManager::mkConst<CVC4::Record>;
+%template(mkConst) CVC4::ExprManager::mkConst<CVC4::RecordSelect>;
%template(mkConst) CVC4::ExprManager::mkConst<bool>;
+#endif
%include "expr/expr_manager.h"
diff --git a/src/expr/expr_manager_scope.h b/src/expr/expr_manager_scope.h
index a8e8f04be..cd4c274e5 100644
--- a/src/expr/expr_manager_scope.h
+++ b/src/expr/expr_manager_scope.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_manager_scope.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/expr/expr_manager_template.cpp b/src/expr/expr_manager_template.cpp
index ce7a92b48..84f674d2b 100644
--- a/src/expr/expr_manager_template.cpp
+++ b/src/expr/expr_manager_template.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_manager_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Christopher L. Conway
- ** Minor contributors (to current version): Kshitij Bansal, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Public-facing expression manager interface, implementation
**
@@ -142,6 +142,11 @@ StringType ExprManager::stringType() const {
return StringType(Type(d_nodeManager, new TypeNode(d_nodeManager->stringType())));
}
+RegExpType ExprManager::regExpType() const {
+ NodeManagerScope nms(d_nodeManager);
+ return StringType(Type(d_nodeManager, new TypeNode(d_nodeManager->regExpType())));
+}
+
RealType ExprManager::realType() const {
NodeManagerScope nms(d_nodeManager);
return RealType(Type(d_nodeManager, new TypeNode(d_nodeManager->realType())));
@@ -791,7 +796,7 @@ void ExprManager::checkResolvedDatatype(DatatypeType dtt) const {
j != j_end;
++j) {
const DatatypeConstructorArg& a = *j;
- Type selectorType = a.getSelector().getType();
+ Type selectorType = a.getType();
Assert(a.isResolved() &&
selectorType.isSelector() &&
SelectorType(selectorType).getDomain() == dtt,
diff --git a/src/expr/expr_manager_template.h b/src/expr/expr_manager_template.h
index 37ef128f4..04f2f4289 100644
--- a/src/expr/expr_manager_template.h
+++ b/src/expr/expr_manager_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_manager_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Andrew Reynolds, Kshitij Bansal, Tim King, Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Public-facing expression manager interface
**
@@ -121,6 +121,9 @@ public:
/** Get the type for strings. */
StringType stringType() const;
+ /** Get the type for regular expressions. */
+ RegExpType regExpType() const;
+
/** Get the type for reals. */
RealType realType() const;
diff --git a/src/expr/expr_stream.h b/src/expr/expr_stream.h
index 20977011c..d3dbd2902 100644
--- a/src/expr/expr_stream.h
+++ b/src/expr/expr_stream.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_stream.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A stream interface for expressions
**
diff --git a/src/expr/expr_template.cpp b/src/expr/expr_template.cpp
index a6cdedd00..43e4a7b76 100644
--- a/src/expr/expr_template.cpp
+++ b/src/expr/expr_template.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Kshitij Bansal
- ** Minor contributors (to current version): Tim King, Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Kshitij Bansal, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Public-facing expression interface, implementation.
**
diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h
index d037a6bb9..5c3f89e9c 100644
--- a/src/expr/expr_template.h
+++ b/src/expr/expr_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Liana Hadarean, Kshitij Bansal, Tim King, Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Public-facing expression interface.
**
diff --git a/src/expr/kind_map.h b/src/expr/kind_map.h
index 02e9728f0..6858f8ab9 100644
--- a/src/expr/kind_map.h
+++ b/src/expr/kind_map.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file kind_map.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A bitmap of Kinds
**
diff --git a/src/expr/kind_template.h b/src/expr/kind_template.h
index 799d1ac33..440d6b586 100644
--- a/src/expr/kind_template.h
+++ b/src/expr/kind_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file kind_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Template for the Node kind header
**
diff --git a/src/expr/matcher.h b/src/expr/matcher.h
index 8cb092a64..308ad06df 100644
--- a/src/expr/matcher.h
+++ b/src/expr/matcher.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file matcher.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class representing a type matcher
**
diff --git a/src/expr/metakind_template.h b/src/expr/metakind_template.h
index 539db1c91..9025aa02a 100644
--- a/src/expr/metakind_template.h
+++ b/src/expr/metakind_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file metakind_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Template for the metakind header.
**
diff --git a/src/expr/node.cpp b/src/expr/node.cpp
index cf9a772b7..793b6af97 100644
--- a/src/expr/node.cpp
+++ b/src/expr/node.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file node.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Reference-counted encapsulation of a pointer to node information.
**
diff --git a/src/expr/node.h b/src/expr/node.h
index a51de6d66..998294da3 100644
--- a/src/expr/node.h
+++ b/src/expr/node.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal, Francois Bobot, Clark Barrett, Tim King, Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Reference-counted encapsulation of a pointer to node information
**
diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h
index e1a083a78..0dd4e44e8 100644
--- a/src/expr/node_builder.h
+++ b/src/expr/node_builder.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_builder.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King, Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A builder interface for Nodes.
**
diff --git a/src/expr/node_manager.cpp b/src/expr/node_manager.cpp
index e6e44928d..0809a0331 100644
--- a/src/expr/node_manager.cpp
+++ b/src/expr/node_manager.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_manager.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): ACSYS, Kshitij Bansal, Tim King, Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Expression manager implementation.
**
@@ -170,7 +170,9 @@ NodeManager::~NodeManager() {
d_operators[i] = Node::null();
}
- d_tupleAndRecordTypes.clear();
+ //d_tupleAndRecordTypes.clear();
+ d_tt_cache.d_children.clear();
+ d_rt_cache.d_children.clear();
Assert(!d_attrManager->inGarbageCollection() );
while(!d_zombies.empty()) {
@@ -461,6 +463,47 @@ TypeNode NodeManager::mkSubrangeType(const SubrangeBounds& bounds)
return TypeNode(mkTypeConst(bounds));
}
+TypeNode NodeManager::TupleTypeCache::getTupleType( NodeManager * nm, std::vector< TypeNode >& types, unsigned index ) {
+ if( index==types.size() ){
+ if( d_data.isNull() ){
+ Datatype dt("__cvc4_tuple");
+ dt.setTuple();
+ DatatypeConstructor c("__cvc4_tuple_ctor");
+ for (unsigned i = 0; i < types.size(); ++ i) {
+ std::stringstream ss;
+ ss << "__cvc4_tuple_stor_" << i;
+ c.addArg(ss.str().c_str(), types[i].toType());
+ }
+ dt.addConstructor(c);
+ d_data = TypeNode::fromType(nm->toExprManager()->mkDatatypeType(dt));
+ Debug("tuprec-debug") << "Return type : " << d_data << std::endl;
+ }
+ return d_data;
+ }else{
+ return d_children[types[index]].getTupleType( nm, types, index+1 );
+ }
+}
+
+TypeNode NodeManager::RecTypeCache::getRecordType( NodeManager * nm, const Record& rec, unsigned index ) {
+ if( index==rec.getNumFields() ){
+ if( d_data.isNull() ){
+ const Record::FieldVector& fields = rec.getFields();
+ Datatype dt("__cvc4_record");
+ dt.setRecord();
+ DatatypeConstructor c("__cvc4_record_ctor");
+ for(Record::FieldVector::const_iterator i = fields.begin(); i != fields.end(); ++i) {
+ c.addArg((*i).first, (*i).second);
+ }
+ dt.addConstructor(c);
+ d_data = TypeNode::fromType(nm->toExprManager()->mkDatatypeType(dt));
+ Debug("tuprec-debug") << "Return type : " << d_data << std::endl;
+ }
+ return d_data;
+ }else{
+ return d_children[TypeNode::fromType( rec[index].second )][rec[index].first].getRecordType( nm, rec, index+1 );
+ }
+}
+
TypeNode NodeManager::mkTupleType(const std::vector<TypeNode>& types) {
std::vector< TypeNode > ts;
Debug("tuprec-debug") << "Make tuple type : ";
@@ -470,60 +513,11 @@ TypeNode NodeManager::mkTupleType(const std::vector<TypeNode>& types) {
Debug("tuprec-debug") << types[i] << " ";
}
Debug("tuprec-debug") << std::endl;
- //index based on function type
- TypeNode tindex;
- if( types.empty() ){
- //do nothing (will index on null type)
- }else if( types.size()==1 ){
- tindex = types[0];
- }else{
- TypeNode tt = ts.back();
- ts.pop_back();
- tindex = mkFunctionType( ts, tt );
- ts.push_back( tt );
- }
- TypeNode& dtt = d_tupleAndRecordTypes[tindex];
- if(dtt.isNull()) {
- Datatype dt("__cvc4_tuple");
- dt.setTuple();
- DatatypeConstructor c("__cvc4_tuple_ctor");
- for (unsigned i = 0; i < ts.size(); ++ i) {
- std::stringstream ss;
- ss << "__cvc4_tuple_stor_" << i;
- c.addArg(ss.str().c_str(), ts[i].toType());
- }
- dt.addConstructor(c);
- dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt));
- dtt.setAttribute(DatatypeTupleAttr(), tindex);
- Debug("tuprec-debug") << "Return type : " << dtt << std::endl;
- }else{
- Debug("tuprec-debug") << "Return cached type : " << dtt << std::endl;
- }
- Assert(!dtt.isNull());
- return dtt;
+ return d_tt_cache.getTupleType( this, ts );
}
TypeNode NodeManager::mkRecordType(const Record& rec) {
- //index based on type constant
- TypeNode tindex = mkTypeConst(rec);
- TypeNode& dtt = d_tupleAndRecordTypes[tindex];
- if(dtt.isNull()) {
- const Record::FieldVector& fields = rec.getFields();
- Datatype dt("__cvc4_record");
- dt.setRecord();
- DatatypeConstructor c("__cvc4_record_ctor");
- for(Record::FieldVector::const_iterator i = fields.begin(); i != fields.end(); ++i) {
- c.addArg((*i).first, (*i).second);
- }
- dt.addConstructor(c);
- dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt));
- dtt.setAttribute(DatatypeRecordAttr(), tindex);
- Debug("tuprec-debug") << "Return type : " << dtt << std::endl;
- }else{
- Debug("tuprec-debug") << "Return cached type : " << dtt << std::endl;
- }
- Assert(!dtt.isNull());
- return dtt;
+ return d_rt_cache.getRecordType( this, rec );
}
void NodeManager::reclaimAllZombies(){
diff --git a/src/expr/node_manager.h b/src/expr/node_manager.h
index 45c9afbde..7d2b13e4c 100644
--- a/src/expr/node_manager.h
+++ b/src/expr/node_manager.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_manager.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Christopher L. Conway, Morgan Deters
- ** Minor contributors (to current version): ACSYS, Tianyi Liang, Kshitij Bansal, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A manager for Nodes
**
@@ -166,7 +166,20 @@ class NodeManager {
/**
* A map of tuple and record types to their corresponding datatype.
*/
- std::hash_map<TypeNode, TypeNode, TypeNodeHashFunction> d_tupleAndRecordTypes;
+ class TupleTypeCache {
+ public:
+ std::map< TypeNode, TupleTypeCache > d_children;
+ TypeNode d_data;
+ TypeNode getTupleType( NodeManager * nm, std::vector< TypeNode >& types, unsigned index = 0 );
+ };
+ class RecTypeCache {
+ public:
+ std::map< TypeNode, std::map< std::string, RecTypeCache > > d_children;
+ TypeNode d_data;
+ TypeNode getRecordType( NodeManager * nm, const Record& rec, unsigned index = 0 );
+ };
+ TupleTypeCache d_tt_cache;
+ RecTypeCache d_rt_cache;
/**
* Keep a count of all abstract values produced by this NodeManager.
@@ -692,7 +705,7 @@ public:
inline TypeNode stringType();
/** Get the (singleton) type for RegExp. */
- inline TypeNode regexpType();
+ inline TypeNode regExpType();
/** Get the (singleton) type for rounding modes. */
inline TypeNode roundingModeType();
@@ -988,7 +1001,7 @@ inline TypeNode NodeManager::stringType() {
}
/** Get the (singleton) type for regexps. */
-inline TypeNode NodeManager::regexpType() {
+inline TypeNode NodeManager::regExpType() {
return TypeNode(mkTypeConst<TypeConstant>(REGEXP_TYPE));
}
diff --git a/src/expr/node_manager_attributes.h b/src/expr/node_manager_attributes.h
index 41086ac21..20e1c6c50 100644
--- a/src/expr/node_manager_attributes.h
+++ b/src/expr/node_manager_attributes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_manager_attributes.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -28,8 +28,6 @@ namespace attr {
struct VarNameTag { };
struct GlobalVarTag { };
struct SortArityTag { };
- struct DatatypeTupleTag { };
- struct DatatypeRecordTag { };
struct TypeTag { };
struct TypeCheckedTag { };
}/* CVC4::expr::attr namespace */
@@ -37,10 +35,6 @@ namespace attr {
typedef Attribute<attr::VarNameTag, std::string> VarNameAttr;
typedef Attribute<attr::GlobalVarTag(), bool> GlobalVarAttr;
typedef Attribute<attr::SortArityTag, uint64_t> SortArityAttr;
-/** Attribute true for datatype types that are replacements for tuple types */
-typedef expr::Attribute<expr::attr::DatatypeTupleTag, TypeNode> DatatypeTupleAttr;
-/** Attribute true for datatype types that are replacements for record types */
-typedef expr::Attribute<expr::attr::DatatypeRecordTag, TypeNode> DatatypeRecordAttr;
typedef expr::Attribute<expr::attr::TypeTag, TypeNode> TypeAttr;
typedef expr::Attribute<expr::attr::TypeCheckedTag, bool> TypeCheckedAttr;
diff --git a/src/expr/node_manager_listeners.cpp b/src/expr/node_manager_listeners.cpp
index ec2de105a..3915aa9bd 100644
--- a/src/expr/node_manager_listeners.cpp
+++ b/src/expr/node_manager_listeners.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file node_manager_listeners.h
+/*! \file node_manager_listeners.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Listeners that NodeManager registers to its Options object.
**
diff --git a/src/expr/node_manager_listeners.h b/src/expr/node_manager_listeners.h
index fc7c2f65f..caff3a545 100644
--- a/src/expr/node_manager_listeners.h
+++ b/src/expr/node_manager_listeners.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_manager_listeners.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Listeners that NodeManager registers to its Options object.
**
diff --git a/src/expr/node_self_iterator.h b/src/expr/node_self_iterator.h
index 77fc05e3b..9d37f6e6e 100644
--- a/src/expr/node_self_iterator.h
+++ b/src/expr/node_self_iterator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_self_iterator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Iterator supporting Node "self-iteration"
**
diff --git a/src/expr/node_value.cpp b/src/expr/node_value.cpp
index ab18973cb..a40075ca9 100644
--- a/src/expr/node_value.cpp
+++ b/src/expr/node_value.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_value.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An expression node.
**
diff --git a/src/expr/node_value.h b/src/expr/node_value.h
index c39c14604..fbf3ff76e 100644
--- a/src/expr/node_value.h
+++ b/src/expr/node_value.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_value.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Christopher L. Conway, Tim King, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An expression node.
**
diff --git a/src/expr/pickle_data.cpp b/src/expr/pickle_data.cpp
index e273bcece..2050d2d15 100644
--- a/src/expr/pickle_data.cpp
+++ b/src/expr/pickle_data.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file pickle_data.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a "pickle" for expressions, CVC4-internal view
**
diff --git a/src/expr/pickle_data.h b/src/expr/pickle_data.h
index acf0dccdd..6c283719a 100644
--- a/src/expr/pickle_data.h
+++ b/src/expr/pickle_data.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file pickle_data.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a "pickle" for expressions, CVC4-internal view
**
diff --git a/src/expr/pickler.cpp b/src/expr/pickler.cpp
index d0501ca2b..ab8037a9a 100644
--- a/src/expr/pickler.cpp
+++ b/src/expr/pickler.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file pickler.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King, Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a "pickler" for expressions
**
diff --git a/src/expr/pickler.h b/src/expr/pickler.h
index cf1754d93..abd927788 100644
--- a/src/expr/pickler.h
+++ b/src/expr/pickler.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file pickler.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a "pickler" for expressions
**
diff --git a/src/expr/predicate.cpp b/src/expr/predicate.cpp
index 5ccc3484a..52b580148 100644
--- a/src/expr/predicate.cpp
+++ b/src/expr/predicate.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file predicate.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of predicates for predicate subtyping
**
diff --git a/src/expr/predicate.h b/src/expr/predicate.h
index 669ecc29f..a7003fbd1 100644
--- a/src/expr/predicate.h
+++ b/src/expr/predicate.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file predicate.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of predicates for predicate subtyping
**
diff --git a/src/expr/record.cpp b/src/expr/record.cpp
index ec5ef96f1..0d2fd6527 100644
--- a/src/expr/record.cpp
+++ b/src/expr/record.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file record.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class representing a record definition
**
diff --git a/src/expr/record.h b/src/expr/record.h
index d30536fb0..84feb7e1d 100644
--- a/src/expr/record.h
+++ b/src/expr/record.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file record.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class representing a Record definition
**
diff --git a/src/expr/symbol_table.cpp b/src/expr/symbol_table.cpp
index c0a80b7ce..185006e73 100644
--- a/src/expr/symbol_table.cpp
+++ b/src/expr/symbol_table.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file symbol_table.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Andrew Reynolds, Dejan Jovanovic, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Convenience class for scoping variable and type
** declarations (implementation)
diff --git a/src/expr/symbol_table.h b/src/expr/symbol_table.h
index 451a482dc..efd0f1a13 100644
--- a/src/expr/symbol_table.h
+++ b/src/expr/symbol_table.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file symbol_table.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Andrew Reynolds, Dejan Jovanovic, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Convenience class for scoping variable and type declarations.
**
diff --git a/src/expr/type.cpp b/src/expr/type.cpp
index 6b5bdf07c..0c4d554ef 100644
--- a/src/expr/type.cpp
+++ b/src/expr/type.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file type.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Dejan Jovanovic, Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of expression types
**
@@ -223,6 +223,12 @@ bool Type::isString() const {
return d_typeNode->isString();
}
+/** Is this the regexp type? */
+bool Type::isRegExp() const {
+ NodeManagerScope nms(d_nodeManager);
+ return d_typeNode->isRegExp();
+}
+
/** Is this the rounding mode type? */
bool Type::isRoundingMode() const {
NodeManagerScope nms(d_nodeManager);
@@ -427,6 +433,11 @@ StringType::StringType(const Type& t) throw(IllegalArgumentException) :
PrettyCheckArgument(isNull() || isString(), this);
}
+RegExpType::RegExpType(const Type& t) throw(IllegalArgumentException) :
+ Type(t) {
+ PrettyCheckArgument(isNull() || isRegExp(), this);
+}
+
RoundingModeType::RoundingModeType(const Type& t) throw(IllegalArgumentException) :
Type(t) {
PrettyCheckArgument(isNull() || isRoundingMode(), this);
diff --git a/src/expr/type.h b/src/expr/type.h
index 67d259fec..43cb3ffbf 100644
--- a/src/expr/type.h
+++ b/src/expr/type.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Dejan Jovanovic, Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds, Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Martin Brain
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interface for expression types.
**
@@ -47,6 +47,7 @@ class BooleanType;
class IntegerType;
class RealType;
class StringType;
+class RegExpType;
class RoundingModeType;
class BitVectorType;
class ArrayType;
@@ -258,6 +259,12 @@ public:
bool isString() const;
/**
+ * Is this the regexp type?
+ * @return true if the type is the regexp type
+ */
+ bool isRegExp() const;
+
+ /**
* Is this the rounding mode type?
* @return true if the type is the rounding mode type
*/
@@ -424,6 +431,18 @@ public:
};/* class StringType */
/**
+ * Singleton class encapsulating the string type.
+ */
+class CVC4_PUBLIC RegExpType : public Type {
+
+public:
+
+ /** Construct from the base type */
+ RegExpType(const Type& type) throw(IllegalArgumentException);
+};/* class RegExpType */
+
+
+/**
* Singleton class encapsulating the rounding mode type.
*/
class CVC4_PUBLIC RoundingModeType : public Type {
diff --git a/src/expr/type_checker.h b/src/expr/type_checker.h
index 4b04adfc9..3df73b268 100644
--- a/src/expr/type_checker.h
+++ b/src/expr/type_checker.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_checker.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A type checker
**
diff --git a/src/expr/type_checker_template.cpp b/src/expr/type_checker_template.cpp
index 061e1b4e0..8ed894a22 100644
--- a/src/expr/type_checker_template.cpp
+++ b/src/expr/type_checker_template.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_checker_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief TypeChecker implementation
**
diff --git a/src/expr/type_node.cpp b/src/expr/type_node.cpp
index 755b16e46..5d672e6ac 100644
--- a/src/expr/type_node.cpp
+++ b/src/expr/type_node.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_node.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Kshitij Bansal, Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Reference-counted encapsulation of a pointer to node information.
**
@@ -93,46 +93,28 @@ bool TypeNode::isSubtypeOf(TypeNode t) const {
t.getConst<TypeConstant>() == REAL_TYPE );
}
}
- if(isTuple() || isRecord()) {
- if(isTuple() != t.isTuple() || isRecord() != t.isRecord()) {
+ if(isTuple() && t.isTuple()) {
+ const Datatype& dt1 = getDatatype();
+ const Datatype& dt2 = t.getDatatype();
+ if( dt1[0].getNumArgs()!=dt2[0].getNumArgs() ){
return false;
}
- if(isTuple()) {
- if(getNumChildren() != t.getNumChildren()) {
+ // r1's fields must be subtypes of r2's, in order
+ for( unsigned i=0; i<dt1[0].getNumArgs(); i++ ){
+ if( !dt1[0][i].getRangeType().isSubtypeOf( dt2[0][i].getRangeType() ) ){
return false;
}
- // children must be subtypes of t's, in order
- for(const_iterator i = begin(), j = t.begin(); i != end(); ++i, ++j) {
- if(!(*i).isSubtypeOf(*j)) {
- return false;
- }
- }
- } else {
- const Record& r1 = getRecord();
- const Record& r2 = t.getRecord();
- if(r1.getNumFields() != r2.getNumFields()) {
- return false;
- }
- const Record::FieldVector& fields1 = r1.getFields();
- const Record::FieldVector& fields2 = r2.getFields();
- // r1's fields must be subtypes of r2's, in order
- // names must match also
- for(Record::FieldVector::const_iterator i = fields1.begin(), j = fields2.begin(); i != fields1.end(); ++i, ++j) {
- if((*i).first != (*j).first || !(*i).second.isSubtypeOf((*j).second)) {
- return false;
- }
- }
}
return true;
+ }else if( t.isRecord() && t.isRecord() ){
+ //records are not subtypes of each other in current implementation
}
if(isFunction()) {
// A function is a subtype of another if the args are the same type, and
// the return type is a subtype of the other's. This is enough for now
// (and it's necessary for model generation, since a Real-valued function
// might return a constant Int and thus the model value is typed differently).
- return t.isFunction() &&
- getArgTypes() == t.getArgTypes() &&
- getRangeType().isSubtypeOf(t.getRangeType());
+ return t.isFunction() && getArgTypes() == t.getArgTypes() && getRangeType().isSubtypeOf(t.getRangeType());
}
if(isParametricDatatype() && t.isParametricDatatype()) {
Assert(getKind() == kind::PARAMETRIC_DATATYPE);
@@ -153,6 +135,11 @@ bool TypeNode::isSubtypeOf(TypeNode t) const {
if(isSet() && t.isSet()) {
return getSetElementType().isSubtypeOf(t.getSetElementType());
}
+ if(isArray() && t.isArray()) {
+ //reverse for index type
+ return t.getArrayIndexType().isSubtypeOf(getArrayIndexType()) &&
+ getArrayConstituentType().isSubtypeOf(t.getArrayConstituentType());
+ }
return false;
}
@@ -163,39 +150,21 @@ bool TypeNode::isComparableTo(TypeNode t) const {
if(isSubtypeOf(NodeManager::currentNM()->realType())) {
return t.isSubtypeOf(NodeManager::currentNM()->realType());
}
- if(isTuple() || isRecord()) {
- if(t.isTuple() || t.isRecord()) {
- if(isTuple() != t.isTuple() || isRecord() != t.isRecord()) {
+ if(isTuple() && t.isTuple()) {
+ const Datatype& dt1 = getDatatype();
+ const Datatype& dt2 = t.getDatatype();
+ if( dt1[0].getNumArgs()!=dt2[0].getNumArgs() ){
+ return false;
+ }
+ // r1's fields must be subtypes of r2's, in order
+ for( unsigned i=0; i<dt1[0].getNumArgs(); i++ ){
+ if( !dt1[0][i].getRangeType().isComparableTo( dt2[0][i].getRangeType() ) ){
return false;
}
- if(isTuple()) {
- if(getNumChildren() != t.getNumChildren()) {
- return false;
- }
- // children must be comparable to t's, in order
- for(const_iterator i = begin(), j = t.begin(); i != end(); ++i, ++j) {
- if(!(*i).isComparableTo(*j)) {
- return false;
- }
- }
- } else {
- const Record& r1 = getRecord();
- const Record& r2 = t.getRecord();
- if(r1.getNumFields() != r2.getNumFields()) {
- return false;
- }
- // r1's fields must be comparable to r2's, in order
- // names must match also
- const Record::FieldVector& fields1 = r1.getFields();
- const Record::FieldVector& fields2 = r2.getFields();
- for(Record::FieldVector::const_iterator i = fields1.begin(), j = fields2.begin(); i != fields1.end(); ++i, ++j) {
- if((*i).first != (*j).first || !(*i).second.isComparableTo((*j).second)) {
- return false;
- }
- }
- }
- return true;
}
+ return true;
+ //}else if( isRecord() && t.isRecord() ){
+ //record types are incomparable in current implementation
} else if(isParametricDatatype() && t.isParametricDatatype()) {
Assert(getKind() == kind::PARAMETRIC_DATATYPE);
Assert(t.getKind() == kind::PARAMETRIC_DATATYPE);
@@ -211,10 +180,12 @@ bool TypeNode::isComparableTo(TypeNode t) const {
} else if(isSet() && t.isSet()) {
return getSetElementType().isComparableTo(t.getSetElementType());
}
-
- if(isPredicateSubtype()) {
- return t.isComparableTo(getSubtypeParentType());
+ if(isArray() && t.isArray()) {
+ return getArrayIndexType().isComparableTo(t.getArrayIndexType()) && getArrayConstituentType().isComparableTo(t.getArrayConstituentType());
}
+ //if(isPredicateSubtype()) {
+ // return t.isComparableTo(getSubtypeParentType());
+ //}
return false;
}
@@ -271,13 +242,13 @@ std::vector<TypeNode> TypeNode::getParamTypes() const {
/** Is this a tuple type? */
bool TypeNode::isTuple() const {
- return ( getKind() == kind::DATATYPE_TYPE && hasAttribute(expr::DatatypeTupleAttr()) ) ||
+ return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isTuple() ) ||
( isPredicateSubtype() && getSubtypeParentType().isTuple() );
}
/** Is this a record type? */
bool TypeNode::isRecord() const {
- return ( getKind() == kind::DATATYPE_TYPE && hasAttribute(expr::DatatypeRecordAttr()) ) ||
+ return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isRecord() ) ||
( isPredicateSubtype() && getSubtypeParentType().isRecord() );
}
@@ -294,14 +265,16 @@ vector<TypeNode> TypeNode::getTupleTypes() const {
Assert(dt.getNumConstructors()==1);
vector<TypeNode> types;
for(unsigned i = 0; i < dt[0].getNumArgs(); ++i) {
- types.push_back(TypeNode::fromType(((SelectorType)dt[0][i].getSelector().getType()).getRangeType()));
+ types.push_back(TypeNode::fromType(dt[0][i].getRangeType()));
}
return types;
}
const Record& TypeNode::getRecord() const {
Assert(isRecord());
- return getAttribute(expr::DatatypeRecordAttr()).getConst<Record>();
+ const Datatype & dt = getDatatype();
+ return *(dt.getRecord());
+ //return getAttribute(expr::DatatypeRecordAttr()).getConst<Record>();
}
vector<TypeNode> TypeNode::getSExprTypes() const {
@@ -341,6 +314,14 @@ bool TypeNode::isParameterInstantiatedDatatype(unsigned n) const {
}
TypeNode TypeNode::leastCommonTypeNode(TypeNode t0, TypeNode t1){
+ return commonTypeNode( t0, t1, true );
+}
+
+TypeNode TypeNode::mostCommonTypeNode(TypeNode t0, TypeNode t1){
+ return commonTypeNode( t0, t1, false );
+}
+
+TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) {
Assert( NodeManager::currentNM() != NULL,
"There is no current CVC4::NodeManager associated to this thread.\n"
"Perhaps a public-facing function is missing a NodeManagerScope ?" );
@@ -361,65 +342,75 @@ TypeNode TypeNode::leastCommonTypeNode(TypeNode t0, TypeNode t1){
return t0; //IntegerType
} else if(t1.isReal()) {
// t0 == IntegerType && t1.isReal() && !t1.isInteger()
- return NodeManager::currentNM()->realType(); // RealType
+ return isLeast ? t1 : t0; // RealType
} else {
return TypeNode(); // null type
}
case REAL_TYPE:
if(t1.isReal()) {
- return t0; // RealType
+ return isLeast ? t0 : t1; // RealType
} else {
return TypeNode(); // null type
}
default:
- if(t1.isPredicateSubtype() && t1.getSubtypeParentType().isSubtypeOf(t0)) {
- return t0; // t0 is a constant type
- } else {
+ //if(t1.isPredicateSubtype() && t1.getSubtypeParentType().isSubtypeOf(t0)) {
+ // return t0; // t0 is a constant type
+ //} else {
return TypeNode(); // null type
- }
+ //}
}
} else if(t1.getKind() == kind::TYPE_CONSTANT) {
- return leastCommonTypeNode(t1, t0); // decrease the number of special cases
+ return commonTypeNode(t1, t0, isLeast); // decrease the number of special cases
}
// t0 != t1 &&
// t0.getKind() == kind::TYPE_CONSTANT &&
// t1.getKind() == kind::TYPE_CONSTANT
switch(t0.getKind()) {
- case kind::ARRAY_TYPE:
case kind::BITVECTOR_TYPE:
case kind::SORT_TYPE:
case kind::CONSTRUCTOR_TYPE:
case kind::SELECTOR_TYPE:
case kind::TESTER_TYPE:
- if(t1.isPredicateSubtype() && t1.getSubtypeParentType().isSubtypeOf(t0)) {
- return t0;
- } else {
+ //if( t1.isPredicateSubtype() && t1.getSubtypeParentType().isSubtypeOf(t0)) {
+ // return t0;
+ //} else {
return TypeNode();
- }
+ //}
case kind::FUNCTION_TYPE:
return TypeNode(); // Not sure if this is right
case kind::SET_TYPE: {
// take the least common subtype of element types
TypeNode elementType;
- if(t1.isSet() &&
- ! (elementType = leastCommonTypeNode(t0[0], t1[0])).isNull() ) {
+ if(t1.isSet() && !(elementType = commonTypeNode(t0[0], t1[0], isLeast)).isNull() ) {
return NodeManager::currentNM()->mkSetType(elementType);
} else {
return TypeNode();
}
}
+ case kind::ARRAY_TYPE: {
+ TypeNode indexType, elementType;
+ if(t1.isArray() &&
+ ! (indexType = commonTypeNode(t0[0], t1[0], !isLeast)).isNull() &&
+ ! (elementType = commonTypeNode(t0[1], t1[1], isLeast)).isNull() ) {
+ return NodeManager::currentNM()->mkArrayType(indexType, elementType);
+ } else {
+ return TypeNode();
+ }
+ }
case kind::SEXPR_TYPE:
Unimplemented("haven't implemented leastCommonType for symbolic expressions yet");
return TypeNode();
case kind::SUBTYPE_TYPE:
- if(t1.isPredicateSubtype()){
- // This is the case where both t0 and t1 are predicate subtypes.
- return leastCommonPredicateSubtype(t0, t1);
- }else{ // t0 is a predicate subtype and t1 is not
- return leastCommonTypeNode(t1, t0); //decrease the number of special cases
- }
+ //if(t1.isPredicateSubtype()){
+ // // This is the case where both t0 and t1 are predicate subtypes.
+ // return leastCommonPredicateSubtype(t0, t1);
+ //}else{ // t0 is a predicate subtype and t1 is not
+ // return commonTypeNode(t1, t0, isLeast); //decrease the number of special cases
+ //}
+ return TypeNode();
case kind::SUBRANGE_TYPE:
+ /*
if(t1.isSubrange()) {
const SubrangeBounds& t0SR = t0.getSubrangeBounds();
const SubrangeBounds& t1SR = t1.getSubrangeBounds();
@@ -449,62 +440,28 @@ TypeNode TypeNode::leastCommonTypeNode(TypeNode t0, TypeNode t1){
Assert(t1.isInteger());
return TypeNode();
}
-/*
- case kind::TUPLE_TYPE: {
- // if the other == this one, we returned already, above
- if(t0.getBaseType() == t1) {
- return t1;
- }
- if(!t1.isTuple() || t0.getNumChildren() != t1.getNumChildren()) {
- // no compatibility between t0, t1
- return TypeNode();
- }
- std::vector<TypeNode> types;
- // construct childwise leastCommonType, if one exists
- for(const_iterator i = t0.begin(), j = t1.begin(); i != t0.end(); ++i, ++j) {
- TypeNode kid = leastCommonTypeNode(*i, *j);
- if(kid.isNull()) {
- // no common supertype: types t0, t1 not compatible
- return TypeNode();
- }
- types.push_back(kid);
- }
- // if we make it here, we constructed the least common type
- return NodeManager::currentNM()->mkTupleType(types);
- }
- case kind::RECORD_TYPE: {
- // if the other == this one, we returned already, above
- if(t0.getBaseType() == t1) {
- return t1;
- }
- const Record& r0 = t0.getConst<Record>();
- if(!t1.isRecord() || r0.getNumFields() != t1.getConst<Record>().getNumFields()) {
- // no compatibility between t0, t1
- return TypeNode();
- }
- std::vector< std::pair<std::string, Type> > fields;
- const Record& r1 = t1.getConst<Record>();
- const Record::FieldVector& fields0 = r0.getFields();
- const Record::FieldVector& fields1 = r1.getFields();
- // construct childwise leastCommonType, if one exists
- for(Record::FieldVector::const_iterator i = fields0.begin(), j = fields1.begin(); i != fields0.end(); ++i, ++j) {
- TypeNode kid = leastCommonTypeNode(TypeNode::fromType((*i).second), TypeNode::fromType((*j).second));
- if((*i).first != (*j).first || kid.isNull()) {
- // if field names differ, or no common supertype, then
- // types t0, t1 not compatible
- return TypeNode();
- }
- fields.push_back(std::make_pair((*i).first, kid.toType()));
- }
- // if we make it here, we constructed the least common type
- return NodeManager::currentNM()->mkRecordType(Record(fields));
- }
*/
+ return TypeNode();
case kind::DATATYPE_TYPE:
- // t1 might be a subtype tuple or record
- if(t1.getBaseType() == t0) {
- return t0;
+ if( t0.isTuple() && t1.isTuple() ){
+ const Datatype& dt1 = t0.getDatatype();
+ const Datatype& dt2 = t1.getDatatype();
+ if( dt1[0].getNumArgs()==dt2[0].getNumArgs() ){
+ std::vector< TypeNode > lc_types;
+ for( unsigned i=0; i<dt1[0].getNumArgs(); i++ ){
+ TypeNode tc = commonTypeNode( TypeNode::fromType( dt1[0][i].getRangeType() ), TypeNode::fromType( dt2[0][i].getRangeType() ), isLeast );
+ if( tc.isNull() ){
+ return tc;
+ }else{
+ lc_types.push_back( tc );
+ }
+ }
+ return NodeManager::currentNM()->mkTupleType( lc_types );
+ }
}
+ //else if( t0.isRecord() && t1.isRecord() ){
+ //record types are not related in current implementation
+ //}
// otherwise no common ancestor
return TypeNode();
case kind::PARAMETRIC_DATATYPE: {
@@ -519,12 +476,12 @@ TypeNode TypeNode::leastCommonTypeNode(TypeNode t0, TypeNode t1){
}
vector<Type> v;
for(size_t i = 1; i < t0.getNumChildren(); ++i) {
- v.push_back(leastCommonTypeNode(t0[i], t1[i]).toType());
+ v.push_back(commonTypeNode(t0[i], t1[i], isLeast).toType());
}
return TypeNode::fromType(t0[0].getDatatype().getDatatypeType(v));
}
default:
- Unimplemented("don't have a leastCommonType for types `%s' and `%s'", t0.toString().c_str(), t1.toString().c_str());
+ Unimplemented("don't have a commonType for types `%s' and `%s'", t0.toString().c_str(), t1.toString().c_str());
return TypeNode();
}
}
diff --git a/src/expr/type_node.h b/src/expr/type_node.h
index 4c48cc3ca..cfb61a085 100644
--- a/src/expr/type_node.h
+++ b/src/expr/type_node.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_node.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Clark Barrett, Andrew Reynolds, Tianyi Liang, Kshitij Bansal, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Martin Brain
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Reference-counted encapsulation of a pointer to node information.
**
@@ -642,8 +642,10 @@ public:
* For more information see: http://cvc4.cs.nyu.edu/wiki/Cvc4_Type_Lattice
*/
static TypeNode leastCommonTypeNode(TypeNode t0, TypeNode t1);
+ static TypeNode mostCommonTypeNode(TypeNode t0, TypeNode t1);
private:
+ static TypeNode commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast);
/**
* Returns the leastUpperBound in the extended type lattice of two
diff --git a/src/expr/type_properties_template.h b/src/expr/type_properties_template.h
index bc780a7e5..4874a84b8 100644
--- a/src/expr/type_properties_template.h
+++ b/src/expr/type_properties_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_properties_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Template for the Type properties header
**
diff --git a/src/expr/uninterpreted_constant.cpp b/src/expr/uninterpreted_constant.cpp
index 97bc3ae4b..c88c3b591 100644
--- a/src/expr/uninterpreted_constant.cpp
+++ b/src/expr/uninterpreted_constant.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file uninterpreted_constant.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of constants of uninterpreted sorts
**
diff --git a/src/expr/uninterpreted_constant.h b/src/expr/uninterpreted_constant.h
index 5b2293df6..7d7a3759b 100644
--- a/src/expr/uninterpreted_constant.h
+++ b/src/expr/uninterpreted_constant.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file uninterpreted_constant.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of constants of uninterpreted sorts
**
diff --git a/src/expr/variable_type_map.h b/src/expr/variable_type_map.h
index 59ce5c606..00d2c3eac 100644
--- a/src/expr/variable_type_map.h
+++ b/src/expr/variable_type_map.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file variable_type_map.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/include/cvc4.h b/src/include/cvc4.h
index 90088de40..6e6204c58 100644
--- a/src/include/cvc4.h
+++ b/src/include/cvc4.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Main header file for CVC4 library functionality
**
diff --git a/src/include/cvc4_private.h b/src/include/cvc4_private.h
index ccc850787..56be6ff71 100644
--- a/src/include/cvc4_private.h
+++ b/src/include/cvc4_private.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4_private.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief #-inclusion of this file marks a header as private and generates a
** warning when the file is included improperly
diff --git a/src/include/cvc4_private_library.h b/src/include/cvc4_private_library.h
index e0127946d..c536d0586 100644
--- a/src/include/cvc4_private_library.h
+++ b/src/include/cvc4_private_library.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4_private_library.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief #-inclusion of this file marks a header as private and generates a
** warning when the file is included improperly
diff --git a/src/include/cvc4_public.h b/src/include/cvc4_public.h
index f299c7237..1308b3d96 100644
--- a/src/include/cvc4_public.h
+++ b/src/include/cvc4_public.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4_public.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Macros that should be defined everywhere during the building of
** the libraries and driver binary, and also exported to the user.
diff --git a/src/include/cvc4parser_private.h b/src/include/cvc4parser_private.h
index c107c4f56..366877c96 100644
--- a/src/include/cvc4parser_private.h
+++ b/src/include/cvc4parser_private.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4parser_private.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief #-inclusion of this file marks a header as private and generates a
** warning when the file is included improperly.
diff --git a/src/include/cvc4parser_public.h b/src/include/cvc4parser_public.h
index edb189c19..ccbd09066 100644
--- a/src/include/cvc4parser_public.h
+++ b/src/include/cvc4parser_public.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc4parser_public.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Macros that should be defined everywhere during the building of
** the libraries and driver binary, and also exported to the user.
diff --git a/src/lib/clock_gettime.c b/src/lib/clock_gettime.c
index 3f1d36f0f..9bd4eafe8 100644
--- a/src/lib/clock_gettime.c
+++ b/src/lib/clock_gettime.c
@@ -1,13 +1,13 @@
/********************* */
/*! \file clock_gettime.c
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Replacement for clock_gettime() for systems without it (like
** Mac OS X)
@@ -16,7 +16,7 @@
** OS X).
**/
-#warning "TODO(taking): Make lib/clock_gettime.h cvc4_private.h again."
+// #warning "TODO(taking): Make lib/clock_gettime.h cvc4_private.h again."
#include "lib/clock_gettime.h"
diff --git a/src/lib/clock_gettime.h b/src/lib/clock_gettime.h
index 3a181bef5..74c9f5088 100644
--- a/src/lib/clock_gettime.h
+++ b/src/lib/clock_gettime.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file clock_gettime.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Replacement for clock_gettime() for systems without it (like Mac OS X)
**
diff --git a/src/lib/ffs.c b/src/lib/ffs.c
index d4481d2ca..81228be63 100644
--- a/src/lib/ffs.c
+++ b/src/lib/ffs.c
@@ -1,13 +1,13 @@
/********************* */
/*! \file ffs.c
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Replacement for ffs() for systems without it (like Win32)
**
diff --git a/src/lib/ffs.h b/src/lib/ffs.h
index 44fb40674..878c8f7cf 100644
--- a/src/lib/ffs.h
+++ b/src/lib/ffs.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ffs.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Replacement for ffs() for systems without it (like Win32)
**
diff --git a/src/lib/replacements.h b/src/lib/replacements.h
index b6acc1c7d..d2f7d9f4f 100644
--- a/src/lib/replacements.h
+++ b/src/lib/replacements.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file replacements.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Common header for replacement function sources
**
diff --git a/src/lib/strtok_r.c b/src/lib/strtok_r.c
index da49aaada..9173596a3 100644
--- a/src/lib/strtok_r.c
+++ b/src/lib/strtok_r.c
@@ -1,13 +1,13 @@
/********************* */
/*! \file strtok_r.c
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Replacement for strtok_r() for systems without it (like Win32)
**
diff --git a/src/lib/strtok_r.h b/src/lib/strtok_r.h
index cc737043b..e3803b0c1 100644
--- a/src/lib/strtok_r.h
+++ b/src/lib/strtok_r.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file strtok_r.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Replacement for strtok_r() for systems without it (like Win32)
**
diff --git a/src/main/command_executor.cpp b/src/main/command_executor.cpp
index 672dedc50..320be701d 100644
--- a/src/main/command_executor.cpp
+++ b/src/main/command_executor.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file command_executor.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds, Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An additional layer between commands and invoking them.
**/
@@ -115,6 +115,10 @@ bool CommandExecutor::doCommandSingleton(Command* cmd)
if(q != NULL) {
d_result = res = q->getResult();
}
+ CheckSynthCommand* csy = dynamic_cast<CheckSynthCommand*>(cmd);
+ if(csy != NULL) {
+ d_result = res = csy->getResult();
+ }
if((cs != NULL || q != NULL) && d_options.getStatsEveryQuery()) {
std::ostringstream ossCurStats;
diff --git a/src/main/command_executor.h b/src/main/command_executor.h
index d8294212a..4018aeda1 100644
--- a/src/main/command_executor.h
+++ b/src/main/command_executor.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file command_executor.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An additional layer between commands and invoking them.
**/
diff --git a/src/main/command_executor_portfolio.cpp b/src/main/command_executor_portfolio.cpp
index 15165e82c..1902e1817 100644
--- a/src/main/command_executor_portfolio.cpp
+++ b/src/main/command_executor_portfolio.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file command_executor_portfolio.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An additional layer between commands and invoking them.
**
@@ -198,7 +198,8 @@ bool CommandExecutorPortfolio::doCommandSingleton(Command* cmd)
// command
if(dynamic_cast<CheckSatCommand*>(cmd) != NULL ||
- dynamic_cast<QueryCommand*>(cmd) != NULL) {
+ dynamic_cast<QueryCommand*>(cmd) != NULL ||
+ dynamic_cast<CheckSynthCommand*>(cmd) != NULL) {
mode = 1;
} else if(dynamic_cast<GetValueCommand*>(cmd) != NULL ||
dynamic_cast<GetAssignmentCommand*>(cmd) != NULL ||
diff --git a/src/main/command_executor_portfolio.h b/src/main/command_executor_portfolio.h
index ce9a80a4e..be980a01b 100644
--- a/src/main/command_executor_portfolio.h
+++ b/src/main/command_executor_portfolio.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file command_executor_portfolio.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An additional layer between commands and invoking them.
**
diff --git a/src/main/driver_unified.cpp b/src/main/driver_unified.cpp
index b83907bd3..bab70e98f 100644
--- a/src/main/driver_unified.cpp
+++ b/src/main/driver_unified.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file driver_unified.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Driver for CVC4 executable (cvc4) unified for both
** sequential and portfolio versions
@@ -101,7 +101,7 @@ int runCvc4(int argc, char* argv[], Options& opts) {
progPath = argv[0];
// Parse the options
- vector<string> filenames = opts.parseOptions(argc, argv);
+ vector<string> filenames = Options::parseOptions(&opts, argc, argv);
# ifndef PORTFOLIO_BUILD
if( opts.wasSetByUserThreads() ||
diff --git a/src/main/interactive_shell.cpp b/src/main/interactive_shell.cpp
index 4982cb2bb..e11f82a40 100644
--- a/src/main/interactive_shell.cpp
+++ b/src/main/interactive_shell.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file interactive_shell.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interactive shell for CVC4
**
diff --git a/src/main/interactive_shell.h b/src/main/interactive_shell.h
index 844fddf45..18e42f1e5 100644
--- a/src/main/interactive_shell.h
+++ b/src/main/interactive_shell.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file interactive_shell.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interactive shell for CVC4
**/
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 56fc3ef40..7b6b9ad86 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file main.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Clark Barrett, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Main driver for CVC4 executable
**
diff --git a/src/main/main.h b/src/main/main.h
index 2ba688a98..8277d366a 100644
--- a/src/main/main.h
+++ b/src/main/main.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file main.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Header for main CVC4 driver
**
diff --git a/src/main/portfolio.cpp b/src/main/portfolio.cpp
index 22f3a67ae..1e1b41bea 100644
--- a/src/main/portfolio.cpp
+++ b/src/main/portfolio.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file portfolio.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Provides (somewhat) generic functionality to simulate a
** (potentially cooperative) race
diff --git a/src/main/portfolio.h b/src/main/portfolio.h
index a7f15a04d..b96efda51 100644
--- a/src/main/portfolio.h
+++ b/src/main/portfolio.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file portfolio.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Provides (somewhat) generic functionality to simulate a
** (potentially cooperative) race
diff --git a/src/main/portfolio_util.cpp b/src/main/portfolio_util.cpp
index e42787fea..03827a917 100644
--- a/src/main/portfolio_util.cpp
+++ b/src/main/portfolio_util.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file portfolio_util.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Code relevant only for portfolio builds
**/
@@ -92,7 +92,7 @@ void parseThreadSpecificOptions(OptionsList& threadOptions, const Options& opts)
*vp++ = NULL;
if(targc > 1) { // this is necessary in case you do e.g. --thread0=" "
try {
- tOpts.parseOptions(targc, targv);
+ Options::parseOptions(&tOpts, targc, targv);
} catch(OptionException& e) {
stringstream ss;
ss << optid << ": " << e.getMessage();
diff --git a/src/main/portfolio_util.h b/src/main/portfolio_util.h
index 50cf0060a..32cc04540 100644
--- a/src/main/portfolio_util.h
+++ b/src/main/portfolio_util.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file portfolio_util.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Code relevant only for portfolio builds
**/
diff --git a/src/main/util.cpp b/src/main/util.cpp
index 71b46e67a..e14b508de 100644
--- a/src/main/util.cpp
+++ b/src/main/util.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file util.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Christopher L. Conway, Tim King, ACSYS
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Utilities for the main driver.
**
diff --git a/src/options/Makefile.am b/src/options/Makefile.am
index 8a465c522..643932781 100644
--- a/src/options/Makefile.am
+++ b/src/options/Makefile.am
@@ -206,7 +206,8 @@ liboptions_la_SOURCES = \
arith_propagation_mode.h \
arith_unate_lemma_mode.cpp \
arith_unate_lemma_mode.h \
- argument_extender.cpp \
+ argument_extender_implementation.cpp \
+ argument_extender_implementation.h \
argument_extender.h \
base_handlers.h \
boolean_term_conversion_mode.cpp \
diff --git a/src/options/argument_extender.cpp b/src/options/argument_extender.cpp
deleted file mode 100644
index d55610590..000000000
--- a/src/options/argument_extender.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/********************* */
-/*! \file preempt_get_option.h
- ** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Utility function for parsing commandline options.
- **
- ** Utility function for parsing commandline options.
- **/
-
-#include "options/argument_extender.h"
-
-#include <cstdlib>
-#include <cstring>
-#include <vector>
-
-#include "base/cvc4_assert.h"
-#include "base/output.h"
-
-namespace CVC4 {
-namespace options {
-
-ArgumentExtender::ArgumentExtender(unsigned additional, size_t length)
- : d_additional(additional)
- , d_length(length)
-{
- AlwaysAssert(d_additional >= 1);
- AlwaysAssert(d_length >= 1);
-}
-
-ArgumentExtender::~ArgumentExtender(){}
-
-unsigned ArgumentExtender::getIncrease() const { return d_additional; }
-size_t ArgumentExtender::getLength() const { return d_length; }
-
-void ArgumentExtender::extend(int& argc, char**& argv, const char* opt,
- std::vector<char*>& allocated)
-{
-
- Debug("preemptGetopt") << "preempting getopt() with " << opt << std::endl;
-
- AlwaysAssert(opt != NULL && *opt != '\0');
- AlwaysAssert(strlen(opt) <= getLength());
-
- ++argc;
- unsigned i = 1;
- while(argv[i] != NULL && argv[i][0] != '\0') {
- ++i;
- }
-
- if(argv[i] == NULL) {
- unsigned newSize = i + getIncrease();
- argv = (char**) realloc(argv, newSize * sizeof(char*));
- for(unsigned j = i; j < newSize-1; ++j) {
- char* newString = (char*) malloc(sizeof(char) * getLength());
- newString[0] = '\0';
- argv[j] = newString;
- allocated.push_back(newString);
- }
- argv[newSize - 1] = NULL;
- }
-
- strncpy(argv[i], opt, getLength() - 1);
- argv[i][getLength() - 1] = '\0'; // ensure NULL-termination even on overflow
-}
-
-}/* CVC4::options namespace */
-}/* CVC4 namespace */
diff --git a/src/options/argument_extender.h b/src/options/argument_extender.h
index 1f7e3c1dd..6be41fe8e 100644
--- a/src/options/argument_extender.h
+++ b/src/options/argument_extender.h
@@ -1,79 +1,85 @@
/********************* */
-/*! \file preempt_get_option.h
+/*! \file argument_extender.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
- ** \brief Utility function for extending commandline options.
+ ** \brief Abstract utility class for extending commandline options.
**
- ** Utility function for extending commandline options.
+ ** Abstract utility class for extending commandline options.
**/
-#include "cvc4_private.h"
+#include "cvc4_public.h"
-#ifndef __CVC4__OPTIONS__PREMPT_GET_OPTION_H
-#define __CVC4__OPTIONS__PREMPT_GET_OPTION_H
+#ifndef __CVC4__OPTIONS__ARGUMENT_EXTENDER_H
+#define __CVC4__OPTIONS__ARGUMENT_EXTENDER_H
#include <cstddef>
-#include <vector>
namespace CVC4 {
namespace options {
-
+/**
+ * Abstract utility class for implementing command line options
+ * parsing for the Options class. This allows for adding preemption
+ * arguments. A preemption is effectivly adding a new argument into
+ * the commandline arguments and must be processed immediately.
+ */
class ArgumentExtender {
- public:
+public:
+ ArgumentExtender(){}
+ virtual ~ArgumentExtender(){}
+
/**
+ * This creates a copy of the current arguments list as a new array.
+ * The new array is stored in argv. The user of this function is
+ * expected to own the memory of the string array, but not the
+ * strings themselves. The length of the new array is
+ * numArguments() and is stored in argc.
+ *
* Preconditions:
- * additional >= 1
- * length >= 1
+ * - argc and argv are non-null.
*/
- ArgumentExtender(unsigned additional, size_t length);
- ~ArgumentExtender();
+ virtual void getArguments(int* argc, char*** argv) const = 0;
+
+ /** Returns the number of arguments that are . */
+ virtual size_t numArguments() const = 0;
/**
- * This purpose of this function is to massage argc and argv upon the event
- * of parsing during Options::parseOptions of an option with the :link or
- * :link-alternative attributes. The purpose of the function is to extend argv
- * with another commandline argument.
- *
- * Preconditions:
- * opt is '\0' terminated, non-null and non-empty c-string.
- * strlen(opt) <= getLength()
- *
- * Let P be the first position in argv that is >= 1 and is either NULL or
- * empty:
- * argv[P] == NULL || argv[P] == '\0'
- *
- * This has a very specific set of side effects:
- * - argc is incremented by one.
- * - If argv[P] == NULL, this reallocates argv to have (P+additional)
- * elements.
- * - The 0 through P-1 elements of argv are the same.
- * - The P element of argv is a copy of the first len-1 characters of opt.
- * This is a newly allocated '\0' terminated c string of length len.
- * - The P+1 through (P+additional-2) elements of argv are newly allocated
- * empty '\0' terminated c strings of size len.
- * - The last element at (P+additional-1) of argv is NULL.
- * - All allocations are pushed back onto allocated.
+ * Inserts a copy of element into the front of the arguments list.
+ * Preconditions: element is non-null and 0 terminated.
+ */
+ virtual void pushFrontArgument(const char* element) = 0;
+
+ /**
+ * Inserts a copy of element into the back of the arguments list.
+ * Preconditions: element is non-null and 0 terminated.
+ */
+ virtual void pushBackArgument(const char* element) = 0;
+
+ /** Removes the front of the arguments list.*/
+ virtual void popFrontArgument() = 0;
+
+ /** Adds a new preemption to the arguments list. */
+ virtual void pushBackPreemption(const char* element) = 0;
+
+ /**
+ * Moves all of the preemptions into the front of the arguments
+ * list.
*/
- void extend(int& argc, char**& argv, const char* opt,
- std::vector<char*>& allocated);
+ virtual void movePreemptionsToArguments() = 0;
- unsigned getIncrease() const;
- size_t getLength() const;
+ /** Returns true iff there is a pending preemption.*/
+ virtual bool hasPreemptions() const = 0;
- private:
- unsigned d_additional;
- size_t d_length;
-};
+};/* class ArgumentExtender */
}/* CVC4::options namespace */
}/* CVC4 namespace */
-#endif /* __CVC4__OPTIONS__PREMPT_GET_OPTION_H */
+#endif /* __CVC4__OPTIONS__ARGUMENT_EXTENDER_H */
diff --git a/src/options/argument_extender_implementation.cpp b/src/options/argument_extender_implementation.cpp
new file mode 100644
index 000000000..0c23434c4
--- /dev/null
+++ b/src/options/argument_extender_implementation.cpp
@@ -0,0 +1,114 @@
+/********************* */
+/*! \file argument_extender_implementation.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Utility class for parsing commandline options.
+ **
+ ** Utility class for parsing commandline options.
+ **/
+
+#include "options/argument_extender_implementation.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <list>
+
+#include "base/cvc4_assert.h"
+#include "base/output.h"
+#include "options/argument_extender.h"
+
+namespace CVC4 {
+namespace options {
+
+ArgumentExtenderImplementation::ArgumentExtenderImplementation()
+ : d_allocated()
+ , d_preemptions()
+ , d_arguments()
+{
+}
+
+ArgumentExtenderImplementation::~ArgumentExtenderImplementation(){
+ for(CharPointerList::iterator i = d_allocated.begin(),
+ iend = d_allocated.end(); i != iend; ++i) {
+ char* current = *i;
+ Debug("options") << "~ArgumentExtenderImplementation " << current
+ << std::endl;
+ free(current);
+ }
+ d_allocated.clear();
+}
+
+size_t ArgumentExtenderImplementation::numArguments() const {
+ return d_arguments.size();
+}
+
+char* ArgumentExtenderImplementation::allocateCopy(const char* element) {
+ Assert(element != NULL);
+
+ char* duplicate = strdup(element);
+ Assert(duplicate != NULL);
+ d_allocated.push_back(duplicate);
+ return duplicate;
+}
+
+bool ArgumentExtenderImplementation::hasPreemptions() const {
+ return !d_preemptions.empty();
+}
+
+void ArgumentExtenderImplementation::pushBackPreemption(const char* element) {
+ d_preemptions.push_back(allocateCopy(element));
+}
+
+void ArgumentExtenderImplementation::movePreemptionsToArguments() {
+ d_arguments.splice(d_arguments.begin(), d_preemptions);
+}
+
+void ArgumentExtenderImplementation::popFrontArgument() {
+ Assert(!d_arguments.empty());
+ Debug("options") << "ArgumentExtenderImplementation::popFrontArgument "
+ << d_arguments.front() << std::endl;
+ d_arguments.pop_front();
+}
+
+void ArgumentExtenderImplementation::pushFrontArgument(const char* element) {
+ d_arguments.push_front(allocateCopy(element));
+}
+
+void ArgumentExtenderImplementation::pushBackArgument(const char* element) {
+ d_arguments.push_back(allocateCopy(element));
+}
+
+void ArgumentExtenderImplementation::getArguments(int* argc, char*** argv)
+ const {
+ Assert(argc != NULL);
+ Assert(argv != NULL);
+
+ *argc = numArguments();
+ *argv = copyArguments();
+}
+
+char** ArgumentExtenderImplementation::copyArguments() const {
+ int size = numArguments();
+ Assert(size >= 0);
+
+ char** array = (char**) malloc( sizeof(char*) * size );
+ Assert(array != NULL);
+ int position = 0;
+ for(std::list< char* >::const_iterator i = d_arguments.begin(),
+ iend = d_arguments.end(); i != iend; ++i, ++position) {
+ char* at_position = *i;
+ array[position] = at_position;
+ }
+
+ return array;
+}
+
+}/* CVC4::options namespace */
+}/* CVC4 namespace */
diff --git a/src/options/argument_extender_implementation.h b/src/options/argument_extender_implementation.h
new file mode 100644
index 000000000..e948132d7
--- /dev/null
+++ b/src/options/argument_extender_implementation.h
@@ -0,0 +1,115 @@
+/********************* */
+/*! \file argument_extender_implementation.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Utility class for extending commandline options.
+ **
+ ** Utility class for extending commandline options.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__OPTIONS__ARGUMENT_EXTENDER_IMPLEMENTATION_H
+#define __CVC4__OPTIONS__ARGUMENT_EXTENDER_IMPLEMENTATION_H
+
+#include <cstddef>
+#include <list>
+
+#include "options/argument_extender.h"
+
+namespace CVC4 {
+namespace options {
+
+/**
+ * Utility class for implementing command line options parsing for the
+ * Options class. This allows for adding preemption arguments.
+ * Preemptions are processed immediately after the current argument.
+ */
+class ArgumentExtenderImplementation : public ArgumentExtender {
+ public:
+ /** Constructs a new empty ArgumentExtender.*/
+ ArgumentExtenderImplementation();
+
+ /** Destroys an ArgumentExtender and frees its associated memory.*/
+ ~ArgumentExtenderImplementation();
+
+ /**
+ * This creates a copy of the current arguments list as a new array.
+ * The new array is stored in argv. The user of this function is
+ * expected to own the memory of the string array, but not the
+ * strings themselves. The length of the new array is
+ * numArguments() and is stored in argc.
+ *
+ * Preconditions:
+ * - argc and argv are non-null.
+ */
+ void getArguments(int* argc, char*** argv) const;
+
+ /** Returns the number of arguments that are . */
+ size_t numArguments() const;
+
+ /**
+ * Inserts a copy of element into the front of the arguments list.
+ * Preconditions: element is non-null and 0 terminated.
+ */
+ void pushFrontArgument(const char* element);
+
+ /**
+ * Inserts a copy of element into the back of the arguments list.
+ * Preconditions: element is non-null and 0 terminated.
+ */
+ void pushBackArgument(const char* element);
+
+ /** Removes the front of the arguments list.*/
+ void popFrontArgument();
+
+ /** Adds a new preemption to the arguments list. */
+ void pushBackPreemption(const char* element);
+
+ /**
+ * Moves all of the preemptions into the front of the arguments
+ * list.
+ */
+ void movePreemptionsToArguments();
+
+ /** Returns true iff there is a pending preemption.*/
+ bool hasPreemptions() const;
+
+private:
+
+ typedef std::list< char* > CharPointerList;
+
+ /** Creates of copy of the arugments list.*/
+ char** copyArguments() const;
+
+ /** Allocates a copy and stores a copy in d_allocated.*/
+ char* allocateCopy(const char* element);
+
+ /** Contains a copy of the allocated strings.*/
+ CharPointerList d_allocated;
+
+ /**
+ * A list of all of the preempted arguments. All of these pointers
+ * in this list should be contained in d_allocated.
+ */
+ CharPointerList d_preemptions;
+
+ /**
+ * A list of all of the arguments. All of these pointers in this
+ * list should be contained in d_allocated.
+ */
+ CharPointerList d_arguments;
+
+};/* class ArgumentExtenderImplementation */
+
+}/* CVC4::options namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__OPTIONS__ARGUMENT_EXTENDER_IMPLEMENTATION_H */
diff --git a/src/options/arith_heuristic_pivot_rule.cpp b/src/options/arith_heuristic_pivot_rule.cpp
index ff5f2102a..15c340aa8 100644
--- a/src/options/arith_heuristic_pivot_rule.cpp
+++ b/src/options/arith_heuristic_pivot_rule.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_heuristic_pivot_rule.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/arith_heuristic_pivot_rule.h b/src/options/arith_heuristic_pivot_rule.h
index e44b8105b..9048cb92e 100644
--- a/src/options/arith_heuristic_pivot_rule.h
+++ b/src/options/arith_heuristic_pivot_rule.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_heuristic_pivot_rule.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/arith_options b/src/options/arith_options
index 9f4003004..f38e377ba 100644
--- a/src/options/arith_options
+++ b/src/options/arith_options
@@ -162,4 +162,7 @@ option pbRewrites --pb-rewrites bool :default false
option pbRewriteThreshold --pb-rewrite-threshold int :default 256
threshold of number of pseudoboolean variables to have before doing rewrites
+option sNormInferEq --snorm-infer-eq bool :default false
+ infer equalities based on Shostak normalization
+
endmodule
diff --git a/src/options/arith_propagation_mode.cpp b/src/options/arith_propagation_mode.cpp
index 7f18a0356..5baf0b832 100644
--- a/src/options/arith_propagation_mode.cpp
+++ b/src/options/arith_propagation_mode.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_propagation_mode.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/arith_propagation_mode.h b/src/options/arith_propagation_mode.h
index fa89496f0..dc4b80372 100644
--- a/src/options/arith_propagation_mode.h
+++ b/src/options/arith_propagation_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_propagation_mode.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/arith_unate_lemma_mode.cpp b/src/options/arith_unate_lemma_mode.cpp
index 55fd8a01f..9b683f4c1 100644
--- a/src/options/arith_unate_lemma_mode.cpp
+++ b/src/options/arith_unate_lemma_mode.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_unate_lemma_mode.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/arith_unate_lemma_mode.h b/src/options/arith_unate_lemma_mode.h
index 5e1362bcb..39664d3aa 100644
--- a/src/options/arith_unate_lemma_mode.h
+++ b/src/options/arith_unate_lemma_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_unate_lemma_mode.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/base_handlers.h b/src/options/base_handlers.h
index d4137255e..0345f9e10 100644
--- a/src/options/base_handlers.h
+++ b/src/options/base_handlers.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file base_handlers.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/base_options_template.cpp b/src/options/base_options_template.cpp
index 2c3d717fa..bdcef6029 100644
--- a/src/options/base_options_template.cpp
+++ b/src/options/base_options_template.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file base_options_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Contains code for handling command-line options.
**
diff --git a/src/options/base_options_template.h b/src/options/base_options_template.h
index c8c02ecaa..486b793d0 100644
--- a/src/options/base_options_template.h
+++ b/src/options/base_options_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file base_options_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Contains code for handling command-line options.
**
diff --git a/src/options/boolean_term_conversion_mode.cpp b/src/options/boolean_term_conversion_mode.cpp
index d1466ae14..0673718bb 100644
--- a/src/options/boolean_term_conversion_mode.cpp
+++ b/src/options/boolean_term_conversion_mode.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file boolean_term_conversion_mode.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/boolean_term_conversion_mode.h b/src/options/boolean_term_conversion_mode.h
index 81a0c661a..f2f4a51af 100644
--- a/src/options/boolean_term_conversion_mode.h
+++ b/src/options/boolean_term_conversion_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file boolean_term_conversion_mode.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/bv_bitblast_mode.cpp b/src/options/bv_bitblast_mode.cpp
index 99ceb41ee..9cf47fe33 100644
--- a/src/options/bv_bitblast_mode.cpp
+++ b/src/options/bv_bitblast_mode.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file bitblast_mode.cpp
+/*! \file bv_bitblast_mode.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitblast modes for bit-vector solver.
**
diff --git a/src/options/bv_bitblast_mode.h b/src/options/bv_bitblast_mode.h
index f36021478..4c8c4f626 100644
--- a/src/options/bv_bitblast_mode.h
+++ b/src/options/bv_bitblast_mode.h
@@ -1,13 +1,13 @@
/********************* */
-/*! \file bitblast_mode.h
+/*! \file bv_bitblast_mode.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitblasting modes for bit-vector solver.
**
diff --git a/src/options/bv_options b/src/options/bv_options
index c1180dba3..8edc809e3 100644
--- a/src/options/bv_options
+++ b/src/options/bv_options
@@ -11,14 +11,14 @@ option bitblastMode bitblast --bitblast=MODE CVC4::theory::bv::BitblastMode :han
choose bitblasting mode, see --bitblast=help
# Options for eager bit-blasting
-
+
option bitvectorAig --bitblast-aig bool :default false :predicate abcEnabledBuild setBitblastAig :read-write
bitblast by first converting to AIG (implies --bitblast=eager)
expert-option bitvectorAigSimplifications --bv-aig-simp=COMMAND std::string :default "" :predicate abcEnabledBuild :read-write :link --bitblast-aig :link-smt bitblast-aig
abc command to run AIG simplifications (implies --bitblast-aig, default is "balance;drw")
# Options for lazy bit-blasting
-option bitvectorPropagate --bv-propagate bool :default true :read-write
+option bitvectorPropagate --bv-propagate bool :default true :read-write
use bit-vector propagation in the bit-blaster
option bitvectorEqualitySolver --bv-eq-solver bool :default true :read-write
@@ -28,18 +28,18 @@ option bitvectorEqualitySlicer --bv-eq-slicer=MODE CVC4::theory::bv::BvSlicerMod
turn on the slicing equality solver for the bit-vector theory (only if --bitblast=lazy)
-option bitvectorInequalitySolver --bv-inequality-solver bool :default true :read-write
+option bitvectorInequalitySolver --bv-inequality-solver bool :default true :read-write
turn on the inequality solver for the bit-vector theory (only if --bitblast=lazy)
option bitvectorAlgebraicSolver --bv-algebraic-solver bool :default true :read-write
turn on the algebraic solver for the bit-vector theory (only if --bitblast=lazy)
-
+
expert-option bitvectorAlgebraicBudget --bv-algebraic-budget unsigned :default 1500 :read-write :link --bv-algebraic-solver :link-smt bv-algebraic-solver
the budget allowed for the algebraic solver in number of SAT conflicts
# General options
-option bitvectorToBool --bv-to-bool bool :default false :read-write
+option bitvectorToBool --bv-to-bool bool :default false :read-write
lift bit-vectors of size 1 to booleans when possible
option bitvectorDivByZeroConst --bv-div-zero-const bool :default false :read-write
@@ -47,11 +47,11 @@ option bitvectorDivByZeroConst --bv-div-zero-const bool :default false :read-wri
expert-option bvExtractArithRewrite --bv-extract-arith bool :default false :read-write
enable rewrite pushing extract [i:0] over arithmetic operations (can blow up)
-
+
expert-option bvAbstraction --bv-abstraction bool :default false :read-write
- mcm benchmark abstraction
+ mcm benchmark abstraction
-expert-option skolemizeArguments --bv-skolemize bool :default false :read-write
+expert-option skolemizeArguments --bv-skolemize bool :default false :read-write
skolemize arguments for bv abstraction (only does something if --bv-abstraction is on)
expert-option bvNumFunc --bv-num-func=NUM unsigned :default 1
@@ -62,8 +62,8 @@ expert-option bvEagerExplanations --bv-eager-explanations bool :default false :r
expert-option bitvectorQuickXplain --bv-quick-xplain bool :default false
minimize bv conflicts using the QuickXplain algorithm
-
+
expert-option bvIntroducePow2 --bv-intro-pow2 bool :default false
introduce bitvector powers of two as a preprocessing pass
-
+
endmodule
diff --git a/src/options/datatypes_options b/src/options/datatypes_options
index b44a36e2a..e9578f8d7 100644
--- a/src/options/datatypes_options
+++ b/src/options/datatypes_options
@@ -23,5 +23,9 @@ option cdtBisimilar --cdt-bisimilar bool :default true
do bisimilarity check for co-datatypes
option dtCyclic --dt-cyclic bool :default true
do cyclicity check for datatypes
+option dtInferAsLemmas --dt-infer-as-lemmas bool :default false
+ always send lemmas out instead of making internal inferences
+#option dtRExplainLemmas --dt-rexplain-lemmas bool :default true
+# regression explanations for datatype lemmas
endmodule
diff --git a/src/options/decision_mode.cpp b/src/options/decision_mode.cpp
index 0aeae1baa..3a93b0274 100644
--- a/src/options/decision_mode.cpp
+++ b/src/options/decision_mode.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_mode.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/decision_mode.h b/src/options/decision_mode.h
index 420d00b4c..efc6ca213 100644
--- a/src/options/decision_mode.h
+++ b/src/options/decision_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_mode.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Kshitij Bansal
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/decision_weight.h b/src/options/decision_weight.h
index 89ebe8a21..6d01b18cb 100644
--- a/src/options/decision_weight.h
+++ b/src/options/decision_weight.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file decision_weight.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter attributes
**
diff --git a/src/options/didyoumean.cpp b/src/options/didyoumean.cpp
index 1066c7a1f..d874c7bc7 100644
--- a/src/options/didyoumean.cpp
+++ b/src/options/didyoumean.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file didyoumean.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief did-you-mean style suggestions
**
diff --git a/src/options/didyoumean.h b/src/options/didyoumean.h
index 2615f4d0a..71a12e6fc 100644
--- a/src/options/didyoumean.h
+++ b/src/options/didyoumean.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file didyoumean.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief did-you-mean style suggestions.
**
diff --git a/src/options/didyoumean_test.cpp b/src/options/didyoumean_test.cpp
index af3daa689..8117b57ac 100644
--- a/src/options/didyoumean_test.cpp
+++ b/src/options/didyoumean_test.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file didyoumean_test.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/language.cpp b/src/options/language.cpp
index 7558c6927..665089e45 100644
--- a/src/options/language.cpp
+++ b/src/options/language.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file language.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definition of input and output languages
**
diff --git a/src/options/language.h b/src/options/language.h
index 9191a1d59..00328e4ab 100644
--- a/src/options/language.h
+++ b/src/options/language.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file language.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Francois Bobot, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definition of input and output languages
**
diff --git a/src/options/main_options b/src/options/main_options
index 7ec4fedb3..0fa799df2 100644
--- a/src/options/main_options
+++ b/src/options/main_options
@@ -54,8 +54,8 @@ option segvSpin --segv-spin bool :default false
spin on segfault/other crash waiting for gdb
undocumented-alias --segv-nospin = --no-segv-spin
-expert-option tearDownIncremental : --tear-down-incremental int :default 0
- implement PUSH/POP/multi-query by destroying and recreating SmtEngine
+expert-option tearDownIncremental : --tear-down-incremental=N int :default 0
+ implement PUSH/POP/multi-query by destroying and recreating SmtEngine every N queries
expert-option waitToJoin --wait-to-join bool :default true
wait for other threads to join before quitting
diff --git a/src/options/mkoptions b/src/options/mkoptions
index ad8d7033f..dd5575644 100755
--- a/src/options/mkoptions
+++ b/src/options/mkoptions
@@ -604,7 +604,7 @@ template <> bool Options::wasSetByUser(options::${internal}__option_t) const { r
for link in $links; do
run_links="$run_links
#line $lineno \"$kf\"
- argumentExtender.extend(extra_argc, extra_argv, \"$link\", allocated);"
+ extender->pushBackPreemption(\"$link\");"
done
fi
if [ -n "$smt_links" ]; then
@@ -623,7 +623,7 @@ template <> bool Options::wasSetByUser(options::${internal}__option_t) const { r
for link in $links_alternate; do
run_links_alternate="$run_links_alternate
#line $lineno \"$kf\"
- argumentExtender.extend(extra_argc, extra_argv, \"$link\", allocated);"
+ extender->pushBackPreemption(\"$link\");"
done
fi
if [ -n "$notifications" ]; then
@@ -657,7 +657,7 @@ template <> void runBoolPredicates(options::${internal}__option_t, std::string o
if [ "$type" = bool ]; then
all_modules_option_handlers="${all_modules_option_handlers}${cases}
#line $lineno \"$kf\"
- assignBool(options::$internal, option, true);$run_links
+ options->assignBool(options::$internal, option, true);$run_links
break;
"
elif [ -n "$expect_arg" -a "$internal" != - ]; then
@@ -690,7 +690,7 @@ template <> options::${internal}__option_t::type runHandlerAndPredicates(options
}"
all_modules_option_handlers="${all_modules_option_handlers}${cases}
#line $lineno \"$kf\"
- assign(options::$internal, option, optionarg);$run_links
+ options->assign(options::$internal, option, optionarg);$run_links
break;
"
elif [ -n "$expect_arg" ]; then
@@ -733,7 +733,7 @@ template <> options::${internal}__option_t::type runHandlerAndPredicates(options
if [ "$type" = bool ]; then
all_modules_option_handlers="${all_modules_option_handlers}${cases_alternate}
#line $lineno \"$kf\"
- assignBool(options::$internal, option, false);$run_links_alternate
+ options->assignBool(options::$internal, option, false);$run_links_alternate
break;
"
else
@@ -1013,12 +1013,12 @@ function handle_alias {
fi
links="$links
#line $lineno \"$kf\"
- argumentExtender.extend(extra_argc, extra_argv, \"$linkopt\", allocated);"
+ extender->pushBackPreemption(\"$linkopt\");"
if [ "$linkarg" ]; then
# include also the arg
links="$links
#line $lineno \"$kf\"
- argumentExtender.extend(extra_argc, extra_argv, optionarg.c_str(), allocated);"
+ extender->pushBackPreemption(optionarg.c_str());"
fi
shift
done
diff --git a/src/options/open_ostream.cpp b/src/options/open_ostream.cpp
index 4c92d056b..214f148aa 100644
--- a/src/options/open_ostream.cpp
+++ b/src/options/open_ostream.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file open_ostream.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/open_ostream.h b/src/options/open_ostream.h
index ab83427a9..6c00e7dd1 100644
--- a/src/options/open_ostream.h
+++ b/src/options/open_ostream.h
@@ -1,13 +1,13 @@
/********************* */
-/*! \file open_stream.h
+/*! \file open_ostream.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/option_exception.h b/src/options/option_exception.h
index c57414026..450eda988 100644
--- a/src/options/option_exception.h
+++ b/src/options/option_exception.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file option_exception.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Options-related exceptions
**
diff --git a/src/options/options.h b/src/options/options.h
index 8fb52146f..33bd94e46 100644
--- a/src/options/options.h
+++ b/src/options/options.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file options.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Global (command-line, set-option, ...) parameters for SMT.
**
@@ -27,6 +27,7 @@
#include "base/listener.h"
#include "base/modal_exception.h"
#include "base/tls.h"
+#include "options/argument_extender.h"
#include "options/language.h"
#include "options/printer_modes.h"
#include "options/option_exception.h"
@@ -314,12 +315,18 @@ public:
static std::vector<std::string> suggestSmtOptions(const std::string& optionName) throw();
/**
- * Initialize the options based on the given command-line arguments.
- * The return value is what's left of the command line (that is, the
- * non-option arguments).
+ * Initialize the Options object options based on the given
+ * command-line arguments given in argc and argv. The return value
+ * is what's left of the command line (that is, the non-option
+ * arguments).
+ *
+ * This function uses getopt_long() and is not thread safe.
+ *
+ * Preconditions: options and argv must be non-null.
*/
- std::vector<std::string> parseOptions(int argc, char* argv[])
- throw(OptionException);
+ static std::vector<std::string> parseOptions(Options* options,
+ int argc, char* argv[])
+ throw(OptionException);
/**
* Get the setting for all options.
@@ -528,6 +535,22 @@ public:
/** Sends a std::flush to getOut(). */
void flushOut();
+ private:
+
+ /**
+ * Internal procedure for implementing the parseOptions function.
+ * Initializes the options object based on the given command-line
+ * arguments. This uses an ArgumentExtender containing the
+ * command-line arguments. Nonoptions are stored into nonoptions.
+ *
+ * This is not thread safe.
+ *
+ * Preconditions: options, extender and nonoptions are non-null.
+ */
+ static void parseOptionsRecursive(Options* options,
+ options::ArgumentExtender* extender,
+ std::vector<std::string>* nonoptions)
+ throw(OptionException);
};/* class Options */
}/* CVC4 namespace */
diff --git a/src/options/options_get_option_template.cpp b/src/options/options_get_option_template.cpp
index b7e5433ee..d50644a5d 100644
--- a/src/options/options_get_option_template.cpp
+++ b/src/options/options_get_option_template.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file option_handler_get_option_template.cpp
+/*! \file options_get_option_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of OptionsHandler::getOption.
**
diff --git a/src/options/options_handler.cpp b/src/options/options_handler.cpp
index 1c48f4bb1..a2809bd67 100644
--- a/src/options/options_handler.cpp
+++ b/src/options/options_handler.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file options_handler.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interface for custom handlers and predicates options.
**
@@ -347,15 +347,21 @@ interleave \n\
const std::string OptionsHandler::s_triggerSelModeHelp = "\
Trigger selection modes currently supported by the --trigger-sel option:\n\
\n\
-default \n\
-+ Default, consider all subterms of quantified formulas for trigger selection.\n\
-\n\
-min \n\
+min | default \n\
+ Consider only minimal subterms that meet criteria for triggers.\n\
\n\
max \n\
+ Consider only maximal subterms that meet criteria for triggers. \n\
\n\
+all \n\
++ Consider all subterms that meet criteria for triggers. \n\
+\n\
+min-s-max \n\
++ Consider only minimal subterms that meet criteria for single triggers, maximal otherwise. \n\
+\n\
+min-s-all \n\
++ Consider only minimal subterms that meet criteria for single triggers, all otherwise. \n\
+\n\
";
const std::string OptionsHandler::s_prenexQuantModeHelp = "\
Prenex quantifiers modes currently supported by the --prenex-quant option:\n\
@@ -428,7 +434,7 @@ post \n\
";
const std::string OptionsHandler::s_macrosQuantHelp = "\
-Template modes for quantifiers macro expansion, supported by --macros-quant-mode:\n\
+Modes for quantifiers macro expansion, supported by --macros-quant-mode:\n\
\n\
all \n\
+ Infer definitions for functions, including those containing quantified formulas.\n\
@@ -441,6 +447,34 @@ ground-uf \n\
\n\
";
+const std::string OptionsHandler::s_quantDSplitHelp = "\
+Modes for quantifiers splitting, supported by --quant-dsplit-mode:\n\
+\n\
+none \n\
++ Never split quantified formulas.\n\
+\n\
+default \n\
++ Split quantified formulas over some finite datatypes when finite model finding is enabled.\n\
+\n\
+agg \n\
++ Aggressively split quantified formulas.\n\
+\n\
+";
+
+const std::string OptionsHandler::s_quantRepHelp = "\
+Modes for quantifiers representative selection, supported by --quant-rep-mode:\n\
+\n\
+ee \n\
++ Let equality engine choose representatives.\n\
+\n\
+first (default) \n\
++ Choose terms that appear first.\n\
+\n\
+depth \n\
++ Choose terms that are of minimal depth.\n\
+\n\
+";
+
theory::quantifiers::InstWhenMode OptionsHandler::stringToInstWhenMode(std::string option, std::string optarg) throw(OptionException) {
if(optarg == "pre-full") {
return theory::quantifiers::INST_WHEN_PRE_FULL;
@@ -542,8 +576,6 @@ theory::quantifiers::QcfMode OptionsHandler::stringToQcfMode(std::string option,
return theory::quantifiers::QCF_PROP_EQ;
} else if(optarg == "partial") {
return theory::quantifiers::QCF_PARTIAL;
- } else if(optarg == "mc" ) {
- return theory::quantifiers::QCF_MC;
} else if(optarg == "help") {
puts(s_qcfModeHelp.c_str());
exit(1);
@@ -574,12 +606,18 @@ theory::quantifiers::UserPatMode OptionsHandler::stringToUserPatMode(std::string
}
theory::quantifiers::TriggerSelMode OptionsHandler::stringToTriggerSelMode(std::string option, std::string optarg) throw(OptionException) {
- if(optarg == "default" || optarg == "all" ) {
+ if(optarg == "default") {
return theory::quantifiers::TRIGGER_SEL_DEFAULT;
} else if(optarg == "min") {
return theory::quantifiers::TRIGGER_SEL_MIN;
} else if(optarg == "max") {
return theory::quantifiers::TRIGGER_SEL_MAX;
+ } else if(optarg == "min-s-max") {
+ return theory::quantifiers::TRIGGER_SEL_MIN_SINGLE_MAX;
+ } else if(optarg == "min-s-all") {
+ return theory::quantifiers::TRIGGER_SEL_MIN_SINGLE_ALL;
+ } else if(optarg == "all") {
+ return theory::quantifiers::TRIGGER_SEL_ALL;
} else if(optarg == "help") {
puts(s_triggerSelModeHelp.c_str());
exit(1);
@@ -686,6 +724,37 @@ theory::quantifiers::MacrosQuantMode OptionsHandler::stringToMacrosQuantMode(std
}
}
+theory::quantifiers::QuantDSplitMode OptionsHandler::stringToQuantDSplitMode(std::string option, std::string optarg) throw(OptionException) {
+ if(optarg == "none" ) {
+ return theory::quantifiers::QUANT_DSPLIT_MODE_NONE;
+ } else if(optarg == "default") {
+ return theory::quantifiers::QUANT_DSPLIT_MODE_DEFAULT;
+ } else if(optarg == "agg") {
+ return theory::quantifiers::QUANT_DSPLIT_MODE_AGG;
+ } else if(optarg == "help") {
+ puts(s_quantDSplitHelp.c_str());
+ exit(1);
+ } else {
+ throw OptionException(std::string("unknown option for --quant-dsplit-mode: `") +
+ optarg + "'. Try --quant-dsplit-mode help.");
+ }
+}
+
+theory::quantifiers::QuantRepMode OptionsHandler::stringToQuantRepMode(std::string option, std::string optarg) throw(OptionException) {
+ if(optarg == "none" ) {
+ return theory::quantifiers::QUANT_REP_MODE_EE;
+ } else if(optarg == "first" || optarg == "default") {
+ return theory::quantifiers::QUANT_REP_MODE_FIRST;
+ } else if(optarg == "depth") {
+ return theory::quantifiers::QUANT_REP_MODE_DEPTH;
+ } else if(optarg == "help") {
+ puts(s_quantRepHelp.c_str());
+ exit(1);
+ } else {
+ throw OptionException(std::string("unknown option for --quant-rep-mode: `") +
+ optarg + "'. Try --quant-rep-mode help.");
+ }
+}
// theory/bv/options_handlers.h
void OptionsHandler::abcEnabledBuild(std::string option, bool value) throw(OptionException) {
diff --git a/src/options/options_handler.h b/src/options/options_handler.h
index 9aa037004..baa6cea96 100644
--- a/src/options/options_handler.h
+++ b/src/options/options_handler.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file options_handler.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interface for custom handlers and predicates options.
**
@@ -100,6 +100,8 @@ public:
theory::quantifiers::IteLiftQuantMode stringToIteLiftQuantMode(std::string option, std::string optarg) throw(OptionException);
theory::quantifiers::SygusInvTemplMode stringToSygusInvTemplMode(std::string option, std::string optarg) throw(OptionException);
theory::quantifiers::MacrosQuantMode stringToMacrosQuantMode(std::string option, std::string optarg) throw(OptionException);
+ theory::quantifiers::QuantDSplitMode stringToQuantDSplitMode(std::string option, std::string optarg) throw(OptionException);
+ theory::quantifiers::QuantRepMode stringToQuantRepMode(std::string option, std::string optarg) throw(OptionException);
// theory/bv/options_handlers.h
void abcEnabledBuild(std::string option, bool value) throw(OptionException);
@@ -199,6 +201,8 @@ public:
static const std::string s_iteLiftQuantHelp;
static const std::string s_literalMatchHelp;
static const std::string s_macrosQuantHelp;
+ static const std::string s_quantDSplitHelp;
+ static const std::string s_quantRepHelp;
static const std::string s_mbqiModeHelp;
static const std::string s_modelFormatHelp;
static const std::string s_prenexQuantModeHelp;
diff --git a/src/options/options_holder_template.h b/src/options/options_holder_template.h
index f033fd5ad..f33656eb1 100644
--- a/src/options/options_holder_template.h
+++ b/src/options/options_holder_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file options_holder_template.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Global (command-line, set-option, ...) parameters for SMT
**
diff --git a/src/options/options_public_functions.cpp b/src/options/options_public_functions.cpp
index 2e86c732e..8f3a63175 100644
--- a/src/options/options_public_functions.cpp
+++ b/src/options/options_public_functions.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file options_public_functions.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definitions of public facing interface functions for Options.
**
@@ -204,7 +204,7 @@ std::ostream* Options::getOut(){
}
std::ostream* Options::getOutConst() const{
-#warning "Remove Options::getOutConst"
+ // #warning "Remove Options::getOutConst"
return (*this)[options::out];
}
diff --git a/src/options/options_set_option_template.cpp b/src/options/options_set_option_template.cpp
index 04f3800f7..cc068f4e6 100644
--- a/src/options/options_set_option_template.cpp
+++ b/src/options/options_set_option_template.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file option_handler_set_option_template.cpp
+/*! \file options_set_option_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of OptionsHandler::setOption.
**
diff --git a/src/options/options_template.cpp b/src/options/options_template.cpp
index 51b2bea5e..f029dfd17 100644
--- a/src/options/options_template.cpp
+++ b/src/options/options_template.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file options_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Contains code for handling command-line options.
**
@@ -53,13 +53,14 @@ extern int optreset;
#include "base/output.h"
#include "base/tls.h"
#include "options/argument_extender.h"
+#include "options/argument_extender_implementation.h"
#include "options/didyoumean.h"
#include "options/language.h"
#include "options/options_handler.h"
${include_all_option_headers}
-#line 63 "${template}"
+#line 64 "${template}"
#include "options/options_holder.h"
#include "cvc4autoconfig.h"
@@ -67,7 +68,7 @@ ${include_all_option_headers}
${option_handler_includes}
-#line 71 "${template}"
+#line 72 "${template}"
using namespace CVC4;
using namespace CVC4::options;
@@ -389,7 +390,7 @@ Options::registerSetReplayLogFilename(
${all_custom_handlers}
-#line 393 "${template}"
+#line 394 "${template}"
#ifdef CVC4_DEBUG
# define USE_EARLY_TYPE_CHECKING_BY_DEFAULT true
@@ -407,18 +408,18 @@ options::OptionsHolder::OptionsHolder() : ${all_modules_defaults}
{
}
-#line 411 "${template}"
+#line 412 "${template}"
static const std::string mostCommonOptionsDescription = "\
Most commonly-used CVC4 options:${common_documentation}";
-#line 416 "${template}"
+#line 417 "${template}"
static const std::string optionsDescription = mostCommonOptionsDescription + "\n\
\n\
Additional CVC4 options:${remaining_documentation}";
-#line 422 "${template}"
+#line 423 "${template}"
static const std::string optionsFootnote = "\n\
[*] Each of these options has a --no-OPTIONNAME variant, which reverses the\n\
@@ -431,7 +432,7 @@ Languages currently supported as arguments to the -L / --lang option:\n\
cvc4 | presentation | pl CVC4 presentation language\n\
smt1 | smtlib1 SMT-LIB format 1.2\n\
smt | smtlib | smt2 |\n\
- smt2.0 | smtlib2 | smtlib2.0 SMT-LIB format 2.0\n\
+ smt2.0 | smtlib2 | smtlib2.0 SMT-LIB format 2.0\n\
smt2.5 | smtlib2.5 SMT-LIB format 2.5\n\
tptp TPTP format (cnf and fof)\n\
sygus SyGuS format\n\
@@ -442,7 +443,7 @@ Languages currently supported as arguments to the --output-lang option:\n\
cvc3 CVC3 presentation language\n\
smt1 | smtlib1 SMT-LIB format 1.2\n\
smt | smtlib | smt2 |\n\
- smt2.0 | smtlib2.0 | smtlib2 SMT-LIB format 2.0\n\
+ smt2.0 | smtlib2.0 | smtlib2 SMT-LIB format 2.0\n\
smt2.5 | smtlib2.5 SMT-LIB format 2.5\n\
tptp TPTP format\n\
z3str SMT-LIB 2.0 with Z3-str string constraints\n\
@@ -497,7 +498,7 @@ static struct option cmdlineOptions[] = {${all_modules_long_options}
{ NULL, no_argument, NULL, '\0' }
};/* cmdlineOptions */
-#line 501 "${template}"
+#line 502 "${template}"
// static void preemptGetopt(int& argc, char**& argv, const char* opt) {
@@ -549,178 +550,196 @@ public:
* The return value is what's left of the command line (that is, the
* non-option arguments).
*/
-std::vector<std::string> Options::parseOptions(int argc, char* main_argv[]) throw(OptionException) {
- options::OptionsGuard guard(&s_current, this);
+std::vector<std::string> Options::parseOptions(Options* options,
+ int argc, char* argv[])
+ throw(OptionException) {
- // Having this synonym simplifies the generation code in mkoptions.
- options::OptionsHandler* handler = d_handler;
+ Assert(options != NULL);
+ Assert(argv != NULL);
- const char *progName = main_argv[0];
+ options::OptionsGuard guard(&s_current, options);
- ArgumentExtender argumentExtender(s_preemptAdditional, s_maxoptlen);
- std::vector<char*> allocated;
+ const char *progName = argv[0];
- Debug("options") << "main_argv == " << main_argv << std::endl;
+ // To debug options parsing, you may prefer to simply uncomment this
+ // and recompile. Debug flags have not been parsed yet so these have
+ // not been set.
+ //DebugChannel.on("options");
- // Reset getopt(), in the case of multiple calls to parseOptions().
- // This can be = 1 in newer GNU getopt, but older (< 2007) require = 0.
- optind = 0;
-#if HAVE_DECL_OPTRESET
- optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
-#endif /* HAVE_DECL_OPTRESET */
+ Debug("options") << "Options::parseOptions == " << options << std::endl;
+ Debug("options") << "argv == " << argv << std::endl;
- // find the base name of the program
+ // Find the base name of the program.
const char *x = strrchr(progName, '/');
if(x != NULL) {
progName = x + 1;
}
- d_holder->binary_name = std::string(progName);
+ options->d_holder->binary_name = std::string(progName);
+
+ ArgumentExtender* argumentExtender = new ArgumentExtenderImplementation();
+ for(int position = 1; position < argc; position++) {
+ argumentExtender->pushBackArgument(argv[position]);
+ }
+
+ std::vector<std::string> nonoptions;
+ parseOptionsRecursive(options, argumentExtender, &nonoptions);
+ if(Debug.isOn("options")){
+ for(std::vector<std::string>::const_iterator i = nonoptions.begin(),
+ iend = nonoptions.end(); i != iend; ++i){
+ Debug("options") << "nonoptions " << *i << std::endl;
+ }
+ }
+
+ delete argumentExtender;
+ return nonoptions;
+}
+
+void Options::parseOptionsRecursive(Options* options,
+ ArgumentExtender* extender,
+ std::vector<std::string>* nonoptions)
+ throw(OptionException) {
+
+ int argc;
+ char** argv;
+
+ extender->movePreemptionsToArguments();
+ extender->pushFrontArgument("");
+ extender->getArguments(&argc, &argv);
+
+ if(Debug.isOn("options")) {
+ Debug("options") << "starting a new parseOptionsRecursive with "
+ << argc << " arguments" << std::endl;
+ for( int i = 0; i < argc ; i++ ){
+ Assert(argv[i] != NULL);
+ Debug("options") << " argv[" << i << "] = " << argv[i] << std::endl;
+ }
+ }
- int extra_argc = 1;
- char **extra_argv = (char**) malloc(2 * sizeof(char*));
- extra_argv[0] = NULL;
- extra_argv[1] = NULL;
+ // Having this synonym simplifies the generation code in mkoptions.
+ options::OptionsHandler* handler = options->d_handler;
+ options::OptionsHolder* holder = options->d_holder;
- int extra_optind = 0, main_optind = 0;
+ // Reset getopt(), in the case of multiple calls to parseOptions().
+ // This can be = 1 in newer GNU getopt, but older (< 2007) require = 0.
+ optind = 0;
+#if HAVE_DECL_OPTRESET
+ optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
+#endif /* HAVE_DECL_OPTRESET */
+
+
+ int main_optind = 0;
int old_optind;
- int *optind_ref = &main_optind;
- char** argv = main_argv;
- std::vector<std::string> nonOptions;
+ while(true) { // Repeat Forever
+
+ if(extender->hasPreemptions()){
+ // Stop this round of parsing. We now parse recursively
+ // to start on a new character array for argv.
+ parseOptionsRecursive(options, extender, nonoptions);
+ break;
+ }
- for(;;) {
- int c = -1;
optopt = 0;
std::string option, optionarg;
- Debug("preemptGetopt") << "top of loop, extra_optind == " << extra_optind
- << ", extra_argc == " << extra_argc << std::endl;
- if((extra_optind == 0 ? 1 : extra_optind) < extra_argc) {
-#if HAVE_DECL_OPTRESET
- if(optind_ref != &extra_optind) {
- optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
- }
-#endif /* HAVE_DECL_OPTRESET */
- old_optind = optind = extra_optind;
- optind_ref = &extra_optind;
- argv = extra_argv;
- Debug("preemptGetopt") << "in preempt code, next arg is "
- << extra_argv[optind == 0 ? 1 : optind]
- << std::endl;
- if(extra_argv[extra_optind == 0 ? 1 : extra_optind][0] != '-') {
- InternalError(
- "preempted args cannot give non-options command-line args (found `%s')",
- extra_argv[extra_optind == 0 ? 1 : extra_optind]);
- }
- c = getopt_long(extra_argc, extra_argv,
- "+:${all_modules_short_options}",
- cmdlineOptions, NULL);
- Debug("preemptGetopt") << "in preempt code"
- << ", c == " << c << " (`" << char(c) << "')"
- << " optind == " << optind << std::endl;
- if(optopt == 0 ||
- ( optopt >= ${long_option_value_begin} && optopt <= ${long_option_value_end} )) {
- // long option
- option = argv[old_optind == 0 ? 1 : old_optind];
- optionarg = (optarg == NULL) ? "" : optarg;
- } else {
- // short option
- option = std::string("-") + char(optopt);
- optionarg = (optarg == NULL) ? "" : optarg;
- }
- if(optind >= extra_argc) {
- Debug("preemptGetopt") << "-- no more preempt args" << std::endl;
- unsigned i = 1;
- while(extra_argv[i] != NULL && extra_argv[i][0] != '\0') {
- extra_argv[i][0] = '\0';
- ++i;
- }
- extra_argc = 1;
- extra_optind = 0;
- } else {
- Debug("preemptGetopt") << "-- more preempt args" << std::endl;
- extra_optind = optind;
- }
+
+ optind = main_optind;
+ old_optind = main_optind;
+ //optind_ref = &main_optind;
+ //argv = main_argv;
+
+ // If we encounter an element that is not at zero and does not start
+ // with a "-", this is a non-option. We consume this element as a
+ // non-option.
+ if (main_optind > 0 && main_optind < argc &&
+ argv[main_optind][0] != '-') {
+ Debug("options") << "enqueueing " << argv[main_optind]
+ << " as a non-option." << std::endl;
+ nonoptions->push_back(argv[main_optind]);
+ ++main_optind;
+ extender->popFrontArgument();
+ continue;
}
- if(c == -1) {
-#if HAVE_DECL_OPTRESET
- if(optind_ref != &main_optind) {
- optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
- }
-#endif /* HAVE_DECL_OPTRESET */
- old_optind = optind = main_optind;
- optind_ref = &main_optind;
- argv = main_argv;
- if(main_optind < argc && main_argv[main_optind][0] != '-') {
- do {
- if(main_optind != 0) {
- nonOptions.push_back(main_argv[main_optind]);
- }
- ++main_optind;
- } while(main_optind < argc && main_argv[main_optind][0] != '-');
- continue;
- }
- Debug("options") << "[ before, optind == " << optind << " ]" << std::endl;
-#if defined(__MINGW32__) || defined(__MINGW64__)
- if(optreset == 1 && optind > 1) {
- // on mingw, optreset will reset the optind, so we have to
- // manually advance argc, argv
- main_argv[optind - 1] = main_argv[0];
- argv = main_argv += optind - 1;
- argc -= optind - 1;
- old_optind = optind = main_optind = 1;
- if(argc > 0) {
- Debug("options") << "looking at : " << argv[0] << std::endl;
- }
- /*c = getopt_long(argc, main_argv,
+
+
+ Debug("options") << "[ before, main_optind == " << main_optind << " ]"
+ << std::endl;
+ Debug("options") << "[ before, optind == " << optind << " ]" << std::endl;
+ Debug("options") << "[ argc == " << argc << ", argv == " << argv << " ]"
+ << std::endl;
+ int c = getopt_long(argc, argv,
"+:${all_modules_short_options}",
cmdlineOptions, NULL);
- Debug("options") << "pre-emptory c is " << c << " (" << char(c) << ")" << std::endl;
- Debug("options") << "optind was reset to " << optind << std::endl;
- optind = main_optind;
- Debug("options") << "I restored optind to " << optind << std::endl;*/
- }
-#endif /* __MINGW32__ || __MINGW64__ */
- Debug("options") << "[ argc == " << argc
- << ", main_argv == " << main_argv << " ]" << std::endl;
- c = getopt_long(argc, main_argv,
- "+:${all_modules_short_options}",
- cmdlineOptions, NULL);
- main_optind = optind;
- Debug("options") << "[ got " << int(c) << " (" << char(c) << ") ]"
- << std::endl;
- Debug("options") << "[ next option will be at pos: " << optind << " ]"
- << std::endl;
- if(c == -1) {
+
+ while(main_optind < optind) {
+ main_optind++;
+ extender->popFrontArgument();
+ }
+
+ Debug("options") << "[ got " << int(c) << " (" << char(c) << ") ]"
+ << "[ next option will be at pos: " << optind << " ]"
+ << std::endl;
+
+ // The initial getopt_long call should always determine that argv[0]
+ // is not an option and returns -1. We always manually advance beyond
+ // this element.
+ //
+ // We have to reinitialize optind to 0 instead of 1 as we need to support
+ // changing the argv array passed to getopt.
+ // This is needed as are using GNU extensions.
+ // From: http://man7.org/linux/man-pages/man3/getopt.3.html
+ // A program that scans multiple argument vectors, or rescans the same
+ // vector more than once, and wants to make use of GNU extensions such
+ // as '+' and '-' at the start of optstring, or changes the value of
+ // POSIXLY_CORRECT between scans, must reinitialize getopt() by
+ // resetting optind to 0, rather than the traditional value of 1.
+ // (Resetting to 0 forces the invocation of an internal initialization
+ // routine that rechecks POSIXLY_CORRECT and checks for GNU extensions
+ // in optstring.)
+ if ( old_optind == 0 && c == -1 ) {
+ Assert(main_optind > 0);
+ continue;
+ }
+
+ if ( c == -1 ) {
+ if(Debug.isOn("options")) {
Debug("options") << "done with option parsing" << std::endl;
- break;
+ for(int index = optind; index < argc; ++index) {
+ Debug("options") << "remaining " << argv[index] << std::endl;
+ }
}
- option = argv[old_optind == 0 ? 1 : old_optind];
- optionarg = (optarg == NULL) ? "" : optarg;
+ break;
}
+ option = argv[old_optind == 0 ? 1 : old_optind];
+ optionarg = (optarg == NULL) ? "" : optarg;
+
Debug("preemptGetopt") << "processing option " << c
<< " (`" << char(c) << "'), " << option << std::endl;
switch(c) {
${all_modules_option_handlers}
-#line 709 "${template}"
+#line 722 "${template}"
case ':':
// This can be a long or short option, and the way to get at the
// name of it is different.
- throw OptionException(std::string("option `") + option + "' missing its required argument");
+ throw OptionException(std::string("option `") + option +
+ "' missing its required argument");
case '?':
default:
- if( ( optopt == 0 || ( optopt >= ${long_option_value_begin} && optopt <= ${long_option_value_end} ) ) &&
- !strncmp(argv[optind - 1], "--thread", 8) &&
- strlen(argv[optind - 1]) > 8 ) {
+ if( ( optopt == 0 ||
+ ( optopt >= ${long_option_value_begin} &&
+ optopt <= ${long_option_value_end} )
+ ) && !strncmp(argv[optind - 1], "--thread", 8) &&
+ strlen(argv[optind - 1]) > 8 )
+ {
if(! isdigit(argv[optind - 1][8])) {
throw OptionException(formatThreadOptionException(option));
}
- std::vector<std::string>& threadArgv = d_holder->threadArgv;
+ std::vector<std::string>& threadArgv = holder->threadArgv;
char *end;
long tnum = strtol(argv[optind - 1] + 8, &end, 10);
if(tnum < 0 || (*end != '\0' && *end != '=')) {
@@ -734,23 +753,24 @@ ${all_modules_option_handlers}
}
if(*end == '\0') { // e.g., we have --thread0 "foo"
if(argc <= optind) {
- throw OptionException(std::string("option `") + option
- + "' missing its required argument");
+ throw OptionException(std::string("option `") + option +
+ "' missing its required argument");
}
Debug("options") << "thread " << tnum << " gets option "
<< argv[optind] << std::endl;
- threadArgv[tnum] += argv[(*optind_ref)++];
+ threadArgv[tnum] += argv[main_optind];
+ main_optind++;
} else { // e.g., we have --thread0="foo"
if(end[1] == '\0') {
throw OptionException(std::string("option `") + option +
"' missing its required argument");
}
- Debug("options") << "thread " << tnum << " gets option " << (end + 1)
- << std::endl;
+ Debug("options") << "thread " << tnum << " gets option "
+ << (end + 1) << std::endl;
threadArgv[tnum] += end + 1;
}
- Debug("options") << "thread " << tnum << " now has " << threadArgv[tnum]
- << std::endl;
+ Debug("options") << "thread " << tnum << " now has "
+ << threadArgv[tnum] << std::endl;
break;
}
@@ -759,19 +779,10 @@ ${all_modules_option_handlers}
}
}
- Debug("options") << "returning " << nonOptions.size() << " non-option arguments." << std::endl;
-
- free(extra_argv);
- for(std::vector<char*>::iterator i = allocated.begin(), iend = allocated.end();
- i != iend; ++i)
- {
- char* current = *i;
- #warning "TODO: Unit tests fail if garbage collection is done here."
- //free(current);
- }
- allocated.clear();
+ Debug("options") << "got " << nonoptions->size()
+ << " non-option arguments." << std::endl;
- return nonOptions;
+ free(argv);
}
std::string Options::suggestCommandLineOptions(const std::string& optionName) throw() {
@@ -787,7 +798,7 @@ std::string Options::suggestCommandLineOptions(const std::string& optionName) th
static const char* smtOptions[] = {
${all_modules_smt_options},
-#line 790 "${template}"
+#line 800 "${template}"
NULL
};/* smtOptions[] */
@@ -809,7 +820,7 @@ std::vector< std::vector<std::string> > Options::getOptions() const throw() {
${all_modules_get_options}
-#line 813 "${template}"
+#line 762 "${template}"
return opts;
}
diff --git a/src/options/printer_modes.cpp b/src/options/printer_modes.cpp
index b698ed07d..3ca311a96 100644
--- a/src/options/printer_modes.cpp
+++ b/src/options/printer_modes.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file printer_modes.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/printer_modes.h b/src/options/printer_modes.h
index 8ccceb13f..a05ca2470 100644
--- a/src/options/printer_modes.h
+++ b/src/options/printer_modes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file printer_modes.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/quantifiers_modes.cpp b/src/options/quantifiers_modes.cpp
index e87f00d65..a58120974 100644
--- a/src/options/quantifiers_modes.cpp
+++ b/src/options/quantifiers_modes.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_modes.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/quantifiers_modes.h b/src/options/quantifiers_modes.h
index 540db38ec..5749da972 100644
--- a/src/options/quantifiers_modes.h
+++ b/src/options/quantifiers_modes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_modes.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -83,8 +83,6 @@ enum QcfMode {
QCF_PROP_EQ,
/** use qcf for conflicts, propagations and heuristic instantiations */
QCF_PARTIAL,
- /** use qcf for model checking */
- QCF_MC,
};
enum UserPatMode {
@@ -107,6 +105,12 @@ enum TriggerSelMode {
TRIGGER_SEL_MIN,
/** only consider maximal terms for triggers */
TRIGGER_SEL_MAX,
+ /** consider minimal terms for single triggers, maximal for non-single */
+ TRIGGER_SEL_MIN_SINGLE_MAX,
+ /** consider minimal terms for single triggers, all for non-single */
+ TRIGGER_SEL_MIN_SINGLE_ALL,
+ /** consider all terms for triggers */
+ TRIGGER_SEL_ALL,
};
enum CVC4_PUBLIC PrenexQuantMode {
@@ -163,6 +167,24 @@ enum MacrosQuantMode {
MACROS_QUANT_MODE_GROUND_UF,
};
+enum QuantDSplitMode {
+ /** never do quantifiers splitting */
+ QUANT_DSPLIT_MODE_NONE,
+ /** default */
+ QUANT_DSPLIT_MODE_DEFAULT,
+ /** do quantifiers splitting aggressively */
+ QUANT_DSPLIT_MODE_AGG,
+};
+
+enum QuantRepMode {
+ /** let equality engine choose representatives */
+ QUANT_REP_MODE_EE,
+ /** default, choose representatives that appear first */
+ QUANT_REP_MODE_FIRST,
+ /** choose representatives that have minimal depth */
+ QUANT_REP_MODE_DEPTH,
+};
+
}/* CVC4::theory::quantifiers namespace */
}/* CVC4::theory namespace */
diff --git a/src/options/quantifiers_options b/src/options/quantifiers_options
index f5a6ee843..74b3011a6 100644
--- a/src/options/quantifiers_options
+++ b/src/options/quantifiers_options
@@ -37,11 +37,6 @@ option condVarSplitQuantAgg --cond-var-split-agg-quant bool :default false
aggressive split quantified formulas that lead to variable eliminations
option iteDtTesterSplitQuant --ite-dtt-split-quant bool :read-write :default false
split ites with dt testers as conditions
-# Whether to CNF quantifier bodies
-# option cnfQuant --cnf-quant bool :default false
-# apply CNF conversion to quantified formulas
-option nnfQuant --nnf-quant bool :default true
- apply NNF conversion to quantified formulas
# Whether to pre-skolemize quantifier bodies.
# For example, forall x. ( P( x ) => (exists y. f( y ) = x) ) will be rewritten to
# forall x. P( x ) => f( S( x ) ) = x
@@ -57,6 +52,8 @@ option elimTautQuant --elim-taut-quant bool :default true
eliminate tautological disjuncts of quantified formulas
option purifyQuant --purify-quant bool :default false
purify quantified formulas
+option elimExtArithQuant --elim-ext-arith-quant bool :default true
+ eliminate extended arithmetic symbols in quantified formulas
#### E-matching options
@@ -67,9 +64,13 @@ option termDbMode --term-db-mode CVC4::theory::quantifiers::TermDbMode :default
which ground terms to consider for instantiation
option registerQuantBodyTerms --register-quant-body-terms bool :default false
consider ground terms within bodies of quantified formulas for matching
+option inferArithTriggerEq --infer-arith-trigger-eq bool :default false
+ infer equalities for trigger terms based on solving arithmetic equalities
+option inferArithTriggerEqExp --infer-arith-trigger-eq-exp bool :default false
+ record explanations for inferArithTriggerEq
-option smartTriggers --smart-triggers bool :default true
- enable smart triggers
+option strictTriggers --strict-triggers bool :default false
+ only instantiate quantifiers with user patterns based on triggers
option relevantTriggers --relevant-triggers bool :default false
prefer triggers that are more relevant based on SInE style analysis
option relationalTriggers --relational-triggers bool :default false
@@ -88,20 +89,26 @@ option multiTriggerPriority --multi-trigger-priority bool :default false
only try multi triggers if single triggers give no instantiations
option triggerSelMode --trigger-sel CVC4::theory::quantifiers::TriggerSelMode :default CVC4::theory::quantifiers::TRIGGER_SEL_DEFAULT :read-write :include "options/quantifiers_modes.h" :handler stringToTriggerSelMode
selection mode for triggers
-option userPatternsQuant --user-pat=MODE CVC4::theory::quantifiers::UserPatMode :default CVC4::theory::quantifiers::USER_PAT_MODE_TRUST :include "options/quantifiers_modes.h" :handler stringToUserPatMode
+option userPatternsQuant --user-pat=MODE CVC4::theory::quantifiers::UserPatMode :default CVC4::theory::quantifiers::USER_PAT_MODE_TRUST :read-write :include "options/quantifiers_modes.h" :handler stringToUserPatMode
policy for handling user-provided patterns for quantifier instantiation
option incrementTriggers --increment-triggers bool :default true
generate additional triggers as needed during search
option instWhenMode --inst-when=MODE CVC4::theory::quantifiers::InstWhenMode :default CVC4::theory::quantifiers::INST_WHEN_FULL_LAST_CALL :read-write :include "options/quantifiers_modes.h" :handler stringToInstWhenMode :predicate checkInstWhenMode
when to apply instantiation
+option instWhenStrictInterleave --inst-when-strict-interleave bool :default true :read-write
+ ensure theory combination and standard quantifier effort strategies take turns
+option instWhenPhase --inst-when-phase=N int :read-write :default 2 :read-write
+ instantiation rounds quantifiers takes (>=1) before allowing theory combination to happen
+option instWhenTcFirst --inst-when-tc-first bool :default true :read-write
+ allow theory combination to happen once initially, before quantifier strategies are run
option instMaxLevel --inst-max-level=N int :read-write :default -1
maximum inst level of terms used to instantiate quantified formulas with (-1 == no limit, default)
option instLevelInputOnly --inst-level-input-only bool :default true
only input terms are assigned instantiation level zero
-option internalReps --quant-internal-reps bool :default true
- instantiate with representatives chosen by quantifiers engine
+option quantRepMode --quant-rep-mode=MODE CVC4::theory::quantifiers::QuantRepMode :default CVC4::theory::quantifiers::QUANT_REP_MODE_FIRST :read-write :include "options/quantifiers_modes.h" :handler stringToQuantRepMode
+ selection mode for representatives in quantifiers engine
option eagerInstQuant --eager-inst-quant bool :default false
apply quantifier instantiation eagerly
@@ -167,6 +174,9 @@ option qcfAllConflict --qcf-all-conflict bool :read-write :default false
option instNoEntail --inst-no-entail bool :read-write :default true
do not consider instances of quantified formulas that are currently entailed
+
+option instPropagate --inst-propagate bool :read-write :default false
+ internal propagation for instantiations for selecting relevant instances
### rewrite rules options
@@ -200,6 +210,8 @@ option conjectureGenGtEnum --conjecture-gen-gt-enum=N int :default 50
number of ground terms to generate for model filtering
option conjectureUeeIntro --conjecture-gen-uee-intro bool :default false
more aggressive merging for universal equality engine, introduces terms
+option conjectureGenMaxDepth --conjecture-gen-max-depth=N int :default 3
+ maximum depth of terms to consider for conjectures
### synthesis options
@@ -283,6 +295,10 @@ option macrosQuant --macros-quant bool :read-write :default false
perform quantifiers macro expansion
option macrosQuantMode --macros-quant-mode=MODE CVC4::theory::quantifiers::MacrosQuantMode :default CVC4::theory::quantifiers::MACROS_QUANT_MODE_GROUND_UF :include "options/quantifiers_modes.h" :handler stringToMacrosQuantMode
mode for quantifiers macro expansion
+option quantDynamicSplit --quant-dsplit-mode=MODE CVC4::theory::quantifiers::QuantDSplitMode :read-write :default CVC4::theory::quantifiers::QUANT_DSPLIT_MODE_DEFAULT :include "options/quantifiers_modes.h" :handler stringToQuantDSplitMode
+ mode for dynamic quantifiers splitting
+option quantAntiSkolem --quant-anti-skolem bool :read-write :default false
+ perform anti-skolemization for quantified formulas
### recursive function options
diff --git a/src/options/set_language.cpp b/src/options/set_language.cpp
index f68adbb45..32d3d73ae 100644
--- a/src/options/set_language.cpp
+++ b/src/options/set_language.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file language.h
+/*! \file set_language.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definition of input and output languages
**
diff --git a/src/options/set_language.h b/src/options/set_language.h
index 53b0a6a63..c27bb5184 100644
--- a/src/options/set_language.h
+++ b/src/options/set_language.h
@@ -1,13 +1,13 @@
/********************* */
-/*! \file language.h
+/*! \file set_language.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definition of input and output languages
**
diff --git a/src/options/sets_options b/src/options/sets_options
index 67bed5fe7..be945e4c9 100644
--- a/src/options/sets_options
+++ b/src/options/sets_options
@@ -17,4 +17,12 @@ expert-option setsCare1 --sets-care1 bool :default false
option setsPropFull --sets-prop-full bool :default true
additional propagation at full effort
+option setsAggRewrite --sets-agg-rewrite bool :default false
+ aggressive sets rewriting
+
+option setsGuessEmpty --sets-guess-empty int :default 0
+ when to guess leaf nodes being empty (0...2 : most aggressive..least aggressive)
+
+option setsSlowLemmas --sets-slow-lemmas bool :default true
+
endmodule
diff --git a/src/options/simplification_mode.cpp b/src/options/simplification_mode.cpp
index ab7851ef9..7189dacd1 100644
--- a/src/options/simplification_mode.cpp
+++ b/src/options/simplification_mode.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file simplification_mode.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/simplification_mode.h b/src/options/simplification_mode.h
index dd02ada5c..d1170f9ad 100644
--- a/src/options/simplification_mode.h
+++ b/src/options/simplification_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file simplification_mode.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/options/strings_options b/src/options/strings_options
index 65c293dbc..5c991a1bb 100644
--- a/src/options/strings_options
+++ b/src/options/strings_options
@@ -53,6 +53,18 @@ option stringInferSym strings-infer-sym --strings-infer-sym bool :default true
strings split on empty string
option stringEagerLen strings-eager-len --strings-eager-len bool :default true
strings eager length lemmas
+option stringCheckEntailLen strings-check-entail-len --strings-check-entail-len bool :default true
+ check entailment between length terms to reduce splitting
+option stringProcessLoop strings-process-loop --strings-process-loop bool :default true
+ reduce looping word equations to regular expressions
+option stringAbortLoop strings-abort-loop --strings-abort-loop bool :default false
+ abort when a looping word equation is encountered
+option stringInferAsLemmas strings-infer-as-lemmas --strings-infer-as-lemmas bool :default false
+ always send lemmas out instead of making internal inferences
+option stringRExplainLemmas strings-rexplain-lemmas --strings-rexplain-lemmas bool :default true
+ regression explanations for string lemmas
+option stringMinPrefixExplain strings-min-prefix-explain --strings-min-prefix-explain bool :default true
+ minimize explanations for prefix of normal forms in strings
endmodule
diff --git a/src/options/theoryof_mode.cpp b/src/options/theoryof_mode.cpp
index c05f97ede..cf7178042 100644
--- a/src/options/theoryof_mode.cpp
+++ b/src/options/theoryof_mode.cpp
@@ -1,3 +1,20 @@
+/********************* */
+/*! \file theoryof_mode.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
+
#include "options/theoryof_mode.h"
diff --git a/src/options/theoryof_mode.h b/src/options/theoryof_mode.h
index 5a8723738..98f05a131 100644
--- a/src/options/theoryof_mode.h
+++ b/src/options/theoryof_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theoryof_mode.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Option selection for theoryOf() operation
**
diff --git a/src/options/ufss_mode.h b/src/options/ufss_mode.h
index 6ce05d46a..4a4b8b4c1 100644
--- a/src/options/ufss_mode.h
+++ b/src/options/ufss_mode.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ufss_mode.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Custom handlers and predicates for TheoryUF options
**
diff --git a/src/parser/antlr_input.cpp b/src/parser/antlr_input.cpp
index a1f74d694..6edb23a23 100644
--- a/src/parser/antlr_input.cpp
+++ b/src/parser/antlr_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file antlr_input.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters, Kshitij Bansal
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A super-class for ANTLR-generated input language parsers.
**
diff --git a/src/parser/antlr_input.h b/src/parser/antlr_input.h
index 241d1bc83..8e5e82811 100644
--- a/src/parser/antlr_input.h
+++ b/src/parser/antlr_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file antlr_input.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King, Francois Bobot, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Base for ANTLR parser classes.
**
diff --git a/src/parser/antlr_line_buffered_input.cpp b/src/parser/antlr_line_buffered_input.cpp
index 99b4a3068..22bbaf1db 100644
--- a/src/parser/antlr_line_buffered_input.cpp
+++ b/src/parser/antlr_line_buffered_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file antlr_line_buffered_input.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/parser/antlr_line_buffered_input.h b/src/parser/antlr_line_buffered_input.h
index c47ab324f..2c01a9bde 100644
--- a/src/parser/antlr_line_buffered_input.h
+++ b/src/parser/antlr_line_buffered_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file antlr_line_buffered_input.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/parser/antlr_tracing.h b/src/parser/antlr_tracing.h
index 1709e99a2..93a781796 100644
--- a/src/parser/antlr_tracing.h
+++ b/src/parser/antlr_tracing.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file antlr_tracing.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/parser/antlr_undefines.h b/src/parser/antlr_undefines.h
index 35a6c7e12..edf64c8a6 100644
--- a/src/parser/antlr_undefines.h
+++ b/src/parser/antlr_undefines.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file antlr_undefines.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Every usage undefines standard autotools macro names.
**
diff --git a/src/parser/bounded_token_buffer.cpp b/src/parser/bounded_token_buffer.cpp
index 716639665..c89005941 100644
--- a/src/parser/bounded_token_buffer.cpp
+++ b/src/parser/bounded_token_buffer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bounded_token_buffer.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An ANTLR3 bounded token stream implementation.
**
diff --git a/src/parser/bounded_token_buffer.h b/src/parser/bounded_token_buffer.h
index d11986754..947b33f69 100644
--- a/src/parser/bounded_token_buffer.h
+++ b/src/parser/bounded_token_buffer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bounded_token_buffer.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An ANTLR3 bounded token stream.
**
diff --git a/src/parser/bounded_token_factory.cpp b/src/parser/bounded_token_factory.cpp
index 7d130146f..1c5a00958 100644
--- a/src/parser/bounded_token_factory.cpp
+++ b/src/parser/bounded_token_factory.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bounded_token_factory.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An ANTLR3 bounded token factory implementation.
**
diff --git a/src/parser/bounded_token_factory.h b/src/parser/bounded_token_factory.h
index 5e5e48fab..8535d49cf 100644
--- a/src/parser/bounded_token_factory.h
+++ b/src/parser/bounded_token_factory.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bounded_token_factory.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An ANTLR3 bounded token factory.
**
diff --git a/src/parser/cvc/Cvc.g b/src/parser/cvc/Cvc.g
index 967503074..c497fcd0d 100644
--- a/src/parser/cvc/Cvc.g
+++ b/src/parser/cvc/Cvc.g
@@ -1,13 +1,13 @@
/* ******************* */
/*! \file Cvc.g
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King, Dejan Jovanovic, Tianyi Liang, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Parser for CVC presentation input language
**
@@ -213,16 +213,35 @@ tokens {
// Strings
STRING_TOK = 'STRING';
- SCONCAT_TOK = 'SCONCAT';
- SCONTAINS_TOK = 'CONTAINS';
- SSUBSTR_TOK = 'SUBSTR';
- SINDEXOF_TOK = 'INDEXOF';
- SREPLACE_TOK = 'REPLACE';
- SPREFIXOF_TOK = 'PREFIXOF';
- SSUFFIXOF_TOK = 'SUFFIXOF';
- STOINTEGER_TOK = 'TO_INTEGER';
- STOSTRING_TOK = 'TO_STRING';
- STORE_TOK = 'TO_RE';
+ STRING_CONCAT_TOK = 'CONCAT';
+ STRING_LENGTH_TOK = 'LENGTH';
+ STRING_CONTAINS_TOK = 'CONTAINS';
+ STRING_SUBSTR_TOK = 'SUBSTR';
+ STRING_CHARAT_TOK = 'CHARAT';
+ STRING_INDEXOF_TOK = 'INDEXOF';
+ STRING_REPLACE_TOK = 'REPLACE';
+ STRING_PREFIXOF_TOK = 'PREFIXOF';
+ STRING_SUFFIXOF_TOK = 'SUFFIXOF';
+ STRING_STOI_TOK = 'STRING_TO_INTEGER';
+ STRING_ITOS_TOK = 'INTEGER_TO_STRING';
+ STRING_U16TOS_TOK = 'UINT16_TO_STRING';
+ STRING_STOU16_TOK = 'STRING_TO_UINT16';
+ STRING_U32TOS_TOK = 'UINT32_TO_STRING';
+ STRING_STOU32_TOK = 'STRING_TO_UINT32';
+ //Regular expressions (TODO)
+ //STRING_IN_REGEXP_TOK
+ //STRING_TO_REGEXP_TOK
+ //REGEXP_CONCAT_TOK
+ //REGEXP_UNION_TOK
+ //REGEXP_INTER_TOK
+ //REGEXP_STAR_TOK
+ //REGEXP_PLUS_TOK
+ //REGEXP_OPT_TOK
+ //REGEXP_RANGE_TOK
+ //REGEXP_LOOP_TOK
+ //REGEXP_EMPTY_TOK
+ //REGEXP_SIGMA_TOK
+
FMF_CARD_TOK = 'HAS_CARD';
@@ -367,6 +386,7 @@ Kind getOperatorKind(int type, bool& negate) {
case CONCAT_TOK: return kind::BITVECTOR_CONCAT;
case BAR: return kind::BITVECTOR_OR;
case BVAND_TOK: return kind::BITVECTOR_AND;
+
}
std::stringstream ss;
@@ -1694,7 +1714,6 @@ postfixTerm[CVC4::Expr& f]
f = MK_EXPR(CVC4::kind::SELECT, f, f2);
}
}
-
/* left- or right-shift */
| ( LEFTSHIFT_TOK { left = true; }
| RIGHTSHIFT_TOK { left = false; } ) k=numeral
@@ -1920,7 +1939,6 @@ bvTerm[CVC4::Expr& f]
{ f = MK_EXPR(CVC4::kind::BITVECTOR_SGT, f, f2); }
| BVSGE_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
{ f = MK_EXPR(CVC4::kind::BITVECTOR_SGE, f, f2); }
-
| stringTerm[f]
;
@@ -1932,27 +1950,35 @@ stringTerm[CVC4::Expr& f]
std::vector<Expr> args;
}
/* String prefix operators */
- : SCONCAT_TOK LPAREN formula[f] { args.push_back(f); }
+ : STRING_CONCAT_TOK LPAREN formula[f] { args.push_back(f); }
( COMMA formula[f2] { args.push_back(f2); } )+ RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_CONCAT, args); }
- | SCONTAINS_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
+ | STRING_LENGTH_TOK LPAREN formula[f] RPAREN
+ { f = MK_EXPR(CVC4::kind::STRING_LENGTH, f); }
+ | STRING_CONTAINS_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_STRCTN, f, f2); }
- | SSUBSTR_TOK LPAREN formula[f] COMMA formula[f2] COMMA formula[f3] RPAREN
+ | STRING_SUBSTR_TOK LPAREN formula[f] COMMA formula[f2] COMMA formula[f3] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_SUBSTR, f, f2, f3); }
- | SINDEXOF_TOK LPAREN formula[f] COMMA formula[f2] COMMA formula[f3] RPAREN
+ | STRING_INDEXOF_TOK LPAREN formula[f] COMMA formula[f2] COMMA formula[f3] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_STRIDOF, f, f2, f3); }
- | SREPLACE_TOK LPAREN formula[f] COMMA formula[f2] COMMA formula[f3] RPAREN
+ | STRING_REPLACE_TOK LPAREN formula[f] COMMA formula[f2] COMMA formula[f3] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_STRREPL, f, f2, f3); }
- | SPREFIXOF_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
+ | STRING_PREFIXOF_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_PREFIX, f, f2); }
- | SSUFFIXOF_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
+ | STRING_SUFFIXOF_TOK LPAREN formula[f] COMMA formula[f2] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_SUFFIX, f, f2); }
- | STOINTEGER_TOK LPAREN formula[f] RPAREN
+ | STRING_STOI_TOK LPAREN formula[f] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_STOI, f); }
- | STOSTRING_TOK LPAREN formula[f] RPAREN
+ | STRING_ITOS_TOK LPAREN formula[f] RPAREN
{ f = MK_EXPR(CVC4::kind::STRING_ITOS, f); }
- | STORE_TOK LPAREN formula[f] RPAREN
- { f = MK_EXPR(CVC4::kind::STRING_TO_REGEXP, f); }
+ | STRING_U16TOS_TOK LPAREN formula[f] RPAREN
+ { f = MK_EXPR(CVC4::kind::STRING_U16TOS, f); }
+ | STRING_STOU16_TOK LPAREN formula[f] RPAREN
+ { f = MK_EXPR(CVC4::kind::STRING_STOU16, f); }
+ | STRING_U32TOS_TOK LPAREN formula[f] RPAREN
+ { f = MK_EXPR(CVC4::kind::STRING_U32TOS, f); }
+ | STRING_STOU32_TOK LPAREN formula[f] RPAREN
+ { f = MK_EXPR(CVC4::kind::STRING_STOU32, f); }
/* string literal */
| str[s]
@@ -2018,6 +2044,11 @@ simpleTerm[CVC4::Expr& f]
}
}
+ /* set cardinality literal */
+ | BAR BAR formula[f] { args.push_back(f); } BAR BAR
+ { f = MK_EXPR(kind::CARD, args[0]);
+ }
+
/* array literals */
| ARRAY_TOK /* { PARSER_STATE->pushScope(); } */ LPAREN
restrictedType[t, CHECK_DECLARED] OF_TOK restrictedType[t2, CHECK_DECLARED]
diff --git a/src/parser/cvc/cvc_input.cpp b/src/parser/cvc/cvc_input.cpp
index 2370109ef..9e00567fe 100644
--- a/src/parser/cvc/cvc_input.cpp
+++ b/src/parser/cvc/cvc_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc_input.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/cvc/cvc_input.h b/src/parser/cvc/cvc_input.h
index a88fd7223..aff3698fc 100644
--- a/src/parser/cvc/cvc_input.h
+++ b/src/parser/cvc/cvc_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc_input.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/input.cpp b/src/parser/input.cpp
index 896e8bc74..5fadbcc54 100644
--- a/src/parser/input.cpp
+++ b/src/parser/input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file input.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A super-class for input language parsers.
**
diff --git a/src/parser/input.h b/src/parser/input.h
index 4ff37409c..7dce369c5 100644
--- a/src/parser/input.h
+++ b/src/parser/input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file input.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Base for parser inputs.
**
diff --git a/src/parser/memory_mapped_input_buffer.cpp b/src/parser/memory_mapped_input_buffer.cpp
index 7be1c9aba..c9515aa92 100644
--- a/src/parser/memory_mapped_input_buffer.cpp
+++ b/src/parser/memory_mapped_input_buffer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file memory_mapped_input_buffer.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/memory_mapped_input_buffer.h b/src/parser/memory_mapped_input_buffer.h
index bacd9cb0f..2a34d1197 100644
--- a/src/parser/memory_mapped_input_buffer.h
+++ b/src/parser/memory_mapped_input_buffer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file memory_mapped_input_buffer.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief ANTLR input buffer from a memory-mapped file.
**
diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp
index b9531e8d9..712494805 100644
--- a/src/parser/parser.cpp
+++ b/src/parser/parser.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file parser.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Tim King, Dejan Jovanovic, Kshitij Bansal, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Parser state implementation.
**
diff --git a/src/parser/parser.h b/src/parser/parser.h
index 9c2c7f7be..54f25ae74 100644
--- a/src/parser/parser.h
+++ b/src/parser/parser.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file parser.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Dejan Jovanovic, Kshitij Bansal, Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A collection of state for use by parser implementations.
**
diff --git a/src/parser/parser_builder.cpp b/src/parser/parser_builder.cpp
index e095d208b..8580d5672 100644
--- a/src/parser/parser_builder.cpp
+++ b/src/parser/parser_builder.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file parser_builder.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic, Francois Bobot
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A builder for parsers.
**
diff --git a/src/parser/parser_builder.h b/src/parser/parser_builder.h
index fe652286b..68dd684c1 100644
--- a/src/parser/parser_builder.h
+++ b/src/parser/parser_builder.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file parser_builder.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A builder for parsers.
**
diff --git a/src/parser/parser_exception.h b/src/parser/parser_exception.h
index de47767c9..d83aab299 100644
--- a/src/parser/parser_exception.h
+++ b/src/parser/parser_exception.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file parser_exception.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Exception class for parse errors.
**
diff --git a/src/parser/smt1/Smt1.g b/src/parser/smt1/Smt1.g
index a8e797470..824e6db8b 100644
--- a/src/parser/smt1/Smt1.g
+++ b/src/parser/smt1/Smt1.g
@@ -1,13 +1,13 @@
/* ******************* */
/*! \file Smt1.g
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Christopher L. Conway
- ** Minor contributors (to current version): Andrew Reynolds, Tim King
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Parser for SMT-LIB input language.
**
diff --git a/src/parser/smt1/smt1.cpp b/src/parser/smt1/smt1.cpp
index a2abee2e7..50f62009a 100644
--- a/src/parser/smt1/smt1.cpp
+++ b/src/parser/smt1/smt1.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt1.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Tim King, Tianyi Liang, Dejan Jovanovic, Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** Definitions of SMT-LIB (v1) constants.
**/
diff --git a/src/parser/smt1/smt1.h b/src/parser/smt1/smt1.h
index 20ba0401c..45de222ac 100644
--- a/src/parser/smt1/smt1.h
+++ b/src/parser/smt1/smt1.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt1.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett, Tianyi Liang
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** Definitions of SMT constants.
**/
diff --git a/src/parser/smt1/smt1_input.cpp b/src/parser/smt1/smt1_input.cpp
index 8a8aa577e..69801e8b4 100644
--- a/src/parser/smt1/smt1_input.cpp
+++ b/src/parser/smt1/smt1_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt1_input.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/smt1/smt1_input.h b/src/parser/smt1/smt1_input.h
index de21036c0..0e719f519 100644
--- a/src/parser/smt1/smt1_input.h
+++ b/src/parser/smt1/smt1_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt1_input.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Christopher L. Conway
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index fb3b5ec5e..38163c579 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -1,13 +1,13 @@
/* ******************* */
/*! \file Smt2.g
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic, Kshitij Bansal, Tianyi Liang, Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Parser for SMT-LIB v2 input language
**
@@ -765,9 +765,7 @@ sygusCommand returns [CVC4::Command* cmd = NULL]
Command* c = new SetUserAttributeCommand("sygus", sygusVar);
c->setMuted(true);
PARSER_STATE->preemptCommand(c);
- c = new AssertCommand(body);
- PARSER_STATE->preemptCommand(c);
- $cmd = new CheckSatCommand();
+ $cmd = new CheckSynthCommand(body);
}
| c = command { $cmd = c; }
// /* error handling */
@@ -1302,6 +1300,12 @@ extendedCommand[CVC4::Command*& cmd]
| SIMPLIFY_TOK { PARSER_STATE->checkThatLogicIsSet(); }
term[e,e2]
{ cmd = new SimplifyCommand(e); }
+ | GET_QE_TOK { PARSER_STATE->checkThatLogicIsSet(); }
+ term[e,e2]
+ { cmd = new GetQuantifierEliminationCommand(e, true); }
+ | GET_QE_DISJUNCT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
+ term[e,e2]
+ { cmd = new GetQuantifierEliminationCommand(e, false); }
;
@@ -2562,6 +2566,8 @@ DECLARE_CONST_TOK : 'declare-const';
DEFINE_CONST_TOK : 'define-const';
SIMPLIFY_TOK : 'simplify';
INCLUDE_TOK : 'include';
+GET_QE_TOK : 'get-qe';
+GET_QE_DISJUNCT_TOK : 'get-qe-disjunct';
// SyGuS commands
SYNTH_FUN_TOK : 'synth-fun';
diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp
index ff22dd9c7..463adcb54 100644
--- a/src/parser/smt2/smt2.cpp
+++ b/src/parser/smt2/smt2.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Kshitij Bansal, Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett, Tianyi Liang
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Kshitij Bansal, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definitions of SMT2 constants.
**
@@ -230,6 +230,7 @@ void Smt2::addTheory(Theory theory) {
addOperator(kind::PRODUCT, "product");
addOperator(kind::SINGLETON, "singleton");
addOperator(kind::INSERT, "insert");
+ addOperator(kind::CARD, "card");
break;
case THEORY_DATATYPES:
diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h
index 7cf92f008..1ae2c9dd7 100644
--- a/src/parser/smt2/smt2.h
+++ b/src/parser/smt2/smt2.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tianyi Liang, Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definitions of SMT2 constants.
**
diff --git a/src/parser/smt2/smt2_input.cpp b/src/parser/smt2/smt2_input.cpp
index cea6db278..7aa4c3441 100644
--- a/src/parser/smt2/smt2_input.cpp
+++ b/src/parser/smt2/smt2_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2_input.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/smt2/smt2_input.h b/src/parser/smt2/smt2_input.h
index 9a07ddc08..0ed88393f 100644
--- a/src/parser/smt2/smt2_input.h
+++ b/src/parser/smt2/smt2_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2_input.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Christopher L. Conway, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/smt2/sygus_input.cpp b/src/parser/smt2/sygus_input.cpp
index e4f36b3df..5b20e0a9a 100644
--- a/src/parser/smt2/sygus_input.cpp
+++ b/src/parser/smt2/sygus_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file sygus_input.cpp
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/smt2/sygus_input.h b/src/parser/smt2/sygus_input.h
index 1f0078076..50bc973e9 100644
--- a/src/parser/smt2/sygus_input.h
+++ b/src/parser/smt2/sygus_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sygus_input.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/tptp/Tptp.g b/src/parser/tptp/Tptp.g
index d57aea376..73dcfa6cb 100644
--- a/src/parser/tptp/Tptp.g
+++ b/src/parser/tptp/Tptp.g
@@ -1,13 +1,13 @@
/* ******************* */
/*! \file Tptp.g
** \verbatim
- ** Original author: Francois Bobot
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Francois Bobot, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Parser for TPTP input language.
**
diff --git a/src/parser/tptp/tptp.cpp b/src/parser/tptp/tptp.cpp
index 9d3bd4b1c..193c27e11 100644
--- a/src/parser/tptp/tptp.cpp
+++ b/src/parser/tptp/tptp.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file tptp.cpp
** \verbatim
- ** Original author: Francois Bobot
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Francois Bobot, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definitions of TPTP constants.
**
diff --git a/src/parser/tptp/tptp.h b/src/parser/tptp/tptp.h
index 0937a11bf..06b7fac3c 100644
--- a/src/parser/tptp/tptp.h
+++ b/src/parser/tptp/tptp.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file tptp.h
** \verbatim
- ** Original author: Francois Bobot
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Francois Bobot, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Definitions of TPTP constants.
**
diff --git a/src/parser/tptp/tptp_input.cpp b/src/parser/tptp/tptp_input.cpp
index 5a393a58c..42337b42b 100644
--- a/src/parser/tptp/tptp_input.cpp
+++ b/src/parser/tptp/tptp_input.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file tptp_input.cpp
** \verbatim
- ** Original author: Francois Bobot
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Francois Bobot, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/parser/tptp/tptp_input.h b/src/parser/tptp/tptp_input.h
index 6357beae1..28bf1828a 100644
--- a/src/parser/tptp/tptp_input.h
+++ b/src/parser/tptp/tptp_input.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file tptp_input.h
** \verbatim
- ** Original author: Francois Bobot
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Francois Bobot, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add file-specific comments here ]].
**
diff --git a/src/printer/ast/ast_printer.cpp b/src/printer/ast/ast_printer.cpp
index d05309ef7..e15d8766f 100644
--- a/src/printer/ast/ast_printer.cpp
+++ b/src/printer/ast/ast_printer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ast_printer.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the AST output language
**
diff --git a/src/printer/ast/ast_printer.h b/src/printer/ast/ast_printer.h
index ea425a16f..ef123d1d4 100644
--- a/src/printer/ast/ast_printer.h
+++ b/src/printer/ast/ast_printer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ast_printer.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the AST output language
**
diff --git a/src/printer/cvc/cvc_printer.cpp b/src/printer/cvc/cvc_printer.cpp
index 9de790d7b..8bd222ca7 100644
--- a/src/printer/cvc/cvc_printer.cpp
+++ b/src/printer/cvc/cvc_printer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc_printer.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Francois Bobot, Liana Hadarean, Clark Barrett, Tim King, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the CVC output language
**
@@ -809,6 +809,13 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, int depth, bool types, boo
return;
break;
}
+ case kind::CARD: {
+ out << "||";
+ toStream(out, n[0], depth, types, false);
+ out << "||";
+ return;
+ break;
+ }
// Quantifiers
case kind::FORALL:
diff --git a/src/printer/cvc/cvc_printer.h b/src/printer/cvc/cvc_printer.h
index 0809696c4..fd250132b 100644
--- a/src/printer/cvc/cvc_printer.h
+++ b/src/printer/cvc/cvc_printer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cvc_printer.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the CVC output language
**
diff --git a/src/printer/dagification_visitor.cpp b/src/printer/dagification_visitor.cpp
index 5bb4af436..c52f0ed08 100644
--- a/src/printer/dagification_visitor.cpp
+++ b/src/printer/dagification_visitor.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file dagification_visitor.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of a dagifier for CVC4 expressions
**
diff --git a/src/printer/dagification_visitor.h b/src/printer/dagification_visitor.h
index 99fa7db64..c79ec514f 100644
--- a/src/printer/dagification_visitor.h
+++ b/src/printer/dagification_visitor.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file dagification_visitor.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A dagifier for CVC4 expressions
**
diff --git a/src/printer/printer.cpp b/src/printer/printer.cpp
index a2734160f..c715312c1 100644
--- a/src/printer/printer.cpp
+++ b/src/printer/printer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file printer.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Base of the pretty-printer interface
**
diff --git a/src/printer/printer.h b/src/printer/printer.h
index f4cd4635c..a6156ad16 100644
--- a/src/printer/printer.h
+++ b/src/printer/printer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file printer.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Base of the pretty-printer interface
**
diff --git a/src/printer/smt1/smt1_printer.cpp b/src/printer/smt1/smt1_printer.cpp
index bcd6faa83..7fde0749b 100644
--- a/src/printer/smt1/smt1_printer.cpp
+++ b/src/printer/smt1/smt1_printer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt1_printer.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the SMT output language
**
diff --git a/src/printer/smt1/smt1_printer.h b/src/printer/smt1/smt1_printer.h
index b13b894f0..d8101d916 100644
--- a/src/printer/smt1/smt1_printer.h
+++ b/src/printer/smt1/smt1_printer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt1_printer.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the SMT output language
**
diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp
index 7c501ffec..9d61e5ef8 100644
--- a/src/printer/smt2/smt2_printer.cpp
+++ b/src/printer/smt2/smt2_printer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2_printer.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Tim King, Liana Hadarean, Kshitij Bansal, Tianyi Liang, Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Martin Brain
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the SMT2 output language
**
@@ -385,6 +385,8 @@ void Smt2Printer::toStream(std::ostream& out, TNode n,
// arrays theory
case kind::SELECT:
case kind::STORE:
+ case kind::PARTIAL_SELECT_0:
+ case kind::PARTIAL_SELECT_1:
case kind::ARRAY_TYPE: out << smtKindString(k) << " "; break;
// string theory
@@ -449,7 +451,7 @@ void Smt2Printer::toStream(std::ostream& out, TNode n,
case kind::CARDINALITY_CONSTRAINT: out << "fmf.card "; break;
case kind::CARDINALITY_VALUE: out << "fmf.card.val "; break;
-
+
// bv theory
case kind::BITVECTOR_CONCAT: out << "concat "; forceBinary = true; break;
case kind::BITVECTOR_AND: out << "bvand "; forceBinary = true; break;
@@ -736,6 +738,8 @@ static string smtKindString(Kind k) throw() {
case kind::SELECT: return "select";
case kind::STORE: return "store";
case kind::ARRAY_TYPE: return "Array";
+ case kind::PARTIAL_SELECT_0: return "partial_select_0";
+ case kind::PARTIAL_SELECT_1: return "partial_select_1";
// bv theory
case kind::BITVECTOR_CONCAT: return "concat";
@@ -981,7 +985,7 @@ void Smt2Printer::toStream(std::ostream& out, const Command* c,
static std::string quoteSymbol(TNode n) {
-#warning "check the old implementation. It seems off."
+ // #warning "check the old implementation. It seems off."
std::stringstream ss;
ss << language::SetLanguage(language::output::LANG_SMTLIB_V2_5);
return CVC4::quoteSymbol(ss.str());
diff --git a/src/printer/smt2/smt2_printer.h b/src/printer/smt2/smt2_printer.h
index a57c4f8dc..0354a5738 100644
--- a/src/printer/smt2/smt2_printer.h
+++ b/src/printer/smt2/smt2_printer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2_printer.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the SMT2 output language
**
diff --git a/src/printer/tptp/tptp_printer.cpp b/src/printer/tptp/tptp_printer.cpp
index 46ae47ba4..1be98ffad 100644
--- a/src/printer/tptp/tptp_printer.cpp
+++ b/src/printer/tptp/tptp_printer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file tptp_printer.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the TPTP output language
**
diff --git a/src/printer/tptp/tptp_printer.h b/src/printer/tptp/tptp_printer.h
index 90a682bcc..aac69d046 100644
--- a/src/printer/tptp/tptp_printer.h
+++ b/src/printer/tptp/tptp_printer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file tptp_printer.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The pretty-printer interface for the TPTP output language
**
diff --git a/src/proof/arith_proof.cpp b/src/proof/arith_proof.cpp
new file mode 100644
index 000000000..a1287b667
--- /dev/null
+++ b/src/proof/arith_proof.cpp
@@ -0,0 +1,833 @@
+/********************* */
+/*! \file arith_proof.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
+**/
+
+#include "proof/theory_proof.h"
+#include "proof/proof_manager.h"
+#include "proof/arith_proof.h"
+#include "theory/arith/theory_arith.h"
+#include <stack>
+
+namespace CVC4 {
+
+inline static Node eqNode(TNode n1, TNode n2) {
+ return NodeManager::currentNM()->mkNode(n1.getType().isBoolean() ? kind::IFF : kind::EQUAL, n1, n2);
+}
+
+// congrence matching term helper
+inline static bool match(TNode n1, TNode n2) {
+ Debug("pf::arith") << "match " << n1 << " " << n2 << std::endl;
+ if(ProofManager::currentPM()->hasOp(n1)) {
+ n1 = ProofManager::currentPM()->lookupOp(n1);
+ }
+ if(ProofManager::currentPM()->hasOp(n2)) {
+ n2 = ProofManager::currentPM()->lookupOp(n2);
+ }
+ Debug("pf::arith") << "+ match " << n1 << " " << n2 << std::endl;
+ if(n1 == n2) {
+ return true;
+ }
+ if(n1.getType().isFunction() && n2.hasOperator()) {
+ if(ProofManager::currentPM()->hasOp(n2.getOperator())) {
+ return n1 == ProofManager::currentPM()->lookupOp(n2.getOperator());
+ } else {
+ return n1 == n2.getOperator();
+ }
+ }
+ if(n2.getType().isFunction() && n1.hasOperator()) {
+ if(ProofManager::currentPM()->hasOp(n1.getOperator())) {
+ return n2 == ProofManager::currentPM()->lookupOp(n1.getOperator());
+ } else {
+ return n2 == n1.getOperator();
+ }
+ }
+ if(n1.hasOperator() && n2.hasOperator() && n1.getOperator() != n2.getOperator()) {
+ return false;
+ }
+ for(size_t i = 0; i < n1.getNumChildren() && i < n2.getNumChildren(); ++i) {
+ if(n1[i] != n2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void ProofArith::toStream(std::ostream& out) {
+ Trace("theory-proof-debug") << "; Print Arith proof..." << std::endl;
+ //AJR : carry this further?
+ LetMap map;
+ toStreamLFSC(out, ProofManager::getArithProof(), d_proof, map);
+}
+
+void ProofArith::toStreamLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, const LetMap& map) {
+ Debug("lfsc-arith") << "Printing arith proof in LFSC : " << std::endl;
+ pf->debug_print("lfsc-arith");
+ Debug("lfsc-arith") << std::endl;
+ toStreamRecLFSC( out, tp, pf, 0, map );
+}
+
+Node ProofArith::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, unsigned tb, const LetMap& map) {
+ Debug("pf::arith") << std::endl << std::endl << "toStreamRecLFSC called. tb = " << tb << " . proof:" << std::endl;
+ pf->debug_print("pf::arith");
+ Debug("pf::arith") << std::endl;
+
+ if(tb == 0) {
+ Assert(pf->d_id == theory::eq::MERGED_THROUGH_TRANS);
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.size() >= 2);
+
+ int neg = -1;
+ theory::eq::EqProof subTrans;
+ subTrans.d_id = theory::eq::MERGED_THROUGH_TRANS;
+ subTrans.d_node = pf->d_node;
+
+ size_t i = 0;
+ while (i < pf->d_children.size()) {
+ // Look for the negative clause, with which we will form a contradiction.
+ if(!pf->d_children[i]->d_node.isNull() && pf->d_children[i]->d_node.getKind() == kind::NOT) {
+ Assert(neg < 0);
+ neg = i;
+ ++i;
+ }
+
+ // Handle congruence closures over equalities.
+ else if (pf->d_children[i]->d_id==theory::eq::MERGED_THROUGH_CONGRUENCE && pf->d_children[i]->d_node.isNull()) {
+ Debug("pf::arith") << "Handling congruence over equalities" << std::endl;
+
+ // Gather the sequence of consecutive congruence closures.
+ std::vector<const theory::eq::EqProof *> congruenceClosures;
+ unsigned count;
+ Debug("pf::arith") << "Collecting congruence sequence" << std::endl;
+ for (count = 0;
+ i + count < pf->d_children.size() &&
+ pf->d_children[i + count]->d_id==theory::eq::MERGED_THROUGH_CONGRUENCE &&
+ pf->d_children[i + count]->d_node.isNull();
+ ++count) {
+ Debug("pf::arith") << "Found a congruence: " << std::endl;
+ pf->d_children[i+count]->debug_print("pf::arith");
+ congruenceClosures.push_back(pf->d_children[i+count]);
+ }
+
+ Debug("pf::arith") << "Total number of congruences found: " << congruenceClosures.size() << std::endl;
+
+ // Determine if the "target" of the congruence sequence appears right before or right after the sequence.
+ bool targetAppearsBefore = true;
+ bool targetAppearsAfter = true;
+
+ if ((i == 0) || (i == 1 && neg == 0)) {
+ Debug("pf::arith") << "Target does not appear before" << std::endl;
+ targetAppearsBefore = false;
+ }
+
+ if ((i + count >= pf->d_children.size()) ||
+ (!pf->d_children[i + count]->d_node.isNull() &&
+ pf->d_children[i + count]->d_node.getKind() == kind::NOT)) {
+ Debug("pf::arith") << "Target does not appear after" << std::endl;
+ targetAppearsAfter = false;
+ }
+
+ // Assert that we have precisely one target clause.
+ Assert(targetAppearsBefore != targetAppearsAfter);
+
+ // Begin breaking up the congruences and ordering the equalities correctly.
+ std::vector<theory::eq::EqProof *> orderedEqualities;
+
+
+ // Insert target clause first.
+ if (targetAppearsBefore) {
+ orderedEqualities.push_back(pf->d_children[i - 1]);
+ // The target has already been added to subTrans; remove it.
+ subTrans.d_children.pop_back();
+ } else {
+ orderedEqualities.push_back(pf->d_children[i + count]);
+ }
+
+ // Start with the congruence closure closest to the target clause, and work our way back/forward.
+ if (targetAppearsBefore) {
+ for (unsigned j = 0; j < count; ++j) {
+ if (pf->d_children[i + j]->d_children[0]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.begin(), pf->d_children[i + j]->d_children[0]);
+ if (pf->d_children[i + j]->d_children[1]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.end(), pf->d_children[i + j]->d_children[1]);
+ }
+ } else {
+ for (unsigned j = 0; j < count; ++j) {
+ if (pf->d_children[i + count - 1 - j]->d_children[0]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.begin(), pf->d_children[i + count - 1 - j]->d_children[0]);
+ if (pf->d_children[i + count - 1 - j]->d_children[1]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.end(), pf->d_children[i + count - 1 - j]->d_children[1]);
+ }
+ }
+
+ // Copy the result into the main transitivity proof.
+ subTrans.d_children.insert(subTrans.d_children.end(), orderedEqualities.begin(), orderedEqualities.end());
+
+ // Increase i to skip over the children that have been processed.
+ i += count;
+ if (targetAppearsAfter) {
+ ++i;
+ }
+ }
+
+ // Else, just copy the child proof as is
+ else {
+ subTrans.d_children.push_back(pf->d_children[i]);
+ ++i;
+ }
+ }
+ Assert(neg >= 0);
+
+ Node n1;
+ std::stringstream ss;
+ //Assert(subTrans.d_children.size() == pf->d_children.size() - 1);
+ Debug("pf::arith") << "\nsubtrans has " << subTrans.d_children.size() << " children\n";
+ if(pf->d_children.size() > 2) {
+ n1 = toStreamRecLFSC(ss, tp, &subTrans, 1, map);
+ } else {
+ n1 = toStreamRecLFSC(ss, tp, subTrans.d_children[0], 1, map);
+ Debug("pf::arith") << "\nsubTrans unique child " << subTrans.d_children[0]->d_id << " was proven\ngot: " << n1 << std::endl;
+ }
+
+ Node n2 = pf->d_children[neg]->d_node;
+ Assert(n2.getKind() == kind::NOT);
+ out << "(clausify_false (contra _ ";
+ Debug("pf::arith") << "\nhave proven: " << n1 << std::endl;
+ Debug("pf::arith") << "n2 is " << n2[0] << std::endl;
+
+ if (n2[0].getNumChildren() > 0) { Debug("pf::arith") << "\nn2[0]: " << n2[0][0] << std::endl; }
+ if (n1.getNumChildren() > 1) { Debug("pf::arith") << "n1[1]: " << n1[1] << std::endl; }
+
+ if(n2[0].getKind() == kind::APPLY_UF) {
+ out << "(trans _ _ _ _ ";
+ out << "(symm _ _ _ ";
+ out << ss.str();
+ out << ") (pred_eq_f _ " << ProofManager::getLitName(n2[0]) << ")) t_t_neq_f))" << std::endl;
+ } else {
+ Assert((n1[0] == n2[0][0] && n1[1] == n2[0][1]) || (n1[1] == n2[0][0] && n1[0] == n2[0][1]));
+ if(n1[1] == n2[0][0]) {
+ out << "(symm _ _ _ " << ss.str() << ")";
+ } else {
+ out << ss.str();
+ }
+ out << " " << ProofManager::getLitName(n2[0]) << "))" << std::endl;
+ }
+ return Node();
+ }
+
+ switch(pf->d_id) {
+ case theory::eq::MERGED_THROUGH_CONGRUENCE: {
+ Debug("pf::arith") << "\nok, looking at congruence:\n";
+ pf->debug_print("pf::arith");
+ std::stack<const theory::eq::EqProof*> stk;
+ for(const theory::eq::EqProof* pf2 = pf; pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE; pf2 = pf2->d_children[0]) {
+ Assert(!pf2->d_node.isNull());
+ Assert(pf2->d_node.getKind() == kind::PARTIAL_APPLY_UF || pf2->d_node.getKind() == kind::BUILTIN || pf2->d_node.getKind() == kind::APPLY_UF || pf2->d_node.getKind() == kind::SELECT || pf2->d_node.getKind() == kind::STORE);
+ Assert(pf2->d_children.size() == 2);
+ out << "(cong _ _ _ _ _ _ ";
+ stk.push(pf2);
+ }
+ Assert(stk.top()->d_children[0]->d_id != theory::eq::MERGED_THROUGH_CONGRUENCE);
+ NodeBuilder<> b1(kind::PARTIAL_APPLY_UF), b2(kind::PARTIAL_APPLY_UF);
+ const theory::eq::EqProof* pf2 = stk.top();
+ stk.pop();
+ Assert(pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE);
+ Node n1 = toStreamRecLFSC(out, tp, pf2->d_children[0], tb + 1, map);
+ out << " ";
+ std::stringstream ss;
+ Node n2 = toStreamRecLFSC(ss, tp, pf2->d_children[1], tb + 1, map);
+ Debug("pf::arith") << "\nok, in FIRST cong[" << stk.size() << "]" << "\n";
+ pf2->debug_print("pf::arith");
+ Debug("pf::arith") << "looking at " << pf2->d_node << "\n";
+ Debug("pf::arith") << " " << n1 << "\n";
+ Debug("pf::arith") << " " << n2 << "\n";
+ int side = 0;
+ if(match(pf2->d_node, n1[0])) {
+ //if(tb == 1) {
+ Debug("pf::arith") << "SIDE IS 0\n";
+ //}
+ side = 0;
+ } else {
+ //if(tb == 1) {
+ Debug("pf::arith") << "SIDE IS 1\n";
+ //}
+ if(!match(pf2->d_node, n1[1])) {
+ Debug("pf::arith") << "IN BAD CASE, our first subproof is\n";
+ pf2->d_children[0]->debug_print("pf::arith");
+ }
+ Assert(match(pf2->d_node, n1[1]));
+ side = 1;
+ }
+ if(n1[side].getKind() == kind::APPLY_UF || n1[side].getKind() == kind::PARTIAL_APPLY_UF || n1[side].getKind() == kind::SELECT || n1[side].getKind() == kind::STORE) {
+ if(n1[side].getKind() == kind::APPLY_UF || n1[side].getKind() == kind::PARTIAL_APPLY_UF) {
+ b1 << n1[side].getOperator();
+ } else {
+ b1 << ProofManager::currentPM()->mkOp(n1[side].getOperator());
+ }
+ b1.append(n1[side].begin(), n1[side].end());
+ } else {
+ b1 << n1[side];
+ }
+ if(n1[1-side].getKind() == kind::PARTIAL_APPLY_UF || n1[1-side].getKind() == kind::APPLY_UF || n1[side].getKind() == kind::SELECT || n1[side].getKind() == kind::STORE) {
+ if(n1[1-side].getKind() == kind::PARTIAL_APPLY_UF || n1[1-side].getKind() == kind::APPLY_UF) {
+ b2 << n1[1-side].getOperator();
+ } else {
+ b2 << ProofManager::currentPM()->mkOp(n1[1-side].getOperator());
+ }
+ b2.append(n1[1-side].begin(), n1[1-side].end());
+ } else {
+ b2 << n1[1-side];
+ }
+ Debug("pf::arith") << "pf2->d_node " << pf2->d_node << std::endl;
+ Debug("pf::arith") << "b1.getNumChildren() " << b1.getNumChildren() << std::endl;
+ Debug("pf::arith") << "n1 " << n1 << std::endl;
+ Debug("pf::arith") << "n2 " << n2 << std::endl;
+ Debug("pf::arith") << "side " << side << std::endl;
+ if(pf2->d_node[b1.getNumChildren() - (pf2->d_node.getMetaKind() == kind::metakind::PARAMETERIZED ? 0 : 1)] == n2[side]) {
+ b1 << n2[side];
+ b2 << n2[1-side];
+ out << ss.str();
+ } else {
+ Assert(pf2->d_node[b1.getNumChildren() - (pf2->d_node.getMetaKind() == kind::metakind::PARAMETERIZED ? 0 : 1)] == n2[1-side]);
+ b1 << n2[1-side];
+ b2 << n2[side];
+ out << "(symm _ _ _ " << ss.str() << ")";
+ }
+ out << ")";
+ while(!stk.empty()) {
+ if(tb == 1) {
+ Debug("pf::arith") << "\nMORE TO DO\n";
+ }
+ pf2 = stk.top();
+ stk.pop();
+ Assert(pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE);
+ out << " ";
+ ss.str("");
+ n2 = toStreamRecLFSC(ss, tp, pf2->d_children[1], tb + 1, map);
+ Debug("pf::arith") << "\nok, in cong[" << stk.size() << "]" << "\n";
+ Debug("pf::arith") << "looking at " << pf2->d_node << "\n";
+ Debug("pf::arith") << " " << n1 << "\n";
+ Debug("pf::arith") << " " << n2 << "\n";
+ Debug("pf::arith") << " " << b1 << "\n";
+ Debug("pf::arith") << " " << b2 << "\n";
+ if(pf2->d_node[b1.getNumChildren()] == n2[side]) {
+ b1 << n2[side];
+ b2 << n2[1-side];
+ out << ss.str();
+ } else {
+ Assert(pf2->d_node[b1.getNumChildren()] == n2[1-side]);
+ b1 << n2[1-side];
+ b2 << n2[side];
+ out << "(symm _ _ _ " << ss.str() << ")";
+ }
+ out << ")";
+ }
+ n1 = b1;
+ n2 = b2;
+ Debug("pf::arith") << "at end assert, got " << pf2->d_node << " and " << n1 << std::endl;
+ if(pf2->d_node.getKind() == kind::PARTIAL_APPLY_UF) {
+ Assert(n1 == pf2->d_node);
+ }
+ if(n1.getOperator().getType().getNumChildren() == n1.getNumChildren() + 1) {
+ if(ProofManager::currentPM()->hasOp(n1.getOperator())) {
+ b1.clear(ProofManager::currentPM()->lookupOp(n2.getOperator()).getConst<Kind>());
+ } else {
+ b1.clear(kind::APPLY_UF);
+ b1 << n1.getOperator();
+ }
+ b1.append(n1.begin(), n1.end());
+ n1 = b1;
+ Debug("pf::arith") << "at[2] end assert, got " << pf2->d_node << " and " << n1 << std::endl;
+ if(pf2->d_node.getKind() == kind::APPLY_UF) {
+ Assert(n1 == pf2->d_node);
+ }
+ }
+ if(n2.getOperator().getType().getNumChildren() == n2.getNumChildren() + 1) {
+ if(ProofManager::currentPM()->hasOp(n2.getOperator())) {
+ b2.clear(ProofManager::currentPM()->lookupOp(n2.getOperator()).getConst<Kind>());
+ } else {
+ b2.clear(kind::APPLY_UF);
+ b2 << n2.getOperator();
+ }
+ b2.append(n2.begin(), n2.end());
+ n2 = b2;
+ }
+ Node n = (side == 0 ? eqNode(n1, n2) : eqNode(n2, n1));
+ if(tb == 1) {
+ Debug("pf::arith") << "\ncong proved: " << n << "\n";
+ }
+ return n;
+ }
+
+ case theory::eq::MERGED_THROUGH_REFLEXIVITY:
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.empty());
+ out << "(refl _ ";
+ tp->printTerm(NodeManager::currentNM()->toExpr(pf->d_node), out, map);
+ out << ")";
+ return eqNode(pf->d_node, pf->d_node);
+
+ case theory::eq::MERGED_THROUGH_EQUALITY:
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.empty());
+ out << ProofManager::getLitName(pf->d_node.negate());
+ return pf->d_node;
+
+ case theory::eq::MERGED_THROUGH_TRANS: {
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.size() >= 2);
+ std::stringstream ss;
+ Debug("pf::arith") << "\ndoing trans proof[[\n";
+ pf->debug_print("pf::arith");
+ Debug("pf::arith") << "\n";
+ Node n1 = toStreamRecLFSC(ss, tp, pf->d_children[0], tb + 1, map);
+ Debug("pf::arith") << "\ndoing trans proof, got n1 " << n1 << "\n";
+ if(tb == 1) {
+ Debug("pf::arith") << "\ntrans proof[0], got n1 " << n1 << "\n";
+ }
+
+ bool identicalEqualities = false;
+ bool evenLengthSequence;
+ Node nodeAfterEqualitySequence;
+
+ std::map<size_t, Node> childToStream;
+
+ for(size_t i = 1; i < pf->d_children.size(); ++i) {
+ std::stringstream ss1(ss.str()), ss2;
+ ss.str("");
+
+ // It is possible that we've already converted the i'th child to stream. If so,
+ // use previously stored result. Otherwise, convert and store.
+ Node n2;
+ if (childToStream.find(i) != childToStream.end())
+ n2 = childToStream[i];
+ else {
+ n2 = toStreamRecLFSC(ss2, tp, pf->d_children[i], tb + 1, map);
+ childToStream[i] = n2;
+ }
+
+ // The following branch is dedicated to handling sequences of identical equalities,
+ // i.e. trans[ a=b, a=b, a=b ].
+ //
+ // There are two cases:
+ // 1. The number of equalities is odd. Then, the sequence can be collapsed to just one equality,
+ // i.e. a=b.
+ // 2. The number of equalities is even. Now, we have two options: a=a or b=b. To determine this,
+ // we look at the node after the equality sequence. If it needs a, we go for a=a; and if it needs
+ // b, we go for b=b. If there is no following node, we look at the goal of the transitivity proof,
+ // and use it to determine which option we need.
+ if(n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) {
+ if (((n1[0] == n2[0]) && (n1[1] == n2[1])) || ((n1[0] == n2[1]) && (n1[1] == n2[0]))) {
+ // We are in a sequence of identical equalities
+
+ Debug("pf::arith") << "Detected identical equalities: " << std::endl << "\t" << n1 << std::endl;
+
+ if (!identicalEqualities) {
+ // The sequence of identical equalities has started just now
+ identicalEqualities = true;
+
+ Debug("pf::arith") << "The sequence is just beginning. Determining length..." << std::endl;
+
+ // Determine whether the length of this sequence is odd or even.
+ evenLengthSequence = true;
+ bool sequenceOver = false;
+ size_t j = i + 1;
+
+ while (j < pf->d_children.size() && !sequenceOver) {
+ std::stringstream dontCare;
+ nodeAfterEqualitySequence = toStreamRecLFSC(dontCare, tp, pf->d_children[j], tb + 1, map );
+
+ if (((nodeAfterEqualitySequence[0] == n1[0]) && (nodeAfterEqualitySequence[1] == n1[1])) ||
+ ((nodeAfterEqualitySequence[0] == n1[1]) && (nodeAfterEqualitySequence[1] == n1[0]))) {
+ evenLengthSequence = !evenLengthSequence;
+ } else {
+ sequenceOver = true;
+ }
+
+ ++j;
+ }
+
+ if (evenLengthSequence) {
+ // If the length is even, we need to apply transitivity for the "correct" hand of the equality.
+
+ Debug("pf::arith") << "Equality sequence of even length" << std::endl;
+ Debug("pf::arith") << "n1 is: " << n1 << std::endl;
+ Debug("pf::arith") << "n2 is: " << n2 << std::endl;
+ Debug("pf::arith") << "pf-d_node is: " << pf->d_node << std::endl;
+ Debug("pf::arith") << "Next node is: " << nodeAfterEqualitySequence << std::endl;
+
+ ss << "(trans _ _ _ _ ";
+
+ // If the sequence is at the very end of the transitivity proof, use pf->d_node to guide us.
+ if (!sequenceOver) {
+ if (match(n1[0], pf->d_node[0])) {
+ n1 = eqNode(n1[0], n1[0]);
+ ss << ss1.str() << " (symm _ _ _ " << ss1.str() << ")";
+ } else if (match(n1[1], pf->d_node[1])) {
+ n1 = eqNode(n1[1], n1[1]);
+ ss << " (symm _ _ _ " << ss1.str() << ")" << ss1.str();
+ } else {
+ Debug("pf::arith") << "Error: identical equalities over, but hands don't match what we're proving."
+ << std::endl;
+ Assert(false);
+ }
+ } else {
+ // We have a "next node". Use it to guide us.
+
+ Assert(nodeAfterEqualitySequence.getKind() == kind::EQUAL ||
+ nodeAfterEqualitySequence.getKind() == kind::IFF);
+
+ if ((n1[0] == nodeAfterEqualitySequence[0]) || (n1[0] == nodeAfterEqualitySequence[1])) {
+
+ // Eliminate n1[1]
+ ss << ss1.str() << " (symm _ _ _ " << ss1.str() << ")";
+ n1 = eqNode(n1[0], n1[0]);
+
+ } else if ((n1[1] == nodeAfterEqualitySequence[0]) || (n1[1] == nodeAfterEqualitySequence[1])) {
+
+ // Eliminate n1[0]
+ ss << " (symm _ _ _ " << ss1.str() << ")" << ss1.str();
+ n1 = eqNode(n1[1], n1[1]);
+
+ } else {
+ Debug("pf::arith") << "Error: even length sequence, but I don't know which hand to keep!" << std::endl;
+ Assert(false);
+ }
+ }
+
+ ss << ")";
+
+ } else {
+ Debug("pf::arith") << "Equality sequence length is odd!" << std::endl;
+ ss.str(ss1.str());
+ }
+
+ Debug("pf::arith") << "Have proven: " << n1 << std::endl;
+ } else {
+ ss.str(ss1.str());
+ }
+
+ // Ignore the redundancy.
+ continue;
+ }
+ }
+
+ if (identicalEqualities) {
+ // We were in a sequence of identical equalities, but it has now ended. Resume normal operation.
+ identicalEqualities = false;
+ }
+
+ Debug("pf::arith") << "\ndoing trans proof, got n2 " << n2 << "\n";
+ if(tb == 1) {
+ Debug("pf::arith") << "\ntrans proof[" << i << "], got n2 " << n2 << "\n";
+ Debug("pf::arith") << (n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) << "\n";
+
+ if ((n1.getNumChildren() >= 2) && (n2.getNumChildren() >= 2)) {
+ Debug("pf::arith") << n1[0].getId() << " " << n1[1].getId() << " / " << n2[0].getId() << " " << n2[1].getId() << "\n";
+ Debug("pf::arith") << n1[0].getId() << " " << n1[0] << "\n";
+ Debug("pf::arith") << n1[1].getId() << " " << n1[1] << "\n";
+ Debug("pf::arith") << n2[0].getId() << " " << n2[0] << "\n";
+ Debug("pf::arith") << n2[1].getId() << " " << n2[1] << "\n";
+ Debug("pf::arith") << (n1[0] == n2[0]) << "\n";
+ Debug("pf::arith") << (n1[1] == n2[1]) << "\n";
+ Debug("pf::arith") << (n1[0] == n2[1]) << "\n";
+ Debug("pf::arith") << (n1[1] == n2[0]) << "\n";
+ }
+ }
+ ss << "(trans _ _ _ _ ";
+
+ if((n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) &&
+ (n1.getKind() == kind::EQUAL || n1.getKind() == kind::IFF))
+ // Both elements of the transitivity rule are equalities/iffs
+ {
+ if(n1[0] == n2[0]) {
+ if(tb == 1) { Debug("pf::arith") << "case 1\n"; }
+ n1 = eqNode(n1[1], n2[1]);
+ ss << "(symm _ _ _ " << ss1.str() << ") " << ss2.str();
+ } else if(n1[1] == n2[1]) {
+ if(tb == 1) { Debug("pf::arith") << "case 2\n"; }
+ n1 = eqNode(n1[0], n2[0]);
+ ss << ss1.str() << " (symm _ _ _ " << ss2.str() << ")";
+ } else if(n1[0] == n2[1]) {
+ if(tb == 1) { Debug("pf::arith") << "case 3\n"; }
+ n1 = eqNode(n2[0], n1[1]);
+ ss << ss2.str() << " " << ss1.str();
+ if(tb == 1) { Debug("pf::arith") << "++ proved " << n1 << "\n"; }
+ } else if(n1[1] == n2[0]) {
+ if(tb == 1) { Debug("pf::arith") << "case 4\n"; }
+ n1 = eqNode(n1[0], n2[1]);
+ ss << ss1.str() << " " << ss2.str();
+ } else {
+ Warning() << "\n\ntrans proof failure at step " << i << "\n\n";
+ Warning() << "0 proves " << n1 << "\n";
+ Warning() << "1 proves " << n2 << "\n\n";
+ pf->debug_print("pf::arith",0);
+ //toStreamRec(Warning.getStream(), pf, 0);
+ Warning() << "\n\n";
+ Unreachable();
+ }
+ Debug("pf::arith") << "++ trans proof[" << i << "], now have " << n1 << std::endl;
+ } else if(n1.getKind() == kind::EQUAL || n1.getKind() == kind::IFF) {
+ // n1 is an equality/iff, but n2 is a predicate
+ if(n1[0] == n2) {
+ n1 = n1[1];
+ ss << "(symm _ _ _ " << ss1.str() << ") (pred_eq_t _ " << ss2.str() << ")";
+ } else if(n1[1] == n2) {
+ n1 = n1[0];
+ ss << ss1.str() << " (pred_eq_t _ " << ss2.str() << ")";
+ } else {
+ Unreachable();
+ }
+ } else if(n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) {
+ // n2 is an equality/iff, but n1 is a predicate
+ if(n2[0] == n1) {
+ n1 = n2[1];
+ ss << "(symm _ _ _ " << ss2.str() << ") (pred_eq_t _ " << ss1.str() << ")";
+ } else if(n2[1] == n1) {
+ n1 = n2[0];
+ ss << ss2.str() << " (pred_eq_t _ " << ss1.str() << ")";
+ } else {
+ Unreachable();
+ }
+ } else {
+ // Both n1 and n2 are prediacates. Don't know what to do...
+ Unreachable();
+ }
+
+ ss << ")";
+ }
+ out << ss.str();
+ Debug("pf::arith") << "\n++ trans proof done, have proven " << n1 << std::endl;
+ return n1;
+ }
+
+ default:
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.empty());
+ Debug("pf::arith") << "theory proof: " << pf->d_node << " by rule " << int(pf->d_id) << std::endl;
+ AlwaysAssert(false);
+ return pf->d_node;
+ }
+}
+
+ArithProof::ArithProof(theory::arith::TheoryArith* arith, TheoryProofEngine* pe)
+ : TheoryProof(arith, pe), d_realMode(false)
+{}
+
+void ArithProof::registerTerm(Expr term) {
+ Debug("pf::arith") << "Arith register term: " << term << ". Kind: " << term.getKind()
+ << ". Type: " << term.getType() << std::endl;
+
+ if (term.getType().isReal() && !term.getType().isInteger()) {
+ Debug("pf::arith") << "Entering real mode" << std::endl;
+ d_realMode = true;
+ }
+
+ // recursively declare all other terms
+ for (unsigned i = 0; i < term.getNumChildren(); ++i) {
+ // could belong to other theories
+ d_proofEngine->registerTerm(term[i]);
+ }
+}
+
+void LFSCArithProof::printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) {
+ Debug("pf::arith") << "Arith print term: " << term << ". Kind: " << term.getKind()
+ << ". Type: " << term.getType()
+ << ". Number of children: " << term.getNumChildren() << std::endl;
+
+ // !d_realMode <--> term.getType().isInteger()
+
+ Assert (theory::Theory::theoryOf(term) == theory::THEORY_ARITH);
+ switch (term.getKind()) {
+
+ case kind::CONST_RATIONAL: {
+ Assert (term.getNumChildren() == 0);
+ Assert (term.getType().isInteger() || term.getType().isReal());
+
+ const Rational& r = term.getConst<Rational>();
+ bool neg = (r < 0);
+
+ os << (!d_realMode ? "(a_int " : "(a_real ");
+
+ if (neg) {
+ os << "(~ ";
+ }
+
+ if (!d_realMode) {
+ os << r.abs();
+ } else {
+ os << r.abs().getNumerator();
+ os << "/";
+ os << r.getDenominator();
+ }
+
+ if (neg) {
+ os << ") ";
+ }
+
+ os << ") ";
+ return;
+ }
+
+ case kind::UMINUS: {
+ Assert (term.getNumChildren() == 1);
+ Assert (term.getType().isInteger() || term.getType().isReal());
+ os << (!d_realMode ? "(u-_Int " : "(u-_Real ");
+ d_proofEngine->printBoundTerm(term[0], os, map);
+ os << ") ";
+ return;
+ }
+
+ case kind::PLUS: {
+ Assert (term.getNumChildren() >= 2);
+
+ std::stringstream paren;
+ for (unsigned i = 0; i < term.getNumChildren() - 1; ++i) {
+ os << (!d_realMode ? "(+_Int " : "(+_Real ");
+ d_proofEngine->printBoundTerm(term[i], os, map);
+ os << " ";
+ paren << ") ";
+ }
+
+ d_proofEngine->printBoundTerm(term[term.getNumChildren() - 1], os, map);
+ os << paren.str();
+ return;
+ }
+
+ case kind::MINUS: {
+ Assert (term.getNumChildren() >= 2);
+
+ std::stringstream paren;
+ for (unsigned i = 0; i < term.getNumChildren() - 1; ++i) {
+ os << (!d_realMode ? "(-_Int " : "(-_Real ");
+ d_proofEngine->printBoundTerm(term[i], os, map);
+ os << " ";
+ paren << ") ";
+ }
+
+ d_proofEngine->printBoundTerm(term[term.getNumChildren() - 1], os, map);
+ os << paren.str();
+ return;
+ }
+
+ case kind::MULT: {
+ Assert (term.getNumChildren() >= 2);
+
+ std::stringstream paren;
+ for (unsigned i = 0; i < term.getNumChildren() - 1; ++i) {
+ os << (!d_realMode ? "(*_Int " : "(*_Real ");
+ d_proofEngine->printBoundTerm(term[i], os, map);
+ os << " ";
+ paren << ") ";
+ }
+
+ d_proofEngine->printBoundTerm(term[term.getNumChildren() - 1], os, map);
+ os << paren.str();
+ return;
+ }
+
+ case kind::DIVISION:
+ case kind::DIVISION_TOTAL: {
+ Assert (term.getNumChildren() >= 2);
+
+ std::stringstream paren;
+ for (unsigned i = 0; i < term.getNumChildren() - 1; ++i) {
+ os << (!d_realMode ? "(/_Int " : "(/_Real ");
+ d_proofEngine->printBoundTerm(term[i], os, map);
+ os << " ";
+ paren << ") ";
+ }
+
+ d_proofEngine->printBoundTerm(term[term.getNumChildren() - 1], os, map);
+ os << paren.str();
+ return;
+ }
+
+ case kind::GT:
+ Assert (term.getNumChildren() == 2);
+ os << (!d_realMode ? "(>_Int " : "(>_Real ");
+ d_proofEngine->printBoundTerm(term[0], os, map);
+ os << " ";
+ d_proofEngine->printBoundTerm(term[1], os, map);
+ os << ") ";
+ return;
+
+ case kind::GEQ:
+ Assert (term.getNumChildren() == 2);
+ os << (!d_realMode ? "(>=_Int " : "(>=_Real ");
+ d_proofEngine->printBoundTerm(term[0], os, map);
+ os << " ";
+ d_proofEngine->printBoundTerm(term[1], os, map);
+ os << ") ";
+ return;
+
+ case kind::LT:
+ Assert (term.getNumChildren() == 2);
+ os << (!d_realMode ? "(<_Int " : "(<_Real ");
+ d_proofEngine->printBoundTerm(term[0], os, map);
+ os << " ";
+ d_proofEngine->printBoundTerm(term[1], os, map);
+ os << ") ";
+ return;
+
+ case kind::LEQ:
+ Assert (term.getNumChildren() == 2);
+ os << (!d_realMode ? "(<=_Int " : "(<=_Real ");
+ d_proofEngine->printBoundTerm(term[0], os, map);
+ os << " ";
+ d_proofEngine->printBoundTerm(term[1], os, map);
+ os << ") ";
+ return;
+
+ default:
+ Debug("pf::arith") << "Default printing of term: " << term << std::endl;
+ os << term;
+ return;
+ }
+}
+
+void LFSCArithProof::printOwnedSort(Type type, std::ostream& os) {
+ Debug("pf::arith") << "Arith print sort: " << type << std::endl;
+
+ if (type.isInteger() && d_realMode) {
+ // If in "real mode", don't use type Int for, e.g., equality.
+ os << "Real ";
+ } else {
+ os << type << " ";
+ }
+}
+
+void LFSCArithProof::printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren) {
+ os << " ;; Arith Theory Lemma \n;;";
+ for (unsigned i = 0; i < lemma.size(); ++i) {
+ os << lemma[i] <<" ";
+ }
+ os <<"\n";
+ //os << " (clausify_false trust)";
+ ArithProof::printTheoryLemmaProof( lemma, os, paren );
+}
+
+void LFSCArithProof::printSortDeclarations(std::ostream& os, std::ostream& paren) {
+}
+
+void LFSCArithProof::printTermDeclarations(std::ostream& os, std::ostream& paren) {
+}
+
+void LFSCArithProof::printDeferredDeclarations(std::ostream& os, std::ostream& paren) {
+ // Nothing to do here at this point.
+}
+
+} /* CVC4 namespace */
diff --git a/src/proof/arith_proof.h b/src/proof/arith_proof.h
new file mode 100644
index 000000000..788e4bd86
--- /dev/null
+++ b/src/proof/arith_proof.h
@@ -0,0 +1,82 @@
+/********************* */
+/*! \file arith_proof.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Arith proof
+ **
+ ** Arith proof
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__ARITH__PROOF_H
+#define __CVC4__ARITH__PROOF_H
+
+#include "expr/expr.h"
+#include "proof/proof_manager.h"
+#include "proof/theory_proof.h"
+#include "theory/uf/equality_engine.h"
+
+namespace CVC4 {
+
+//proof object outputted by TheoryArith
+class ProofArith : public Proof {
+private:
+ static Node toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, unsigned tb, const LetMap& map);
+public:
+ ProofArith( theory::eq::EqProof * pf ) : d_proof( pf ) {}
+ //it is simply an equality engine proof
+ theory::eq::EqProof * d_proof;
+ void toStream(std::ostream& out);
+ static void toStreamLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, const LetMap& map);
+};
+
+
+namespace theory {
+namespace arith {
+class TheoryArith;
+}
+}
+
+typedef __gnu_cxx::hash_set<Type, TypeHashFunction > TypeSet;
+
+
+class ArithProof : public TheoryProof {
+protected:
+ // std::map<Expr, std::string> d_constRationalString; // all the variable/function declarations
+
+ // TypeSet d_sorts; // all the uninterpreted sorts in this theory
+ // ExprSet d_declarations; // all the variable/function declarations
+
+ bool d_realMode;
+
+public:
+ ArithProof(theory::arith::TheoryArith* arith, TheoryProofEngine* proofEngine);
+
+ virtual void registerTerm(Expr term);
+};
+
+class LFSCArithProof : public ArithProof {
+public:
+ LFSCArithProof(theory::arith::TheoryArith* arith, TheoryProofEngine* proofEngine)
+ : ArithProof(arith, proofEngine)
+ {}
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map);
+ virtual void printOwnedSort(Type type, std::ostream& os);
+ virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren);
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren);
+};
+
+
+}/* CVC4 namespace */
+
+#endif /* __CVC4__ARITH__PROOF_H */
diff --git a/src/proof/array_proof.cpp b/src/proof/array_proof.cpp
new file mode 100644
index 000000000..8aba8dce9
--- /dev/null
+++ b/src/proof/array_proof.cpp
@@ -0,0 +1,1269 @@
+/********************* */
+/*! \file array_proof.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
+**/
+
+#include "proof/theory_proof.h"
+#include "proof/proof_manager.h"
+#include "proof/array_proof.h"
+#include "theory/arrays/theory_arrays.h"
+#include <stack>
+
+namespace CVC4 {
+
+inline static Node eqNode(TNode n1, TNode n2) {
+ return NodeManager::currentNM()->mkNode(n1.getType().isBoolean() ? kind::IFF : kind::EQUAL, n1, n2);
+}
+
+// congrence matching term helper
+inline static bool match(TNode n1, TNode n2) {
+ Debug("mgd") << "match " << n1 << " " << n2 << std::endl;
+ if(ProofManager::currentPM()->hasOp(n1)) {
+ n1 = ProofManager::currentPM()->lookupOp(n1);
+ }
+ if(ProofManager::currentPM()->hasOp(n2)) {
+ n2 = ProofManager::currentPM()->lookupOp(n2);
+ }
+ Debug("mgd") << "+ match " << n1 << " " << n2 << std::endl;
+ Debug("pf::array") << "+ match: step 1" << std::endl;
+ if(n1 == n2) {
+ return true;
+ }
+
+ if(n1.getType().isFunction() && n2.hasOperator()) {
+ if(ProofManager::currentPM()->hasOp(n2.getOperator())) {
+ return n1 == ProofManager::currentPM()->lookupOp(n2.getOperator());
+ } else {
+ return n1 == n2.getOperator();
+ }
+ }
+
+ if(n2.getType().isFunction() && n1.hasOperator()) {
+ if(ProofManager::currentPM()->hasOp(n1.getOperator())) {
+ return n2 == ProofManager::currentPM()->lookupOp(n1.getOperator());
+ } else {
+ return n2 == n1.getOperator();
+ }
+ }
+
+ if(n1.hasOperator() && n2.hasOperator() && n1.getOperator() != n2.getOperator()) {
+ if (!((n1.getKind() == kind::SELECT && n2.getKind() == kind::PARTIAL_SELECT_0) ||
+ (n1.getKind() == kind::SELECT && n2.getKind() == kind::PARTIAL_SELECT_1) ||
+ (n1.getKind() == kind::PARTIAL_SELECT_1 && n2.getKind() == kind::SELECT) ||
+ (n1.getKind() == kind::PARTIAL_SELECT_1 && n2.getKind() == kind::PARTIAL_SELECT_0) ||
+ (n1.getKind() == kind::PARTIAL_SELECT_0 && n2.getKind() == kind::SELECT) ||
+ (n1.getKind() == kind::PARTIAL_SELECT_0 && n2.getKind() == kind::PARTIAL_SELECT_1)
+ )) {
+ return false;
+ }
+ }
+
+ for(size_t i = 0; i < n1.getNumChildren() && i < n2.getNumChildren(); ++i) {
+ if(n1[i] != n2[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void ProofArray::setRowMergeTag(unsigned tag) {
+ d_reasonRow = tag;
+}
+
+void ProofArray::setRow1MergeTag(unsigned tag) {
+ d_reasonRow1 = tag;
+}
+
+void ProofArray::setExtMergeTag(unsigned tag) {
+ d_reasonExt = tag;
+}
+
+void ProofArray::toStream(std::ostream& out) {
+ Trace("pf::array") << "; Print Array proof..." << std::endl;
+ //AJR : carry this further?
+ LetMap map;
+ toStreamLFSC(out, ProofManager::getArrayProof(), d_proof, map);
+ Debug("pf::array") << "; Print Array proof done!" << std::endl;
+}
+
+void ProofArray::toStreamLFSC(std::ostream& out, TheoryProof* tp, theory::eq::EqProof* pf, const LetMap& map) {
+ Debug("pf::array") << "Printing array proof in LFSC : " << std::endl;
+ pf->debug_print("pf::array");
+ Debug("pf::array") << std::endl;
+ toStreamRecLFSC( out, tp, pf, 0, map );
+ Debug("pf::array") << "Printing array proof in LFSC DONE" << std::endl;
+}
+
+Node ProofArray::toStreamRecLFSC(std::ostream& out,
+ TheoryProof* tp,
+ theory::eq::EqProof* pf,
+ unsigned tb,
+ const LetMap& map) {
+
+ Debug("pf::array") << std::endl << std::endl << "toStreamRecLFSC called. tb = " << tb << " . proof:" << std::endl;
+ pf->debug_print("pf::array");
+ Debug("pf::array") << std::endl;
+
+ if(tb == 0) {
+ Assert(pf->d_id == theory::eq::MERGED_THROUGH_TRANS);
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.size() >= 2);
+
+ int neg = -1;
+ theory::eq::EqProof subTrans;
+ subTrans.d_id = theory::eq::MERGED_THROUGH_TRANS;
+ subTrans.d_node = pf->d_node;
+
+ size_t i = 0;
+ while (i < pf->d_children.size()) {
+ // Look for the negative clause, with which we will form a contradiction.
+ if(!pf->d_children[i]->d_node.isNull() && pf->d_children[i]->d_node.getKind() == kind::NOT) {
+ Assert(neg < 0);
+ neg = i;
+ ++i;
+ }
+
+ // Handle congruence closures over equalities.
+ else if (pf->d_children[i]->d_id==theory::eq::MERGED_THROUGH_CONGRUENCE && pf->d_children[i]->d_node.isNull()) {
+ Debug("pf::array") << "Handling congruence over equalities" << std::endl;
+
+ // Gather the sequence of consecutive congruence closures.
+ std::vector<const theory::eq::EqProof *> congruenceClosures;
+ unsigned count;
+ Debug("pf::array") << "Collecting congruence sequence" << std::endl;
+ for (count = 0;
+ i + count < pf->d_children.size() &&
+ pf->d_children[i + count]->d_id==theory::eq::MERGED_THROUGH_CONGRUENCE &&
+ pf->d_children[i + count]->d_node.isNull();
+ ++count) {
+ Debug("pf::array") << "Found a congruence: " << std::endl;
+ pf->d_children[i+count]->debug_print("pf::array");
+ congruenceClosures.push_back(pf->d_children[i+count]);
+ }
+
+ Debug("pf::array") << "Total number of congruences found: " << congruenceClosures.size() << std::endl;
+
+ // Determine if the "target" of the congruence sequence appears right before or right after the sequence.
+ bool targetAppearsBefore = true;
+ bool targetAppearsAfter = true;
+
+ if ((i == 0) || (i == 1 && neg == 0)) {
+ Debug("pf::array") << "Target does not appear before" << std::endl;
+ targetAppearsBefore = false;
+ }
+
+ if ((i + count >= pf->d_children.size()) ||
+ (!pf->d_children[i + count]->d_node.isNull() &&
+ pf->d_children[i + count]->d_node.getKind() == kind::NOT)) {
+ Debug("pf::array") << "Target does not appear after" << std::endl;
+ targetAppearsAfter = false;
+ }
+
+ // Assert that we have precisely one target clause.
+ Assert(targetAppearsBefore != targetAppearsAfter);
+
+ // Begin breaking up the congruences and ordering the equalities correctly.
+ std::vector<theory::eq::EqProof *> orderedEqualities;
+
+ // Insert target clause first.
+ if (targetAppearsBefore) {
+ orderedEqualities.push_back(pf->d_children[i - 1]);
+ // The target has already been added to subTrans; remove it.
+ subTrans.d_children.pop_back();
+ } else {
+ orderedEqualities.push_back(pf->d_children[i + count]);
+ }
+
+ // Start with the congruence closure closest to the target clause, and work our way back/forward.
+ if (targetAppearsBefore) {
+ for (unsigned j = 0; j < count; ++j) {
+ if (pf->d_children[i + j]->d_children[0]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.begin(), pf->d_children[i + j]->d_children[0]);
+ if (pf->d_children[i + j]->d_children[1]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.end(), pf->d_children[i + j]->d_children[1]);
+ }
+ } else {
+ for (unsigned j = 0; j < count; ++j) {
+ if (pf->d_children[i + count - 1 - j]->d_children[0]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.begin(), pf->d_children[i + count - 1 - j]->d_children[0]);
+ if (pf->d_children[i + count - 1 - j]->d_children[1]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
+ orderedEqualities.insert(orderedEqualities.end(), pf->d_children[i + count - 1 - j]->d_children[1]);
+ }
+ }
+
+ // Copy the result into the main transitivity proof.
+ subTrans.d_children.insert(subTrans.d_children.end(), orderedEqualities.begin(), orderedEqualities.end());
+
+ // Increase i to skip over the children that have been processed.
+ i += count;
+ if (targetAppearsAfter) {
+ ++i;
+ }
+ }
+
+ // Else, just copy the child proof as is
+ else {
+ subTrans.d_children.push_back(pf->d_children[i]);
+ ++i;
+ }
+ }
+ Assert(neg >= 0);
+
+ Node n1;
+ std::stringstream ss, ss2;
+ //Assert(subTrans.d_children.size() == pf->d_children.size() - 1);
+ Debug("mgdx") << "\nsubtrans has " << subTrans.d_children.size() << " children\n";
+ if(pf->d_children.size() > 2) {
+ n1 = toStreamRecLFSC(ss, tp, &subTrans, 1, map);
+ } else {
+ n1 = toStreamRecLFSC(ss, tp, subTrans.d_children[0], 1, map);
+ Debug("mgdx") << "\nsubTrans unique child " << subTrans.d_children[0]->d_id << " was proven\ngot: " << n1 << std::endl;
+ }
+
+ Node n2 = pf->d_children[neg]->d_node;
+ Assert(n2.getKind() == kind::NOT);
+ Debug("mgdx") << "\nhave proven: " << n1 << std::endl;
+ Debug("mgdx") << "n2 is " << n2 << std::endl;
+ Debug("mgdx") << "n2->d_id is " << pf->d_children[neg]->d_id << std::endl;
+ Debug("mgdx") << "n2[0] is " << n2[0] << std::endl;
+
+ if (n2[0].getNumChildren() > 0) { Debug("mgdx") << "\nn2[0]: " << n2[0][0] << std::endl; }
+ if (n1.getNumChildren() > 1) { Debug("mgdx") << "n1[1]: " << n1[1] << std::endl; }
+
+ if (pf->d_children[neg]->d_id == d_reasonExt) {
+ // The negative node was created by an EXT rule; e.g. it is a[k]!=b[k], due to a!=b.
+
+ // (clausify_false (contra _ .gl2 (or_elim_1 _ _ .gl1 FIXME))))))) (\ .glemc6
+
+ out << "(clausify_false (contra _ ";
+ out << ss.str();
+
+ toStreamRecLFSC(ss2, tp, pf->d_children[neg], 1, map);
+
+ out << " ";
+ out << ss2.str();
+ out << "))";
+
+ } else {
+ // The negative node is, e.g., a pure equality
+ out << "(clausify_false (contra _ ";
+
+ if(n2[0].getKind() == kind::APPLY_UF) {
+ out << "(trans _ _ _ _ ";
+ out << "(symm _ _ _ ";
+ out << ss.str();
+ out << ") (pred_eq_f _ " << ProofManager::getLitName(n2[0]) << ")) t_t_neq_f))" << std::endl;
+ } else {
+ Assert((n1[0] == n2[0][0] && n1[1] == n2[0][1]) || (n1[1] == n2[0][0] && n1[0] == n2[0][1]));
+ if(n1[1] == n2[0][0]) {
+ out << "(symm _ _ _ " << ss.str() << ")";
+ } else {
+ out << ss.str();
+ }
+ Debug("pf::array") << "ArrayProof::toStream: getLitName( " << n2[0] << " ) = " <<
+ ProofManager::getLitName(n2[0]) << std::endl;
+
+ out << " " << ProofManager::getLitName(n2[0]) << "))" << std::endl;
+ }
+ }
+
+ return Node();
+ }
+
+ if (pf->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE) {
+ Debug("mgd") << "\nok, looking at congruence:\n";
+ pf->debug_print("mgd");
+ std::stack<const theory::eq::EqProof*> stk;
+ for(const theory::eq::EqProof* pf2 = pf; pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE; pf2 = pf2->d_children[0]) {
+ Assert(!pf2->d_node.isNull());
+ Assert(pf2->d_node.getKind() == kind::PARTIAL_APPLY_UF ||
+ pf2->d_node.getKind() == kind::BUILTIN ||
+ pf2->d_node.getKind() == kind::APPLY_UF ||
+ pf2->d_node.getKind() == kind::SELECT ||
+ pf2->d_node.getKind() == kind::PARTIAL_SELECT_0 ||
+ pf2->d_node.getKind() == kind::PARTIAL_SELECT_1 ||
+ pf2->d_node.getKind() == kind::STORE);
+
+ Assert(pf2->d_children.size() == 2);
+ out << "(cong _ _ _ _ _ _ ";
+ stk.push(pf2);
+ }
+ Assert(stk.top()->d_children[0]->d_id != theory::eq::MERGED_THROUGH_CONGRUENCE);
+ // NodeBuilder<> b1(kind::PARTIAL_APPLY_UF), b2(kind::PARTIAL_APPLY_UF);
+ NodeBuilder<> b1, b2;
+
+ const theory::eq::EqProof* pf2 = stk.top();
+ stk.pop();
+ Assert(pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE);
+ Node n1 = toStreamRecLFSC(out, tp, pf2->d_children[0], tb + 1, map);
+ out << " ";
+ std::stringstream ss;
+ Node n2 = toStreamRecLFSC(ss, tp, pf2->d_children[1], tb + 1, map);
+
+
+ Debug("mgd") << "\nok, in FIRST cong[" << stk.size() << "]" << "\n";
+ pf2->debug_print("mgd");
+ // Temp
+ Debug("mgd") << "n1 is a proof for: " << pf2->d_children[0]->d_node << ". It is: " << n1 << std::endl;
+ Debug("mgd") << "n2 is a proof for: " << pf2->d_children[1]->d_node << ". It is: " << n2 << std::endl;
+ //
+ Debug("mgd") << "looking at " << pf2->d_node << "\n";
+ Debug("mgd") << " " << n1 << "\n";
+ Debug("mgd") << " " << n2 << "\n";
+
+ int side = 0;
+ if(match(pf2->d_node, n1[0])) {
+ Debug("mgd") << "SIDE IS 0\n";
+ side = 0;
+ } else {
+ Debug("mgd") << "SIDE IS 1\n";
+ if(!match(pf2->d_node, n1[1])) {
+ Debug("mgd") << "IN BAD CASE, our first subproof is\n";
+ pf2->d_children[0]->debug_print("mgd");
+ }
+ Assert(match(pf2->d_node, n1[1]));
+ side = 1;
+ }
+
+ if(n1[side].getKind() == kind::APPLY_UF ||
+ n1[side].getKind() == kind::PARTIAL_APPLY_UF ||
+ n1[side].getKind() == kind::SELECT ||
+ n1[side].getKind() == kind::PARTIAL_SELECT_1 ||
+ n1[side].getKind() == kind::STORE) {
+ if(n1[side].getKind() == kind::APPLY_UF || n1[side].getKind() == kind::PARTIAL_APPLY_UF) {
+ b1 << kind::PARTIAL_APPLY_UF;
+ b1 << n1[side].getOperator();
+ } else if (n1[side].getKind() == kind::SELECT || n1[side].getKind() == kind::PARTIAL_SELECT_1) {
+ // b1 << n1[side].getKind();
+ b1 << kind::SELECT;
+ } else {
+ b1 << kind::PARTIAL_APPLY_UF;
+ b1 << ProofManager::currentPM()->mkOp(n1[side].getOperator());
+ }
+ b1.append(n1[side].begin(), n1[side].end());
+ }
+ else if (n1[side].getKind() == kind::PARTIAL_SELECT_0) {
+ b1 << kind::PARTIAL_SELECT_1;
+ } else {
+ b1 << n1[side];
+ }
+
+ if(n1[1-side].getKind() == kind::PARTIAL_APPLY_UF ||
+ n1[1-side].getKind() == kind::APPLY_UF ||
+ n1[1-side].getKind() == kind::SELECT ||
+ n1[1-side].getKind() == kind::PARTIAL_SELECT_1 ||
+ n1[1-side].getKind() == kind::STORE) {
+ if(n1[1-side].getKind() == kind::APPLY_UF ||
+ n1[1-side].getKind() == kind::PARTIAL_APPLY_UF) {
+ b2 << kind::PARTIAL_APPLY_UF;
+ b2 << n1[1-side].getOperator();
+ } else if (n1[1-side].getKind() == kind::SELECT || n1[1-side].getKind() == kind::PARTIAL_SELECT_1) {
+ // b2 << n1[1-side].getKind();
+ b2 << kind::SELECT;
+ } else {
+ b2 << kind::PARTIAL_APPLY_UF;
+ b2 << ProofManager::currentPM()->mkOp(n1[1-side].getOperator());
+ }
+ b2.append(n1[1-side].begin(), n1[1-side].end());
+ } else if (n1[1-side].getKind() == kind::PARTIAL_SELECT_0) {
+ b2 << kind::PARTIAL_SELECT_1;
+ } else {
+ b2 << n1[1-side];
+ }
+ Debug("mgd") << "pf2->d_node " << pf2->d_node << std::endl;
+ Debug("mgd") << "b1.getNumChildren() " << b1.getNumChildren() << std::endl;
+ Debug("mgd") << "n1 " << n1 << std::endl;
+ Debug("mgd") << "n2 " << n2 << std::endl;
+ // These debug prints can cause a problem if we're constructing a SELECT node and it doesn't have enough
+ // children yet.
+ // Debug("mgd") << "b1 " << b1 << std::endl;
+ // Debug("mgd") << "b2 " << b2 << std::endl;
+ Debug("mgd") << "side " << side << std::endl;
+ Debug("mgd") << "pf2->d_node's number of children: " << pf2->d_node.getNumChildren() << std::endl;
+ Debug("mgd") << "pf2->d_node's meta kind: " << pf2->d_node.getMetaKind() << std::endl;
+ Debug("mgd") << "Is this meta kind considered parameterized? " << (pf2->d_node.getMetaKind() == kind::metakind::PARAMETERIZED) << std::endl;
+
+ if(pf2->d_node[b1.getNumChildren() +
+ (n1[side].getKind() == kind::PARTIAL_SELECT_0 ? 1 : 0) +
+ (n1[side].getKind() == kind::PARTIAL_SELECT_1 ? 1 : 0) -
+ (pf2->d_node.getMetaKind() == kind::metakind::PARAMETERIZED ? 0 : 1)] == n2[side]) {
+ b1 << n2[side];
+ b2 << n2[1-side];
+ out << ss.str();
+ } else {
+ Assert(pf2->d_node[b1.getNumChildren() +
+ (n1[side].getKind() == kind::PARTIAL_SELECT_0 ? 1 : 0) +
+ (n1[side].getKind() == kind::PARTIAL_SELECT_1 ? 1 : 0) -
+ (pf2->d_node.getMetaKind() == kind::metakind::PARAMETERIZED ? 0 : 1)] == n2[1-side]);
+ b1 << n2[1-side];
+ b2 << n2[side];
+ out << "(symm _ _ _ " << ss.str() << ")";
+ }
+
+ Debug("mgd") << "After first insertion:" << std::endl;
+ Debug("mgd") << "b1 " << b1 << std::endl;
+ Debug("mgd") << "b2 " << b2 << std::endl;
+
+ out << ")";
+ while(!stk.empty()) {
+
+ Debug("mgd") << "\nMORE TO DO\n";
+
+ pf2 = stk.top();
+ stk.pop();
+ Assert(pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE);
+ out << " ";
+ ss.str("");
+ n2 = toStreamRecLFSC(ss, tp, pf2->d_children[1], tb + 1, map);
+
+ Debug("mgd") << "\nok, in cong[" << stk.size() << "]" << "\n";
+ Debug("mgd") << "looking at " << pf2->d_node << "\n";
+ Debug("mgd") << " " << n1 << "\n";
+ Debug("mgd") << " " << n2 << "\n";
+ Debug("mgd") << " " << b1 << "\n";
+ Debug("mgd") << " " << b2 << "\n";
+ if(pf2->d_node[b1.getNumChildren()] == n2[side]) {
+ b1 << n2[side];
+ b2 << n2[1-side];
+ out << ss.str();
+ } else {
+ Assert(pf2->d_node[b1.getNumChildren()] == n2[1-side]);
+ b1 << n2[1-side];
+ b2 << n2[side];
+ out << "(symm _ _ _ " << ss.str() << ")";
+ }
+ out << ")";
+ }
+ n1 = b1;
+ n2 = b2;
+
+ Debug("mgd") << "at end assert!" << std::endl
+ << "pf2->d_node = " << pf2->d_node << std::endl
+ << "n1 (assigned from b1) = " << n1 << std::endl
+ << "n2 (assigned from b2) = " << n2 << std::endl;
+
+ if(pf2->d_node.getKind() == kind::PARTIAL_APPLY_UF) {
+ Assert(n1 == pf2->d_node);
+ }
+
+ Debug("mgd") << "n1.getOperator().getType().getNumChildren() = "
+ << n1.getOperator().getType().getNumChildren() << std::endl;
+ Debug("mgd") << "n1.getNumChildren() + 1 = "
+ << n1.getNumChildren() + 1 << std::endl;
+
+ Assert(!((n1.getKind() == kind::PARTIAL_SELECT_0 && n1.getNumChildren() == 2)));
+ if (n1.getKind() == kind::PARTIAL_SELECT_1 && n1.getNumChildren() == 2) {
+ Debug("mgd") << "Finished a SELECT. Updating.." << std::endl;
+ b1.clear(kind::SELECT);
+ b1.append(n1.begin(), n1.end());
+ n1 = b1;
+ Debug("mgd") << "New n1: " << n1 << std::endl;
+ // } else if (n1.getKind() == kind::PARTIAL_SELECT_0 && n1.getNumChildren() == 1) {
+ // Debug("mgd") << "Finished a PARTIAL_SELECT_1. Updating.." << std::endl;
+ // b1.clear(kind::PARTIAL_SELECT_1);
+ // b1.append(n1.begin(), n1.end());
+ // n1 = b1;
+ // Debug("mgd") << "New n1: " << n1 << std::endl;
+ // } else
+ } else if(n1.getOperator().getType().getNumChildren() == n1.getNumChildren() + 1) {
+ if(ProofManager::currentPM()->hasOp(n1.getOperator())) {
+ b1.clear(ProofManager::currentPM()->lookupOp(n2.getOperator()).getConst<Kind>());
+ } else {
+ b1.clear(kind::APPLY_UF);
+ b1 << n1.getOperator();
+ }
+ b1.append(n1.begin(), n1.end());
+ n1 = b1;
+ Debug("mgd") << "at[2] end assert, got " << pf2->d_node << " and " << n1 << std::endl;
+ if(pf2->d_node.getKind() == kind::APPLY_UF) {
+ Assert(n1 == pf2->d_node);
+ }
+ }
+
+ Debug("mgd") << "n2.getOperator().getType().getNumChildren() = "
+ << n2.getOperator().getType().getNumChildren() << std::endl;
+ Debug("mgd") << "n2.getNumChildren() + 1 = "
+ << n2.getNumChildren() + 1 << std::endl;
+
+ Assert(!((n2.getKind() == kind::PARTIAL_SELECT_0 && n2.getNumChildren() == 2)));
+ if (n2.getKind() == kind::PARTIAL_SELECT_1 && n2.getNumChildren() == 2) {
+ Debug("mgd") << "Finished a SELECT. Updating.." << std::endl;
+ b2.clear(kind::SELECT);
+ b2.append(n2.begin(), n2.end());
+ n2 = b2;
+ Debug("mgd") << "New n2: " << n2 << std::endl;
+ // } else if (n2.getKind() == kind::PARTIAL_SELECT_0 && n2.getNumChildren() == 1) {
+ // Debug("mgd") << "Finished a PARTIAL_SELECT_1. Updating.." << std::endl;
+ // b2.clear(kind::PARTIAL_SELECT_1);
+ // b2.append(n2.begin(), n2.end());
+ // n2 = b2;
+ // Debug("mgd") << "New n2: " << n2 << std::endl;
+ // } else
+ } else if(n2.getOperator().getType().getNumChildren() == n2.getNumChildren() + 1) {
+ if(ProofManager::currentPM()->hasOp(n2.getOperator())) {
+ b2.clear(ProofManager::currentPM()->lookupOp(n2.getOperator()).getConst<Kind>());
+ } else {
+ b2.clear(kind::APPLY_UF);
+ b2 << n2.getOperator();
+ }
+ b2.append(n2.begin(), n2.end());
+ n2 = b2;
+ }
+ Node n = (side == 0 ? eqNode(n1, n2) : eqNode(n2, n1));
+
+ Debug("mgdx") << "\ncong proved: " << n << "\n";
+ return n;
+ }
+
+ else if (pf->d_id == theory::eq::MERGED_THROUGH_REFLEXIVITY) {
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.empty());
+ out << "(refl _ ";
+ tp->printTerm(NodeManager::currentNM()->toExpr(pf->d_node), out, map);
+ out << ")";
+ return eqNode(pf->d_node, pf->d_node);
+ }
+
+ else if (pf->d_id == theory::eq::MERGED_THROUGH_EQUALITY) {
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.empty());
+ Debug("pf::array") << "ArrayProof::toStream: getLitName( " << pf->d_node.negate() << " ) = " <<
+ ProofManager::getLitName(pf->d_node.negate()) << std::endl;
+ out << ProofManager::getLitName(pf->d_node.negate());
+ return pf->d_node;
+ }
+
+ else if (pf->d_id == theory::eq::MERGED_THROUGH_TRANS) {
+ bool firstNeg = false;
+ bool secondNeg = false;
+
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.size() >= 2);
+ std::stringstream ss;
+ Debug("mgd") << "\ndoing trans proof[[\n";
+ pf->debug_print("mgd");
+ Debug("mgd") << "\n";
+ Node n1 = toStreamRecLFSC(ss, tp, pf->d_children[0], tb + 1, map);
+ Debug("mgd") << "\ndoing trans proof, got n1 " << n1 << "\n";
+ if(tb == 1) {
+ Debug("mgdx") << "\ntrans proof[0], got n1 " << n1 << "\n";
+ }
+
+ bool identicalEqualities = false;
+ bool evenLengthSequence;
+ Node nodeAfterEqualitySequence;
+
+ std::map<size_t, Node> childToStream;
+
+ for(size_t i = 1; i < pf->d_children.size(); ++i) {
+ std::stringstream ss1(ss.str()), ss2;
+ ss.str("");
+
+ // It is possible that we've already converted the i'th child to stream. If so,
+ // use previously stored result. Otherwise, convert and store.
+ Node n2;
+ if (childToStream.find(i) != childToStream.end())
+ n2 = childToStream[i];
+ else {
+ n2 = toStreamRecLFSC(ss2, tp, pf->d_children[i], tb + 1, map);
+ childToStream[i] = n2;
+ }
+
+ Debug("mgd") << "\ndoing trans proof, got (first) n2 " << n2 << "\n";
+
+ // The following branch is dedicated to handling sequences of identical equalities,
+ // i.e. trans[ a=b, a=b, a=b ].
+ //
+ // There are two cases:
+ // 1. The number of equalities is odd. Then, the sequence can be collapsed to just one equality,
+ // i.e. a=b.
+ // 2. The number of equalities is even. Now, we have two options: a=a or b=b. To determine this,
+ // we look at the node after the equality sequence. If it needs a, we go for a=a; and if it needs
+ // b, we go for b=b. If there is no following node, we look at the goal of the transitivity proof,
+ // and use it to determine which option we need.
+ if(n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) {
+ if (((n1[0] == n2[0]) && (n1[1] == n2[1])) || ((n1[0] == n2[1]) && (n1[1] == n2[0]))) {
+ // We are in a sequence of identical equalities
+
+ Debug("pf::array") << "Detected identical equalities: " << std::endl << "\t" << n1 << std::endl;
+
+ if (!identicalEqualities) {
+ // The sequence of identical equalities has started just now
+ identicalEqualities = true;
+
+ Debug("pf::array") << "The sequence is just beginning. Determining length..." << std::endl;
+
+ // Determine whether the length of this sequence is odd or even.
+ evenLengthSequence = true;
+ bool sequenceOver = false;
+ size_t j = i + 1;
+
+ while (j < pf->d_children.size() && !sequenceOver) {
+ std::stringstream dontCare;
+ nodeAfterEqualitySequence = toStreamRecLFSC(dontCare, tp, pf->d_children[j], tb + 1, map );
+
+ if (((nodeAfterEqualitySequence[0] == n1[0]) && (nodeAfterEqualitySequence[1] == n1[1])) ||
+ ((nodeAfterEqualitySequence[0] == n1[1]) && (nodeAfterEqualitySequence[1] == n1[0]))) {
+ evenLengthSequence = !evenLengthSequence;
+ } else {
+ sequenceOver = true;
+ }
+
+ ++j;
+ }
+
+ if (evenLengthSequence) {
+ // If the length is even, we need to apply transitivity for the "correct" hand of the equality.
+
+ Debug("pf::array") << "Equality sequence of even length" << std::endl;
+ Debug("pf::array") << "n1 is: " << n1 << std::endl;
+ Debug("pf::array") << "n2 is: " << n2 << std::endl;
+ Debug("pf::array") << "pf-d_node is: " << pf->d_node << std::endl;
+ Debug("pf::array") << "Next node is: " << nodeAfterEqualitySequence << std::endl;
+
+ ss << "(trans _ _ _ _ ";
+
+ // If the sequence is at the very end of the transitivity proof, use pf->d_node to guide us.
+ if (!sequenceOver) {
+ if (match(n1[0], pf->d_node[0])) {
+ n1 = eqNode(n1[0], n1[0]);
+ ss << ss1.str() << " (symm _ _ _ " << ss1.str() << ")";
+ } else if (match(n1[1], pf->d_node[1])) {
+ n1 = eqNode(n1[1], n1[1]);
+ ss << " (symm _ _ _ " << ss1.str() << ")" << ss1.str();
+ } else {
+ Debug("pf::array") << "Error: identical equalities over, but hands don't match what we're proving."
+ << std::endl;
+ Assert(false);
+ }
+ } else {
+ // We have a "next node". Use it to guide us.
+ if (nodeAfterEqualitySequence.getKind() == kind::NOT) {
+ nodeAfterEqualitySequence = nodeAfterEqualitySequence[0];
+ }
+
+ Assert(nodeAfterEqualitySequence.getKind() == kind::EQUAL ||
+ nodeAfterEqualitySequence.getKind() == kind::IFF);
+
+ if ((n1[0] == nodeAfterEqualitySequence[0]) || (n1[0] == nodeAfterEqualitySequence[1])) {
+
+ // Eliminate n1[1]
+ ss << ss1.str() << " (symm _ _ _ " << ss1.str() << ")";
+ n1 = eqNode(n1[0], n1[0]);
+
+ } else if ((n1[1] == nodeAfterEqualitySequence[0]) || (n1[1] == nodeAfterEqualitySequence[1])) {
+
+ // Eliminate n1[0]
+ ss << " (symm _ _ _ " << ss1.str() << ")" << ss1.str();
+ n1 = eqNode(n1[1], n1[1]);
+
+ } else {
+ Debug("pf::array") << "Error: even length sequence, but I don't know which hand to keep!" << std::endl;
+ Assert(false);
+ }
+ }
+
+ ss << ")";
+
+ } else {
+ Debug("pf::array") << "Equality sequence length is odd!" << std::endl;
+ ss.str(ss1.str());
+ }
+
+ Debug("pf::array") << "Have proven: " << n1 << std::endl;
+ } else {
+ ss.str(ss1.str());
+ }
+
+ // Ignore the redundancy.
+ continue;
+ }
+ }
+
+ if (identicalEqualities) {
+ // We were in a sequence of identical equalities, but it has now ended. Resume normal operation.
+ identicalEqualities = false;
+ }
+
+ Debug("mgd") << "\ndoing trans proof, got n2 " << n2 << "\n";
+ if(tb == 1) {
+ Debug("mgdx") << "\ntrans proof[" << i << "], got n2 " << n2 << "\n";
+ Debug("mgdx") << (n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) << "\n";
+
+ if ((n1.getNumChildren() >= 2) && (n2.getNumChildren() >= 2)) {
+ Debug("mgdx") << n1[0].getId() << " " << n1[1].getId() << " / " << n2[0].getId() << " " << n2[1].getId() << "\n";
+ Debug("mgdx") << n1[0].getId() << " " << n1[0] << "\n";
+ Debug("mgdx") << n1[1].getId() << " " << n1[1] << "\n";
+ Debug("mgdx") << n2[0].getId() << " " << n2[0] << "\n";
+ Debug("mgdx") << n2[1].getId() << " " << n2[1] << "\n";
+ Debug("mgdx") << (n1[0] == n2[0]) << "\n";
+ Debug("mgdx") << (n1[1] == n2[1]) << "\n";
+ Debug("mgdx") << (n1[0] == n2[1]) << "\n";
+ Debug("mgdx") << (n1[1] == n2[0]) << "\n";
+ }
+ }
+
+ // We can hadnle one of the equalities being negative, but not both
+ Assert((n1.getKind() != kind::NOT) || (n2.getKind() != kind::NOT));
+
+ firstNeg = false;
+ secondNeg = false;
+
+ if (n1.getKind() == kind::NOT) {
+ Debug("mgdx") << "n1 is negative" << std::endl;
+ Debug("pf::array") << "n1 = " << n1 << ", n2 = " << n2 << std::endl;
+ firstNeg = true;
+ ss << "(negtrans1 _ _ _ _ ";
+ n1 = n1[0];
+ } else if (n2.getKind() == kind::NOT) {
+ Debug("mgdx") << "n2 is negative" << std::endl;
+ Debug("pf::array") << "n1 = " << n1 << ", n2 = " << n2 << std::endl;
+ secondNeg = true;
+ ss << "(negtrans2 _ _ _ _ ";
+ n2 = n2[0];
+ } else {
+ ss << "(trans _ _ _ _ ";
+ }
+
+ if((n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) &&
+ (n1.getKind() == kind::EQUAL || n1.getKind() == kind::IFF))
+ // Both elements of the transitivity rule are equalities/iffs
+ {
+ if(n1[0] == n2[0]) {
+ if(tb == 1) { Debug("mgdx") << "case 1\n"; }
+ n1 = eqNode(n1[1], n2[1]);
+ ss << (firstNeg ? "(negsymm _ _ _ " : "(symm _ _ _ ") << ss1.str() << ") " << ss2.str();
+ } else if(n1[1] == n2[1]) {
+ if(tb == 1) { Debug("mgdx") << "case 2\n"; }
+ n1 = eqNode(n1[0], n2[0]);
+ ss << ss1.str() << (secondNeg ? " (negsymm _ _ _ " : " (symm _ _ _ " ) << ss2.str() << ")";
+ } else if(n1[0] == n2[1]) {
+ if(tb == 1) { Debug("mgdx") << "case 3\n"; }
+ if(!firstNeg && !secondNeg) {
+ n1 = eqNode(n2[0], n1[1]);
+ ss << ss2.str() << " " << ss1.str();
+ } else if (firstNeg) {
+ n1 = eqNode(n1[1], n2[0]);
+ ss << " (negsymm _ _ _ " << ss1.str() << ") (symm _ _ _ " << ss2.str() << ")";
+ } else {
+ Assert(secondNeg);
+ n1 = eqNode(n1[1], n2[0]);
+ ss << " (symm _ _ _ " << ss1.str() << ") (negsymm _ _ _ " << ss2.str() << ")";
+ }
+ if(tb == 1) { Debug("mgdx") << "++ proved " << n1 << "\n"; }
+ } else if(n1[1] == n2[0]) {
+ if(tb == 1) { Debug("mgdx") << "case 4\n"; }
+ n1 = eqNode(n1[0], n2[1]);
+ ss << ss1.str() << " " << ss2.str();
+ } else {
+ Warning() << "\n\ntrans proof failure at step " << i << "\n\n";
+ Warning() << "0 proves " << n1 << "\n";
+ Warning() << "1 proves " << n2 << "\n\n";
+ pf->debug_print("mgdx",0);
+ //toStreamRec(Warning.getStream(), pf, 0);
+ Warning() << "\n\n";
+ Unreachable();
+ }
+ Debug("mgd") << "++ trans proof[" << i << "], now have " << n1 << std::endl;
+ } else if(n1.getKind() == kind::EQUAL || n1.getKind() == kind::IFF) {
+ // n1 is an equality/iff, but n2 is a predicate
+ if(n1[0] == n2) {
+ n1 = n1[1];
+ ss << (firstNeg ? "(negsymm _ _ _ " : "(symm _ _ _ ")
+ << ss1.str() << ") (pred_eq_t _ " << ss2.str() << ")";
+ } else if(n1[1] == n2) {
+ n1 = n1[0];
+ ss << ss1.str() << " (pred_eq_t _ " << ss2.str() << ")";
+ } else {
+ Unreachable();
+ }
+ } else if(n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) {
+ // n2 is an equality/iff, but n1 is a predicate
+ if(n2[0] == n1) {
+ n1 = n2[1];
+ ss << (secondNeg ? "(negsymm _ _ _ " : "(symm _ _ _ ")
+ << ss2.str() << ") (pred_eq_t _ " << ss1.str() << ")";
+ } else if(n2[1] == n1) {
+ n1 = n2[0];
+ ss << ss2.str() << " (pred_eq_t _ " << ss1.str() << ")";
+ } else {
+ Unreachable();
+ }
+ } else {
+ // Both n1 and n2 are prediacates. Don't know what to do...
+ Unreachable();
+ }
+
+ ss << ")";
+
+ if (firstNeg || secondNeg) {
+ n1 = (n1.getKind() == kind::NOT) ? n1[0] : n1.notNode();
+ }
+ }
+
+ out << ss.str();
+ Debug("mgd") << "\n++ trans proof done, have proven " << n1 << std::endl;
+ //return (firstNeg || secondNeg) ? n1.notNode() : n1;
+ return n1;
+ }
+
+ else if (pf->d_id == d_reasonRow) {
+ Debug("mgd") << "row lemma: " << pf->d_node << std::endl;
+ Assert(pf->d_node.getKind() == kind::EQUAL);
+
+
+ if (pf->d_node[1].getKind() == kind::SELECT) {
+ // This is the case where ((a[i]:=t)[k] == a[k]), and the sub-proof explains why (i != k).
+ TNode t1, t2, t3, t4;
+ Node ret;
+ if(pf->d_node[1].getKind() == kind::SELECT &&
+ pf->d_node[1][0].getKind() == kind::STORE &&
+ pf->d_node[0].getKind() == kind::SELECT &&
+ pf->d_node[0][0] == pf->d_node[1][0][0] &&
+ pf->d_node[0][1] == pf->d_node[1][1]) {
+ t2 = pf->d_node[1][0][1];
+ t3 = pf->d_node[1][1];
+ t1 = pf->d_node[0][0];
+ t4 = pf->d_node[1][0][2];
+ ret = pf->d_node[1].eqNode(pf->d_node[0]);
+ Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\nt4 " << t4 << "\n";
+ } else {
+ Assert(pf->d_node[0].getKind() == kind::SELECT &&
+ pf->d_node[0][0].getKind() == kind::STORE &&
+ pf->d_node[1].getKind() == kind::SELECT &&
+ pf->d_node[1][0] == pf->d_node[0][0][0] &&
+ pf->d_node[1][1] == pf->d_node[0][1]);
+ t2 = pf->d_node[0][0][1];
+ t3 = pf->d_node[0][1];
+ t1 = pf->d_node[1][0];
+ t4 = pf->d_node[0][0][2];
+ ret = pf->d_node;
+ Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\nt4 " << t4 << "\n";
+ }
+
+ // inner index != outer index
+ // t3 is the outer index
+
+
+ Assert(pf->d_children.size() == 1);
+ std::stringstream ss;
+ Node subproof = toStreamRecLFSC(ss, tp, pf->d_children[0], tb + 1, map);
+
+ out << "(row _ _ ";
+ tp->printTerm(t2.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t3.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t1.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t4.toExpr(), out, map);
+ out << " ";
+
+ Debug("pf::array") << "pf->d_children[0]->d_node is: " << pf->d_children[0]->d_node
+ << ". t3 is: " << t3 << std::endl
+ << "subproof is: " << subproof << std::endl;
+
+ Debug("pf::array") << "Subproof is: " << ss.str() << std::endl;
+
+ if (subproof[0][1] == t3) {
+ Debug("pf::array") << "Dont need symmetry!" << std::endl;
+ out << ss.str();
+ } else {
+ Debug("pf::array") << "Need symmetry!" << std::endl;
+ out << "(negsymm _ _ _ " << ss.str() << ")";
+ }
+
+ out << ")";
+
+ return ret;
+ } else {
+ Debug("pf::array") << "In the case of NEGATIVE ROW" << std::endl;
+
+ Debug("pf::array") << "pf->d_children[0]->d_node is: " << pf->d_children[0]->d_node << std::endl;
+
+ // This is the case where (i == k), and the sub-proof explains why ((a[i]:=t)[k] != a[k])
+
+ // If we wanted to remove the need for "negativerow", we would need to prove i==k using a new satlem. We would:
+ // 1. Create a new satlem.
+ // 2. Assume that i != k
+ // 3. Apply ROW to show that ((a[i]:=t)[k] == a[k])
+ // 4. Contradict this with the fact that ((a[i]:=t)[k] != a[k]), obtaining our contradiction
+
+ TNode t1, t2, t3, t4;
+ Node ret;
+
+ // pf->d_node is an equality, i==k.
+ t1 = pf->d_node[0];
+ t2 = pf->d_node[1];
+
+ // pf->d_children[0]->d_node will have the form: (not (= (select (store a_565 i7 e_566) i1) (select a_565 i1))),
+ // or its symmetrical version.
+
+ unsigned side;
+ if (pf->d_children[0]->d_node[0][0].getKind() == kind::SELECT &&
+ pf->d_children[0]->d_node[0][0][0].getKind() == kind::STORE) {
+ side = 0;
+ } else if (pf->d_children[0]->d_node[0][1].getKind() == kind::SELECT &&
+ pf->d_children[0]->d_node[0][1][0].getKind() == kind::STORE) {
+ side = 1;
+ }
+ else {
+ Unreachable();
+ }
+
+ Debug("pf::array") << "Side is: " << side << std::endl;
+
+ // The array's index and element types will come from the subproof...
+ t3 = pf->d_children[0]->d_node[0][side][0][0];
+ t4 = pf->d_children[0]->d_node[0][side][0][2];
+ ret = pf->d_node;
+
+ Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\nt4 " << t4 << "\n";
+
+ Assert(pf->d_children.size() == 1);
+ std::stringstream ss;
+ Node subproof = toStreamRecLFSC(ss, tp, pf->d_children[0], tb + 1, map);
+
+ Debug("pf::array") << "Subproof is: " << ss.str() << std::endl;
+
+ out << "(negativerow _ _ ";
+ tp->printTerm(t1.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t2.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t3.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t4.toExpr(), out, map);
+ out << " ";
+
+
+ // if (subproof[0][1] == t3) {
+ Debug("pf::array") << "Dont need symmetry!" << std::endl;
+ out << ss.str();
+ // } else {
+ // Debug("pf::array") << "Need symmetry!" << std::endl;
+ // out << "(negsymm _ _ _ " << ss.str() << ")";
+ // }
+
+ out << ")";
+
+ // Unreachable();
+
+ return ret;
+ }
+ }
+
+ else if (pf->d_id == d_reasonRow1) {
+ Debug("mgd") << "row1 lemma: " << pf->d_node << std::endl;
+ Assert(pf->d_node.getKind() == kind::EQUAL);
+ TNode t1, t2, t3;
+ Node ret;
+ if(pf->d_node[1].getKind() == kind::SELECT &&
+ pf->d_node[1][0].getKind() == kind::STORE &&
+ pf->d_node[1][0][1] == pf->d_node[1][1] &&
+ pf->d_node[1][0][2] == pf->d_node[0]) {
+ t1 = pf->d_node[1][0][0];
+ t2 = pf->d_node[1][0][1];
+ t3 = pf->d_node[0];
+ ret = pf->d_node[1].eqNode(pf->d_node[0]);
+ Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\n";
+ } else {
+ Assert(pf->d_node[0].getKind() == kind::SELECT &&
+ pf->d_node[0][0].getKind() == kind::STORE &&
+ pf->d_node[0][0][1] == pf->d_node[0][1] &&
+ pf->d_node[0][0][2] == pf->d_node[1]);
+ t1 = pf->d_node[0][0][0];
+ t2 = pf->d_node[0][0][1];
+ t3 = pf->d_node[1];
+ ret = pf->d_node;
+ Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\n";
+ }
+ out << "(row1 _ _ ";
+ tp->printTerm(t1.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t2.toExpr(), out, map);
+ out << " ";
+ tp->printTerm(t3.toExpr(), out, map);
+ out << ")";
+ return ret;
+ }
+
+ else if (pf->d_id == d_reasonExt) {
+ theory::eq::EqProof *child_proof;
+
+ Assert(pf->d_node.getKind() == kind::NOT);
+ Assert(pf->d_node[0].getKind() == kind::EQUAL);
+ Assert(pf->d_children.size() == 1);
+
+ child_proof = pf->d_children[0];
+ Assert(child_proof->d_node.getKind() == kind::NOT);
+ Assert(child_proof->d_node[0].getKind() == kind::EQUAL);
+
+ Debug("mgd") << "EXT lemma: " << pf->d_node << std::endl;
+
+ TNode t1, t2, t3;
+ t1 = child_proof->d_node[0][0];
+ t2 = child_proof->d_node[0][1];
+ t3 = pf->d_node[0][0][1];
+
+ Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\n";
+
+ out << "(or_elim_1 _ _ ";
+ out << ProofManager::getLitName(child_proof->d_node[0]);
+ out << " ";
+ out << ProofManager::getArrayProof()->skolemToLiteral(t3.toExpr());
+ out << ")";
+
+ return pf->d_node;
+ }
+
+ else {
+ Assert(!pf->d_node.isNull());
+ Assert(pf->d_children.empty());
+ Debug("mgd") << "theory proof: " << pf->d_node << " by rule " << int(pf->d_id) << std::endl;
+ AlwaysAssert(false);
+ return pf->d_node;
+ }
+}
+
+ArrayProof::ArrayProof(theory::arrays::TheoryArrays* arrays, TheoryProofEngine* pe)
+ : TheoryProof(arrays, pe)
+{}
+
+void ArrayProof::registerTerm(Expr term) {
+ // already registered
+ if (d_declarations.find(term) != d_declarations.end())
+ return;
+
+ Type type = term.getType();
+ if (type.isSort()) {
+ // declare uninterpreted sorts
+ d_sorts.insert(type);
+ }
+
+ if (term.getKind() == kind::APPLY_UF) {
+ Expr function = term.getOperator();
+ d_declarations.insert(function);
+ }
+
+ if (term.isVariable()) {
+ d_declarations.insert(term);
+ }
+
+ // recursively declare all other terms
+ for (unsigned i = 0; i < term.getNumChildren(); ++i) {
+ // could belong to other theories
+ d_proofEngine->registerTerm(term[i]);
+ }
+}
+
+std::string ArrayProof::skolemToLiteral(Expr skolem) {
+ Assert(d_skolemToLiteral.find(skolem) != d_skolemToLiteral.end());
+ return d_skolemToLiteral[skolem];
+}
+
+void LFSCArrayProof::printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) {
+ Debug("pf::array") << std::endl << "(pf::array) LFSCArrayProof::printOwnedTerm: term = " << term << std::endl;
+
+ Assert (theory::Theory::theoryOf(term) == theory::THEORY_ARRAY);
+
+ if (theory::Theory::theoryOf(term) != theory::THEORY_ARRAY) {
+ // We can get here, for instance, if there's a (select ite ...), e.g. a non-array term
+ // hiding as a subterm of an array term. In that case, send it back to the dispatcher.
+ d_proofEngine->printBoundTerm(term, os, map);
+ return;
+ }
+
+ if (term.getKind() == kind::VARIABLE || term.getKind() == kind::SKOLEM) {
+ os << term;
+ return;
+ }
+
+ Assert ((term.getKind() == kind::SELECT) || (term.getKind() == kind::PARTIAL_SELECT_0) || (term.getKind() == kind::PARTIAL_SELECT_1) || (term.getKind() == kind::STORE));
+
+ switch (term.getKind()) {
+ case kind::SELECT:
+ Assert(term.getNumChildren() == 2);
+ os << "(apply _ _ (apply _ _ (read ";
+ printSort(ArrayType(term[0].getType()).getIndexType(), os);
+ os << " ";
+ printSort(ArrayType(term[0].getType()).getConstituentType(), os);
+ os << ") ";
+ printTerm(term[0], os, map);
+ os << ") ";
+ printTerm(term[1], os, map);
+ os << ") ";
+ return;
+
+ case kind::PARTIAL_SELECT_0:
+ Assert(term.getNumChildren() == 1);
+ os << "(read ";
+ printSort(ArrayType(term[0].getType()).getIndexType(), os);
+ os << " ";
+ printSort(ArrayType(term[0].getType()).getConstituentType(), os);
+ os << ") ";
+ return;
+
+ case kind::PARTIAL_SELECT_1:
+ Debug("pf::array") << "This branch has not beed tested yet." << std::endl;
+ Unreachable();
+
+ Assert(term.getNumChildren() == 1);
+ os << "(apply _ _ (read ";
+ printSort(ArrayType(term[0].getType()).getIndexType(), os);
+ os << " ";
+ printSort(ArrayType(term[0].getType()).getConstituentType(), os);
+ os << ") ";
+ printTerm(term[0], os, map);
+ os << ") ";
+ return;
+
+ case kind::STORE:
+ os << "(apply _ _ (apply _ _ (apply _ _ (write ";
+ printSort(ArrayType(term[0].getType()).getIndexType(), os);
+ os << " ";
+ printSort(ArrayType(term[0].getType()).getConstituentType(), os);
+ os << ") ";
+ printTerm(term[0], os, map);
+ os << ") ";
+ printTerm(term[1], os, map);
+ os << ") ";
+ printTerm(term[2], os, map);
+ os << ") ";
+ return;
+
+ default:
+ Unreachable();
+ return;
+ }
+}
+
+void LFSCArrayProof::printOwnedSort(Type type, std::ostream& os) {
+ Debug("pf::array") << std::endl << "(pf::array) LFSCArrayProof::printOwnedSort: type is: " << type << std::endl;
+ Assert (type.isArray() || type.isSort());
+ os << type <<" ";
+}
+
+void LFSCArrayProof::printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren) {
+ os << " ;; Array Theory Lemma \n;;";
+ for (unsigned i = 0; i < lemma.size(); ++i) {
+ os << lemma[i] <<" ";
+ }
+ os <<"\n";
+ //os << " (clausify_false trust)";
+ ArrayProof::printTheoryLemmaProof(lemma, os, paren);
+}
+
+void LFSCArrayProof::printSortDeclarations(std::ostream& os, std::ostream& paren) {
+ // declaring the sorts
+ Debug("pf::array") << "Arrays declaring sorts..." << std::endl;
+
+ for (TypeSet::const_iterator it = d_sorts.begin(); it != d_sorts.end(); ++it) {
+ if (!ProofManager::currentPM()->wasPrinted(*it)) {
+ os << "(% " << *it << " sort\n";
+ paren << ")";
+ ProofManager::currentPM()->markPrinted(*it);
+ }
+ }
+}
+
+void LFSCArrayProof::printTermDeclarations(std::ostream& os, std::ostream& paren) {
+ Debug("pf::array") << "Arrays declaring terms..." << std::endl;
+
+ for (ExprSet::const_iterator it = d_declarations.begin(); it != d_declarations.end(); ++it) {
+ Expr term = *it;
+
+ Assert(term.getType().isArray() || term.isVariable());
+
+ Debug("pf::array") << "LFSCArrayProof::printDeclarations: term is: " << term
+ << ". It's type is: " << term.getType()
+ << std::endl;
+
+ if (term.getType().isArray()){
+ ArrayType array_type(term.getType());
+
+ Debug("pf::array") << "LFSCArrayProof::printDeclarations: term is an array. Index type: "
+ << array_type.getIndexType()
+ << ", element type: " << array_type.getConstituentType() << std::endl;
+
+ os << "(% " << ProofManager::sanitize(term) << " ";
+ os << "(term ";
+ os << "(Array ";
+
+ printSort(array_type.getIndexType(), os);
+ os << " ";
+ printSort(array_type.getConstituentType(), os);
+
+ os << "))\n";
+ } else {
+ Assert(term.isVariable());
+ if (ProofManager::getSkolemizationManager()->isSkolem(*it)) {
+ Debug("pf::array") << "This term is a skoelm!" << std::endl;
+ d_skolemDeclarations.insert(*it);
+ } else {
+ os << "(% " << ProofManager::sanitize(term) << " ";
+ os << "(term ";
+ os << term.getType() << ")\n";
+ }
+ }
+
+ paren << ")";
+ }
+
+ Debug("pf::array") << "Declaring terms done!" << std::endl;
+}
+
+void LFSCArrayProof::printDeferredDeclarations(std::ostream& os, std::ostream& paren) {
+ Debug("pf::array") << "Array: print deferred declarations called" << std::endl;
+
+ for (ExprSet::const_iterator it = d_skolemDeclarations.begin(); it != d_skolemDeclarations.end(); ++it) {
+ Expr term = *it;
+ Node equality = ProofManager::getSkolemizationManager()->getDisequality(*it);
+
+ Debug("pf::array") << "LFSCArrayProof::printDeferredDeclarations: term is: " << *it << std::endl
+ << "It is a witness for: " << equality << std::endl;
+
+ std::ostringstream newSkolemLiteral;
+ newSkolemLiteral << ".sl" << d_skolemToLiteral.size();
+ std::string skolemLiteral = newSkolemLiteral.str();
+
+ d_skolemToLiteral[*it] = skolemLiteral;
+
+ Debug("pf::array") << "LFSCArrayProof::printDeferredDeclarations: new skolem literal is: " << skolemLiteral << std::endl;
+
+ Assert(equality.getKind() == kind::NOT);
+ Assert(equality[0].getKind() == kind::EQUAL);
+
+ Node array_one = equality[0][0];
+ Node array_two = equality[0][1];
+
+ LetMap map;
+
+ os << "(ext _ _ ";
+ printTerm(array_one.toExpr(), os, map);
+ os << " ";
+ printTerm(array_two.toExpr(), os, map);
+ os << " (\\ ";
+ printTerm(*it, os, map);
+ os << " (\\ ";
+ os << skolemLiteral.c_str();
+ os << "\n";
+
+ paren << ")))";
+ }
+}
+
+} /* CVC4 namespace */
diff --git a/src/proof/array_proof.h b/src/proof/array_proof.h
index beaf5194c..fb25c9433 100644
--- a/src/proof/array_proof.h
+++ b/src/proof/array_proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file array_proof.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Guy Katz, Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Arrray proof
**
@@ -23,53 +23,74 @@
#include "proof/proof_manager.h"
#include "proof/theory_proof.h"
#include "theory/arrays/theory_arrays.h"
+#include "theory/uf/equality_engine.h"
namespace CVC4 {
+//proof object outputted by TheoryARRAY
+class ProofArray : public Proof {
+private:
+ Node toStreamRecLFSC(std::ostream& out, TheoryProof* tp,
+ theory::eq::EqProof* pf,
+ unsigned tb,
+ const LetMap& map);
+
+ /** Merge tag for ROW applications */
+ unsigned d_reasonRow;
+ /** Merge tag for ROW1 applications */
+ unsigned d_reasonRow1;
+ /** Merge tag for EXT applications */
+ unsigned d_reasonExt;
+public:
+ ProofArray(theory::eq::EqProof* pf) : d_proof(pf) {}
+ //it is simply an equality engine proof
+ theory::eq::EqProof *d_proof;
+ void toStream(std::ostream& out);
+ void toStreamLFSC(std::ostream& out, TheoryProof* tp, theory::eq::EqProof* pf, const LetMap& map);
+
+ void registerSkolem(Node equality, Node skolem);
+
+ void setRowMergeTag(unsigned tag);
+ void setRow1MergeTag(unsigned tag);
+ void setExtMergeTag(unsigned tag);
+};
+
namespace theory {
namespace arrays{
class TheoryArrays;
} /* namespace CVC4::theory::arrays */
} /* namespace CVC4::theory */
+typedef __gnu_cxx::hash_set<Type, TypeHashFunction > TypeSet;
+
class ArrayProof : public TheoryProof {
// TODO: whatever goes in this theory
+protected:
+ TypeSet d_sorts; // all the uninterpreted sorts in this theory
+ ExprSet d_declarations; // all the variable/function declarations
+ ExprSet d_skolemDeclarations; // all the skolem variable declarations
+ std::map<Expr, std::string> d_skolemToLiteral;
+
public:
- ArrayProof(theory::arrays::TheoryArrays* arrays, TheoryProofEngine* proofEngine)
- : TheoryProof(arrays, proofEngine)
- {}
- virtual void registerTerm(Expr term) {}
-
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map) = 0;
- virtual void printSort(Type type, std::ostream& os) = 0;
- /**
- * Print a proof for the theory lemma. Must prove
- * clause representing lemma to be used in resolution proof.
- *
- * @param lemma clausal form of lemma
- * @param os output stream
- */
- virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren) = 0;
- /**
- * Print the variable/sorts declarations for this theory.
- *
- * @param os
- * @param paren
- */
- virtual void printDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ ArrayProof(theory::arrays::TheoryArrays* arrays, TheoryProofEngine* proofEngine);
+
+ std::string skolemToLiteral(Expr skolem);
+
+ virtual void registerTerm(Expr term);
};
class LFSCArrayProof : public ArrayProof {
public:
- LFSCArrayProof(theory::arrays::TheoryArrays* uf, TheoryProofEngine* proofEngine)
- : ArrayProof(uf, proofEngine)
+ LFSCArrayProof(theory::arrays::TheoryArrays* arrays, TheoryProofEngine* proofEngine)
+ : ArrayProof(arrays, proofEngine)
{}
- // TODO implement
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map) {}
- virtual void printSort(Type type, std::ostream& os) {}
- virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren) {}
- virtual void printDeclarations(std::ostream& os, std::ostream& paren) {}
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map);
+ virtual void printOwnedSort(Type type, std::ostream& os);
+ virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren);
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren);
};
diff --git a/src/proof/bitvector_proof.cpp b/src/proof/bitvector_proof.cpp
index e067f0bce..b63782226 100644
--- a/src/proof/bitvector_proof.cpp
+++ b/src/proof/bitvector_proof.cpp
@@ -1,23 +1,23 @@
/********************* */
/*! \file bitvector_proof.cpp
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: none
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief [[ Add one-line brief description here ]]
-**
-** [[ Add lengthier description here ]]
-** \todo document this file
-**/
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+**/
-#include "proof/bitvector_proof.h"
+#include "proof/bitvector_proof.h"
#include "options/bv_options.h"
+#include "proof/clause_id.h"
#include "proof/proof_utils.h"
#include "proof/sat_proof_implementation.h"
#include "prop/bvminisat/bvminisat.h"
@@ -130,10 +130,10 @@ void BitVectorProof::endBVConflict(const CVC4::BVMinisat::Solver::TLitVec& confl
expr_confl.push_back(expr_lit);
}
Expr conflict = utils::mkSortedExpr(kind::OR, expr_confl);
- Debug("bv-proof") << "Make conflict for " << conflict << std::endl;
+ Debug("pf::bv") << "Make conflict for " << conflict << std::endl;
if (d_bbConflictMap.find(conflict) != d_bbConflictMap.end()) {
- Debug("bv-proof") << "Abort...already conflict for " << conflict << std::endl;
+ Debug("pf::bv") << "Abort...already conflict for " << conflict << std::endl;
// This can only happen when we have eager explanations in the bv solver
// if we don't get to propagate p before ~p is already asserted
d_resolutionProof->cancelResChain();
@@ -144,30 +144,33 @@ void BitVectorProof::endBVConflict(const CVC4::BVMinisat::Solver::TLitVec& confl
ClauseId clause_id = d_resolutionProof->registerAssumptionConflict(confl);
d_bbConflictMap[conflict] = clause_id;
d_resolutionProof->endResChain(clause_id);
- Debug("bv-proof") << "BitVectorProof::endBVConflict id"<<clause_id<< " => " << conflict << "\n";
+ Debug("pf::bv") << "BitVectorProof::endBVConflict id"<<clause_id<< " => " << conflict << "\n";
d_isAssumptionConflict = false;
}
void BitVectorProof::finalizeConflicts(std::vector<Expr>& conflicts) {
if (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER) {
- Debug("bv-proof") << "Construct full proof." << std::endl;
+ Debug("pf::bv") << "Construct full proof." << std::endl;
d_resolutionProof->constructProof();
return;
}
for(unsigned i = 0; i < conflicts.size(); ++i) {
Expr confl = conflicts[i];
- Debug("bv-proof") << "Finalize conflict " << confl << std::endl;
+ Debug("pf::bv") << "Finalize conflict " << confl << std::endl;
//Assert (d_bbConflictMap.find(confl) != d_bbConflictMap.end());
if(d_bbConflictMap.find(confl) != d_bbConflictMap.end()){
ClauseId id = d_bbConflictMap[confl];
d_resolutionProof->collectClauses(id);
}else{
- Debug("bv-proof") << "Do not collect clauses for " << confl << std::endl;
+ Debug("pf::bv") << "Do not collect clauses for " << confl << std::endl;
}
}
}
-void LFSCBitVectorProof::printTerm(Expr term, std::ostream& os, const LetMap& map) {
+void LFSCBitVectorProof::printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) {
+ Debug("pf::bv") << std::endl << "(pf::bv) LFSCBitVectorProof::printOwnedTerm( " << term << " ), theory is: "
+ << Theory::theoryOf(term) << std::endl;
+
Assert (Theory::theoryOf(term) == THEORY_BV);
// peel off eager bit-blasting trick
@@ -232,7 +235,7 @@ void LFSCBitVectorProof::printTerm(Expr term, std::ostream& os, const LetMap& ma
return;
}
case kind::BITVECTOR_BITOF : {
- printBitOf(term, os);
+ printBitOf(term, os, map);
return;
}
case kind::VARIABLE:
@@ -245,13 +248,25 @@ void LFSCBitVectorProof::printTerm(Expr term, std::ostream& os, const LetMap& ma
}
}
-void LFSCBitVectorProof::printBitOf(Expr term, std::ostream& os) {
+void LFSCBitVectorProof::printBitOf(Expr term, std::ostream& os, const LetMap& map) {
Assert (term.getKind() == kind::BITVECTOR_BITOF);
unsigned bit = term.getOperator().getConst<BitVectorBitOf>().bitIndex;
Expr var = term[0];
- Assert (var.getKind() == kind::VARIABLE ||
- var.getKind() == kind::SKOLEM);
- os << "(bitof " << ProofManager::sanitize(var) <<" " << bit <<")";
+
+ Debug("pf::bv") << "LFSCBitVectorProof::printBitOf( " << term << " ), "
+ << "bit = " << bit
+ << ", var = " << var << std::endl;
+
+ os << "(bitof ";
+ if (var.getKind() == kind::VARIABLE || var.getKind() == kind::SKOLEM) {
+ // If var is "simple", we can just sanitize and print
+ os << ProofManager::sanitize(var);
+ } else {
+ // If var is "complex", it can belong to another theory. Therefore, dispatch again.
+ d_proofEngine->printBoundTerm(var, os, map);
+ }
+
+ os << " " << bit << ")";
}
void LFSCBitVectorProof::printConstant(Expr term, std::ostream& os) {
@@ -332,7 +347,9 @@ void LFSCBitVectorProof::printOperatorParametric(Expr term, std::ostream& os, co
os <<")";
}
-void LFSCBitVectorProof::printSort(Type type, std::ostream& os) {
+void LFSCBitVectorProof::printOwnedSort(Type type, std::ostream& os) {
+ Debug("pf::bv") << std::endl << "(pf::bv) LFSCBitVectorProof::printOwnedSort( " << type << " )" << std::endl;
+
Assert (type.isBitVector());
unsigned width = utils::getSize(type);
os << "(BitVec "<<width<<")";
@@ -368,12 +385,20 @@ void LFSCBitVectorProof::printTheoryLemmaProof(std::vector<Expr>& lemma, std::os
ClauseId lemma_id = d_bbConflictMap[lem];
d_resolutionProof->printAssumptionsResolution(lemma_id, os, lemma_paren);
os <<lemma_paren.str();
- }else{
- Debug("bv-proof") << std::endl << "; Print non-bitblast theory conflict " << conflict << std::endl;
+ } else {
+ Unreachable(); // If we were to reach here, we would crash because BV replay is currently not supported
+ // in TheoryProof::printTheoryLemmaProof()
+
+ Debug("pf::bv") << std::endl << "; Print non-bitblast theory conflict " << conflict << std::endl;
BitVectorProof::printTheoryLemmaProof( lemma, os, paren );
}
}
-void LFSCBitVectorProof::printDeclarations(std::ostream& os, std::ostream& paren) {
+
+void LFSCBitVectorProof::printSortDeclarations(std::ostream& os, std::ostream& paren) {
+ // Nothing to do here at this point.
+}
+
+void LFSCBitVectorProof::printTermDeclarations(std::ostream& os, std::ostream& paren) {
ExprSet::const_iterator it = d_declarations.begin();
ExprSet::const_iterator end = d_declarations.end();
for (; it != end; ++it) {
@@ -382,6 +407,9 @@ void LFSCBitVectorProof::printDeclarations(std::ostream& os, std::ostream& paren
}
}
+void LFSCBitVectorProof::printDeferredDeclarations(std::ostream& os, std::ostream& paren) {
+ // Nothing to do here at this point.
+}
void LFSCBitVectorProof::printTermBitblasting(Expr term, std::ostream& os) {
// TODO: once we have the operator elimination rules remove those that we
@@ -428,7 +456,7 @@ void LFSCBitVectorProof::printTermBitblasting(Expr term, std::ostream& os) {
os <<" _ _ _ _ _ _ ";
}
os << getBBTermName(term[0]) <<" ";
-
+
for (unsigned i = 1; i < term.getNumChildren(); ++i) {
os << getBBTermName(term[i]);
os << ") ";
@@ -488,7 +516,7 @@ void LFSCBitVectorProof::printTermBitblasting(Expr term, std::ostream& os) {
case kind::BITVECTOR_SHL :
case kind::BITVECTOR_LSHR :
case kind::BITVECTOR_ASHR : {
- // these are terms for which bit-blasting is not supported yet
+ // these are terms for which bit-blasting is not supported yet
std::ostringstream paren;
os <<"(trust_bblast_term _ ";
paren <<")";
diff --git a/src/proof/bitvector_proof.h b/src/proof/bitvector_proof.h
index 80d567f7c..4a1f4015d 100644
--- a/src/proof/bitvector_proof.h
+++ b/src/proof/bitvector_proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bitvector_proof.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitvector proof
**
@@ -19,7 +19,7 @@
#ifndef __CVC4__BITVECTOR__PROOF_H
#define __CVC4__BITVECTOR__PROOF_H
-//#include <cstdint>
+//#include <cstdint>
#include <ext/hash_map>
#include <ext/hash_set>
#include <iostream>
@@ -45,7 +45,7 @@ template <class T> class TBitblaster;
} /* namespace CVC4::theory::bv */
} /* namespace CVC4::theory */
-class CnfProof;
+class CnfProof;
} /* namespace CVC4 */
namespace CVC4 {
@@ -109,7 +109,7 @@ public:
virtual void printTermBitblasting(Expr term, std::ostream& os) = 0;
virtual void printAtomBitblasting(Expr term, std::ostream& os) = 0;
-
+
virtual void printBitblasting(std::ostream& os, std::ostream& paren) = 0;
virtual void printResolutionProof(std::ostream& os, std::ostream& paren) = 0;
@@ -122,17 +122,19 @@ class LFSCBitVectorProof: public BitVectorProof {
void printOperatorUnary(Expr term, std::ostream& os, const LetMap& map);
void printPredicate(Expr term, std::ostream& os, const LetMap& map);
void printOperatorParametric(Expr term, std::ostream& os, const LetMap& map);
- void printBitOf(Expr term, std::ostream& os);
+ void printBitOf(Expr term, std::ostream& os, const LetMap& map);
public:
LFSCBitVectorProof(theory::bv::TheoryBV* bv, TheoryProofEngine* proofEngine)
:BitVectorProof(bv, proofEngine)
{}
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map);
- virtual void printSort(Type type, std::ostream& os);
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map);
+ virtual void printOwnedSort(Type type, std::ostream& os);
virtual void printTermBitblasting(Expr term, std::ostream& os);
virtual void printAtomBitblasting(Expr term, std::ostream& os);
virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren);
- virtual void printDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren);
virtual void printBitblasting(std::ostream& os, std::ostream& paren);
virtual void printResolutionProof(std::ostream& os, std::ostream& paren);
};
diff --git a/src/proof/clause_id.h b/src/proof/clause_id.h
new file mode 100644
index 000000000..c66f8c9f5
--- /dev/null
+++ b/src/proof/clause_id.h
@@ -0,0 +1,33 @@
+/********************* */
+/*! \file clause_id.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Definition of ClauseId
+ **
+ ** A ClauseId is a shared identifier between the proofs module and the sat
+ ** solver for a clause.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__PROOF__CLAUSE_ID_H
+#define __CVC4__PROOF__CLAUSE_ID_H
+
+namespace CVC4 {
+
+/**
+ * A ClauseId is a shared identifier between the proofs module and the sat
+ * solver for a clause.
+ */
+typedef unsigned ClauseId;
+
+}/* CVC4 namespace */
+
+#endif /* __CVC4__PROOF__CLAUSE_ID_H */
diff --git a/src/proof/cnf_proof.cpp b/src/proof/cnf_proof.cpp
index 884a67856..19e9cbac9 100644
--- a/src/proof/cnf_proof.cpp
+++ b/src/proof/cnf_proof.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cnf_proof.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters, Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -16,22 +16,23 @@
**/
#include "proof/cnf_proof.h"
-#include "proof/theory_proof.h"
+
+#include "proof/clause_id.h"
#include "proof/proof_manager.h"
-#include "prop/sat_solver_types.h"
-#include "prop/minisat/minisat.h"
+#include "proof/theory_proof.h"
#include "prop/cnf_stream.h"
-
-using namespace CVC4::prop;
+#include "prop/minisat/minisat.h"
+#include "prop/sat_solver_types.h"
namespace CVC4 {
-CnfProof::CnfProof(CnfStream* stream,
+CnfProof::CnfProof(prop::CnfStream* stream,
context::Context* ctx,
const std::string& name)
: d_cnfStream(stream)
, d_clauseToAssertion(ctx)
, d_assertionToProofRule(ctx)
+ , d_clauseIdToOwnerTheory(ctx)
, d_currentAssertionStack()
, d_currentDefinitionStack()
, d_clauseToDefinition(ctx)
@@ -54,12 +55,13 @@ bool CnfProof::isDefinition(Node node) {
return d_definitions.find(node) !=
d_definitions.end();
}
-
+
ProofRule CnfProof::getProofRule(Node node) {
Assert (isAssertion(node));
NodeToProofRule::iterator it = d_assertionToProofRule.find(node);
return (*it).second;
}
+
ProofRule CnfProof::getProofRule(ClauseId clause) {
TNode assertion = getAssertionForClause(clause);
return getProofRule(assertion);
@@ -94,13 +96,14 @@ void CnfProof::registerConvertedClause(ClauseId clause, bool explanation) {
Node current_assertion = getCurrentAssertion();
Node current_expr = getCurrentDefinition();
-
+
Debug("proof:cnf") << "CnfProof::registerConvertedClause "
<< clause << " assertion = " << current_assertion
<< clause << " definition = " << current_expr << std::endl;
setClauseAssertion(clause, current_assertion);
setClauseDefinition(clause, current_expr);
+ registerExplanationLemma(clause);
}
void CnfProof::setClauseAssertion(ClauseId clause, Node expr) {
@@ -112,7 +115,7 @@ void CnfProof::setClauseAssertion(ClauseId clause, Node expr) {
// that since b is top level, it is not cached by the CnfStream)
if (d_clauseToAssertion.find(clause) != d_clauseToAssertion.end())
return;
-
+
d_clauseToAssertion.insert (clause, expr);
}
@@ -126,7 +129,7 @@ void CnfProof::setClauseDefinition(ClauseId clause, Node definition) {
d_clauseToDefinition.insert(clause, definition);
d_definitions.insert(definition);
}
-
+
void CnfProof::registerAssertion(Node assertion, ProofRule reason) {
Debug("proof:cnf") << "CnfProof::registerAssertion "
<< assertion << " reason " << reason << std::endl;
@@ -140,6 +143,16 @@ void CnfProof::registerAssertion(Node assertion, ProofRule reason) {
d_assertionToProofRule.insert(assertion, reason);
}
+void CnfProof::registerExplanationLemma(ClauseId clauseId) {
+ d_clauseIdToOwnerTheory.insert(clauseId, getExplainerTheory());
+}
+
+theory::TheoryId CnfProof::getOwnerTheory(ClauseId clause) {
+ Assert(d_clauseIdToOwnerTheory.find(clause) != d_clauseIdToOwnerTheory.end());
+ return d_clauseIdToOwnerTheory[clause];
+}
+
+
void CnfProof::setCnfDependence(Node from, Node to) {
Debug("proof:cnf") << "CnfProof::setCnfDependence "
<< "from " << from << std::endl
@@ -158,10 +171,10 @@ void CnfProof::pushCurrentAssertion(Node assertion) {
void CnfProof::popCurrentAssertion() {
Assert (d_currentAssertionStack.size());
-
+
Debug("proof:cnf") << "CnfProof::popCurrentAssertion "
<< d_currentAssertionStack.back() << std::endl;
-
+
d_currentAssertionStack.pop_back();
}
@@ -170,6 +183,14 @@ Node CnfProof::getCurrentAssertion() {
return d_currentAssertionStack.back();
}
+void CnfProof::setExplainerTheory(theory::TheoryId theory) {
+ d_explainerTheory = theory;
+}
+
+theory::TheoryId CnfProof::getExplainerTheory() {
+ return d_explainerTheory;
+}
+
void CnfProof::pushCurrentDefinition(Node definition) {
Debug("proof:cnf") << "CnfProof::pushCurrentDefinition "
<< definition << std::endl;
@@ -179,10 +200,10 @@ void CnfProof::pushCurrentDefinition(Node definition) {
void CnfProof::popCurrentDefinition() {
Assert (d_currentDefinitionStack.size());
-
+
Debug("proof:cnf") << "CnfProof::popCurrentDefinition "
<< d_currentDefinitionStack.back() << std::endl;
-
+
d_currentDefinitionStack.pop_back();
}
@@ -202,8 +223,8 @@ Node CnfProof::getAtom(prop::SatVariable var) {
void CnfProof::collectAtoms(const prop::SatClause* clause,
NodeSet& atoms) {
for (unsigned i = 0; i < clause->size(); ++i) {
- SatLiteral lit = clause->operator[](i);
- SatVariable var = lit.getSatVariable();
+ prop::SatLiteral lit = clause->operator[](i);
+ prop::SatVariable var = lit.getSatVariable();
TNode atom = getAtom(var);
if (atoms.find(atom) == atoms.end()) {
Assert (atoms.find(atom) == atoms.end());
@@ -245,8 +266,8 @@ void CnfProof::collectAssertionsForClauses(const IdToSatClause& clauses,
void LFSCCnfProof::printAtomMapping(const NodeSet& atoms,
std::ostream& os,
std::ostream& paren) {
- NodeSet::const_iterator it = atoms.begin();
- NodeSet::const_iterator end = atoms.end();
+ NodeSet::const_iterator it = atoms.begin();
+ NodeSet::const_iterator end = atoms.end();
for (;it != end; ++it) {
os << "(decl_atom ";
@@ -255,7 +276,7 @@ void LFSCCnfProof::printAtomMapping(const NodeSet& atoms,
//FIXME hideous
LFSCTheoryProofEngine* pe = (LFSCTheoryProofEngine*)ProofManager::currentPM()->getTheoryProofEngine();
pe->printLetTerm(atom.toExpr(), os);
-
+
os << " (\\ " << ProofManager::getVarName(var, d_name)
<< " (\\ " << ProofManager::getAtomName(var, d_name) << "\n";
paren << ")))";
@@ -295,9 +316,9 @@ void LFSCCnfProof::printCnfProofForClause(ClauseId id,
// paren << "))";
// return;
-
+
Assert( clause->size()>0 );
-
+
Node base_assertion = getDefinitionForClause(id);
//get the assertion for the clause id
@@ -357,19 +378,19 @@ void LFSCCnfProof::printCnfProofForClause(ClauseId id,
std::stringstream os_paren;
//eliminate each one
for (int j = base_assertion.getNumChildren()-2; j >= 0; j--) {
+ Trace("cnf-pf-debug") << "; base_assertion[" << j << "] is: " << base_assertion[j]
+ << ", and its kind is: " << base_assertion[j].getKind() << std::endl ;
+
Node child_base = base_assertion[j].getKind()==kind::NOT ?
base_assertion[j][0] : base_assertion[j];
bool child_pol = base_assertion[j].getKind()!=kind::NOT;
-
- if( j==0 && base_assertion.getKind()==kind::IMPLIES ){
- child_pol = !child_pol;
- }
-
+
Trace("cnf-pf-debug") << "; child " << j << " "
- << child_base << " "
- << child_pol << " "
- << childPol[child_base] << std::endl;
-
+ << ", child base: " << child_base
+ << ", child pol: " << child_pol
+ << ", childPol[child_base] "
+ << childPol[child_base] << ", base pol: " << base_pol << std::endl;
+
std::map< Node, unsigned >::iterator itcic = childIndex.find( child_base );
if( itcic!=childIndex.end() ){
@@ -377,7 +398,13 @@ void LFSCCnfProof::printCnfProofForClause(ClauseId id,
os_main << "(or_elim_1 _ _ ";
prop::SatLiteral lit = (*clause)[itcic->second];
// Should be if in the original formula it was negated
- if( childPol[child_base] && base_pol ){
+ // if( childPol[child_base] && base_pol ){
+
+ // Adding the below to catch a specific case where the first child of an IMPLIES is negative,
+ // in which case we need not_not introduction.
+ if (base_assertion.getKind() == kind::IMPLIES && !child_pol && base_pol) {
+ os_main << "(not_not_intro _ " << ProofManager::getLitName(lit, d_name) << ") ";
+ } else if (childPol[child_base] && base_pol) {
os_main << ProofManager::getLitName(lit, d_name) << " ";
}else{
os_main << "(not_not_intro _ " << ProofManager::getLitName(lit, d_name) << ") ";
@@ -391,6 +418,7 @@ void LFSCCnfProof::printCnfProofForClause(ClauseId id,
success = false;
}
}
+
if( success ){
if( base_assertion.getKind()==kind::IMPLIES ){
os_main << "(impl_elim _ _ ";
@@ -420,7 +448,7 @@ void LFSCCnfProof::printCnfProofForClause(ClauseId id,
}else if ((base_assertion.getKind()==kind::AND && base_pol) ||
((base_assertion.getKind()==kind::OR ||
base_assertion.getKind()==kind::IMPLIES) && !base_pol)) {
-
+
std::stringstream os_main;
Node iatom;
@@ -431,7 +459,7 @@ void LFSCCnfProof::printCnfProofForClause(ClauseId id,
Assert( assertion.getNumChildren()==1 );
iatom = assertion[0];
}
-
+
Trace("cnf-pf") << "; and/or case 2, iatom = " << iatom << std::endl;
Node e_base = iatom.getKind()==kind::NOT ? iatom[0] : iatom;
bool e_pol = iatom.getKind()!=kind::NOT;
@@ -729,6 +757,4 @@ bool LFSCCnfProof::printProofTopLevel(Node e, std::ostream& out) {
}
}
-
-
} /* CVC4 namespace */
diff --git a/src/proof/cnf_proof.h b/src/proof/cnf_proof.h
index 675bd9b9d..a21cb1c0e 100644
--- a/src/proof/cnf_proof.h
+++ b/src/proof/cnf_proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cnf_proof.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters, Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A manager for CnfProofs.
**
@@ -21,14 +21,13 @@
#ifndef __CVC4__CNF_PROOF_H
#define __CVC4__CNF_PROOF_H
-#include <ext/hash_map>
+#include <ext/hash_map>
#include <ext/hash_set>
#include <iosfwd>
#include "context/cdhashmap.h"
+#include "proof/clause_id.h"
#include "proof/sat_proof.h"
-#include "proof/sat_proof.h"
-#include "util/proof.h"
#include "util/proof.h"
namespace CVC4 {
@@ -44,6 +43,7 @@ typedef __gnu_cxx::hash_set<ClauseId> ClauseIdSet;
typedef context::CDHashMap<ClauseId, Node> ClauseIdToNode;
typedef context::CDHashMap<Node, ProofRule, NodeHashFunction> NodeToProofRule;
+typedef context::CDHashMap<ClauseId, theory::TheoryId> ClauseIdToTheory;
class CnfProof {
protected:
@@ -55,28 +55,33 @@ protected:
/** Map from assertion to reason for adding assertion **/
NodeToProofRule d_assertionToProofRule;
+ /** Map from assertion to the theory that added this assertion **/
+ ClauseIdToTheory d_clauseIdToOwnerTheory;
+
+ /** The last theory to explain a lemma **/
+ theory::TheoryId d_explainerTheory;
+
/** Top of stack is assertion currently being converted to CNF **/
std::vector<Node> d_currentAssertionStack;
/** Top of stack is top-level fact currently being converted to CNF **/
std::vector<Node> d_currentDefinitionStack;
-
/** Map from ClauseId to the top-level fact that lead to adding this clause **/
ClauseIdToNode d_clauseToDefinition;
/** Top-level facts that follow from assertions during convertAndAssert **/
NodeSet d_definitions;
-
+
/** Map from top-level fact to facts/assertion that it follows from **/
NodeToNode d_cnfDeps;
ClauseIdSet d_explanations;
-
+
bool isDefinition(Node node);
Node getDefinitionForClause(ClauseId clause);
-
+
std::string d_name;
public:
CnfProof(CVC4::prop::CnfStream* cnfStream,
@@ -104,10 +109,10 @@ public:
/** Clause is one of the clauses defining top-level assertion node*/
void setClauseAssertion(ClauseId clause, Node node);
-
+
void registerAssertion(Node assertion, ProofRule reason);
void setCnfDependence(Node from, Node to);
-
+
void pushCurrentAssertion(Node assertion); // the current assertion being converted
void popCurrentAssertion();
Node getCurrentAssertion();
@@ -116,14 +121,18 @@ public:
void popCurrentDefinition();
Node getCurrentDefinition();
-
+ void setExplainerTheory(theory::TheoryId theory);
+ theory::TheoryId getExplainerTheory();
+ theory::TheoryId getOwnerTheory(ClauseId clause);
+
+ void registerExplanationLemma(ClauseId clauseId);
+
// accessors for the leaf assertions that are being converted to CNF
bool isAssertion(Node node);
ProofRule getProofRule(Node assertion);
ProofRule getProofRule(ClauseId clause);
Node getAssertionForClause(ClauseId clause);
-
/** Virtual methods for printing things **/
virtual void printAtomMapping(const NodeSet& atoms,
std::ostream& os,
@@ -155,7 +164,7 @@ public:
void printAtomMapping(const NodeSet& atoms,
std::ostream& os,
std::ostream& paren);
-
+
void printClause(const prop::SatClause& clause,
std::ostream& os,
std::ostream& paren);
diff --git a/src/proof/proof.h b/src/proof/proof.h
index 97dad7150..af72ccfa8 100644
--- a/src/proof/proof.h
+++ b/src/proof/proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file proof.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Proof macros
**
diff --git a/src/proof/proof_manager.cpp b/src/proof/proof_manager.cpp
index b90d589b8..a3689d746 100644
--- a/src/proof/proof_manager.cpp
+++ b/src/proof/proof_manager.cpp
@@ -1,34 +1,31 @@
/********************* */
/*! \file proof_manager.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief [[ Add one-line brief description here ]]
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
+
** \todo document this file
- **/
-#include "context/context.h"
+**/
#include "proof/proof_manager.h"
-#include "proof/cnf_proof.h"
-#include "proof/theory_proof.h"
+
+#include "base/cvc4_assert.h"
+#include "context/context.h"
+#include "options/bv_options.h"
#include "proof/bitvector_proof.h"
+#include "proof/clause_id.h"
+#include "proof/cnf_proof.h"
#include "proof/proof_utils.h"
#include "proof/sat_proof_implementation.h"
-#include "options/bv_options.h"
-
-#include "util/proof.h"
-#include "util/hash.h"
-
-#include "base/cvc4_assert.h"
+#include "proof/theory_proof.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
#include "smt_util/node_visitor.h"
@@ -38,7 +35,8 @@
#include "theory/uf/equality_engine.h"
#include "theory/uf/theory_uf.h"
#include "theory/valuation.h"
-
+#include "util/hash.h"
+#include "util/proof.h"
namespace CVC4 {
@@ -107,6 +105,7 @@ UFProof* ProofManager::getUfProof() {
TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_UF);
return (UFProof*)pf;
}
+
BitVectorProof* ProofManager::getBitVectorProof() {
Assert (options::proof());
TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_BV);
@@ -119,6 +118,17 @@ ArrayProof* ProofManager::getArrayProof() {
return (ArrayProof*)pf;
}
+ArithProof* ProofManager::getArithProof() {
+ Assert (options::proof());
+ TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_ARITH);
+ return (ArithProof*)pf;
+}
+
+SkolemizationManager* ProofManager::getSkolemizationManager() {
+ Assert (options::proof());
+ return &(currentPM()->d_skolemizationManager);
+}
+
void ProofManager::initSatProof(Minisat::Solver* solver) {
Assert (currentPM()->d_satProof == NULL);
Assert(currentPM()->d_format == LFSC);
@@ -212,14 +222,22 @@ std::string ProofManager::getLitName(TNode lit,
return getLitName(currentPM()->d_cnfProof->getLiteral(lit), prefix);
}
-std::string ProofManager::sanitize(TNode var) {
- Assert (var.isVar());
- std::string name = var.toString();
- std::replace(name.begin(), name.end(), ' ', '_');
+std::string ProofManager::sanitize(TNode node) {
+ Assert (node.isVar() || node.isConst());
+
+ std::string name = node.toString();
+ if (node.isVar()) {
+ std::replace(name.begin(), name.end(), ' ', '_');
+ } else if (node.isConst()) {
+ name.erase(std::remove(name.begin(), name.end(), '('), name.end());
+ name.erase(std::remove(name.begin(), name.end(), ')'), name.end());
+ name.erase(std::remove(name.begin(), name.end(), ' '), name.end());
+ name = "const" + name;
+ }
+
return name;
}
-
void ProofManager::traceDeps(TNode n) {
Debug("cores") << "trace deps " << n << std::endl;
if ((n.isConst() && n == NodeManager::currentNM()->mkConst<bool>(true)) ||
@@ -321,10 +339,51 @@ void LFSCProof::toStream(std::ostream& out) {
d_satProof->collectClausesUsed(used_inputs,
used_lemmas);
+ IdToSatClause::iterator it2;
+ Debug("pf::pm") << std::endl << "Used inputs: " << std::endl;
+ for (it2 = used_inputs.begin(); it2 != used_inputs.end(); ++it2) {
+ Debug("pf::pm") << "\t input = " << *(it2->second) << std::endl;
+ }
+ Debug("pf::pm") << std::endl;
+
+ // Debug("pf::pm") << std::endl << "Used lemmas: " << std::endl;
+ // for (it2 = used_lemmas.begin(); it2 != used_lemmas.end(); ++it2) {
+ // Debug("pf::pm") << "\t lemma = " << *(it2->second) << std::endl;
+ // }
+ // Debug("pf::pm") << std::endl;
+ Debug("pf::pm") << std::endl << "Used lemmas: " << std::endl;
+ for (it2 = used_lemmas.begin(); it2 != used_lemmas.end(); ++it2) {
+
+ std::vector<Expr> clause_expr;
+ for(unsigned i = 0; i < it2->second->size(); ++i) {
+ prop::SatLiteral lit = (*(it2->second))[i];
+ Expr atom = d_cnfProof->getAtom(lit.getSatVariable()).toExpr();
+ if (atom.isConst()) {
+ Assert (atom == utils::mkTrue());
+ continue;
+ }
+ Expr expr_lit = lit.isNegated() ? atom.notExpr(): atom;
+ clause_expr.push_back(expr_lit);
+ }
+
+ Debug("pf::pm") << "\t lemma " << it2->first << " = " << *(it2->second) << std::endl;
+ Debug("pf::pm") << "\t";
+ for (unsigned i = 0; i < clause_expr.size(); ++i) {
+ Debug("pf::pm") << clause_expr[i] << " ";
+ }
+ Debug("pf::pm") << std::endl;
+ }
+ Debug("pf::pm") << std::endl;
+
// collecting assertions that lead to the clauses being asserted
NodeSet used_assertions;
d_cnfProof->collectAssertionsForClauses(used_inputs, used_assertions);
+ NodeSet::iterator it3;
+ Debug("pf::pm") << std::endl << "Used assertions: " << std::endl;
+ for (it3 = used_assertions.begin(); it3 != used_assertions.end(); ++it3)
+ Debug("pf::pm") << "\t assertion = " << *it3 << std::endl;
+
NodeSet atoms;
// collects the atoms in the clauses
d_cnfProof->collectAtomsForClauses(used_inputs, atoms);
@@ -336,21 +395,25 @@ void LFSCProof::toStream(std::ostream& out) {
utils::collectAtoms(*it, atoms);
}
- if (Debug.isOn("proof:pm")) {
- // std::cout << NodeManager::currentNM();
- Debug("proof:pm") << "LFSCProof::Used assertions: "<< std::endl;
- for(NodeSet::const_iterator it = used_assertions.begin(); it != used_assertions.end(); ++it) {
- Debug("proof:pm") << " " << *it << std::endl;
- }
+ NodeSet::iterator atomIt;
+ Debug("pf::pm") << std::endl << "Dumping atoms from lemmas, inputs and assertions: " << std::endl << std::endl;
+ for (atomIt = atoms.begin(); atomIt != atoms.end(); ++atomIt) {
+ Debug("pf::pm") << "\tAtom: " << *atomIt << std::endl;
+
+ if (Debug.isOn("proof:pm")) {
+ // std::cout << NodeManager::currentNM();
+ Debug("proof:pm") << "LFSCProof::Used assertions: "<< std::endl;
+ for(NodeSet::const_iterator it = used_assertions.begin(); it != used_assertions.end(); ++it) {
+ Debug("proof:pm") << " " << *it << std::endl;
+ }
- Debug("proof:pm") << "LFSCProof::Used atoms: "<< std::endl;
- for(NodeSet::const_iterator it = atoms.begin(); it != atoms.end(); ++it) {
- Debug("proof:pm") << " " << *it << std::endl;
+ Debug("proof:pm") << "LFSCProof::Used atoms: "<< std::endl;
+ for(NodeSet::const_iterator it = atoms.begin(); it != atoms.end(); ++it) {
+ Debug("proof:pm") << " " << *it << std::endl;
+ }
}
}
-
-
smt::SmtScope scope(d_smtEngine);
std::ostringstream paren;
out << "(check\n";
@@ -359,32 +422,55 @@ void LFSCProof::toStream(std::ostream& out) {
// declare the theory atoms
NodeSet::const_iterator it = atoms.begin();
NodeSet::const_iterator end = atoms.end();
+
+ Debug("pf::pm") << "LFSCProof::toStream: registering terms:" << std::endl;
for(; it != end; ++it) {
+ Debug("pf::pm") << "\tTerm: " << (*it).toExpr() << std::endl;
d_theoryProof->registerTerm((*it).toExpr());
}
+
+ Debug("pf::pm") << std::endl << "Term registration done!" << std::endl << std::endl;
+
+ Debug("pf::pm") << std::endl << "LFSCProof::toStream: starting to print assertions" << std::endl;
+
// print out all the original assertions
+ d_theoryProof->registerTermsFromAssertions();
+ d_theoryProof->printSortDeclarations(out, paren);
+ d_theoryProof->printTermDeclarations(out, paren);
d_theoryProof->printAssertions(out, paren);
+ Debug("pf::pm") << std::endl << "LFSCProof::toStream: print assertions DONE" << std::endl;
- out << "(: (holds cln)\n";
+ out << "(: (holds cln)\n\n";
+
+ // Have the theory proofs print deferred declarations, e.g. for skolem variables.
+ out << " ;; Printing deferred declarations \n";
+ d_theoryProof->printDeferredDeclarations(out, paren);
// print trust that input assertions are their preprocessed form
printPreprocessedAssertions(used_assertions, out, paren);
// print mapping between theory atoms and internal SAT variables
+ out << ";; Printing mapping from preprocessed assertions into atoms \n";
d_cnfProof->printAtomMapping(atoms, out, paren);
+ Debug("pf::pm") << std::endl << "Printing cnf proof for clauses" << std::endl;
+
IdToSatClause::const_iterator cl_it = used_inputs.begin();
// print CNF conversion proof for each clause
for (; cl_it != used_inputs.end(); ++cl_it) {
d_cnfProof->printCnfProofForClause(cl_it->first, cl_it->second, out, paren);
}
+ Debug("pf::pm") << std::endl << "Printing cnf proof for clauses DONE" << std::endl;
+
// FIXME: for now assume all theory lemmas are in CNF form so
// distinguish between them and inputs
// print theory lemmas for resolution proof
- d_theoryProof->printTheoryLemmas(used_lemmas, out, paren);
+ Debug("pf::pm") << "Proof manager: printing theory lemmas" << std::endl;
+ d_theoryProof->printTheoryLemmas(used_lemmas, out, paren);
+ Debug("pf::pm") << "Proof manager: printing theory lemmas DONE!" << std::endl;
if (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER && ProofManager::getBitVectorProof()) {
// print actual resolution proof
@@ -406,7 +492,7 @@ void LFSCProof::toStream(std::ostream& out) {
void LFSCProof::printPreprocessedAssertions(const NodeSet& assertions,
std::ostream& os,
std::ostream& paren) {
- os << " ;; Preprocessing \n";
+ os << "\n ;; In the preprocessor we trust \n";
NodeSet::const_iterator it = assertions.begin();
NodeSet::const_iterator end = assertions.end();
@@ -422,11 +508,12 @@ void LFSCProof::printPreprocessedAssertions(const NodeSet& assertions,
paren << "))";
}
-}
-
+ os << "\n";
+}
//---from Morgan---
+
bool ProofManager::hasOp(TNode n) const {
return d_bops.find(n) != d_bops.end();
}
@@ -438,16 +525,21 @@ Node ProofManager::lookupOp(TNode n) const {
}
Node ProofManager::mkOp(TNode n) {
+ Trace("mgd-pm-mkop") << "MkOp : " << n << " " << n.getKind() << std::endl;
if(n.getKind() != kind::BUILTIN) {
return n;
}
+
Node& op = d_ops[n];
if(op.isNull()) {
- Debug("mgd") << "making an op for " << n << "\n";
+ Assert((n.getConst<Kind>() == kind::SELECT) || (n.getConst<Kind>() == kind::STORE));
+
+ Debug("mgd-pm-mkop") << "making an op for " << n << "\n";
+
std::stringstream ss;
ss << n;
std::string s = ss.str();
- Debug("mgd") << " : " << s << std::endl;
+ Debug("mgd-pm-mkop") << " : " << s << std::endl;
std::vector<TypeNode> v;
v.push_back(NodeManager::currentNM()->integerType());
if(n.getConst<Kind>() == kind::SELECT) {
@@ -459,44 +551,54 @@ Node ProofManager::mkOp(TNode n) {
v.push_back(NodeManager::currentNM()->integerType());
}
TypeNode type = NodeManager::currentNM()->mkFunctionType(v);
+ Debug("mgd-pm-mkop") << "typenode is: " << type << "\n";
op = NodeManager::currentNM()->mkSkolem(s, type, " ignore", NodeManager::SKOLEM_NO_NOTIFY);
d_bops[op] = n;
}
+ Debug("mgd-pm-mkop") << "returning the op: " << op << "\n";
return op;
}
//---end from Morgan---
+bool ProofManager::wasPrinted(const Type& type) const {
+ return d_printedTypes.find(type) != d_printedTypes.end();
+}
+
+void ProofManager::markPrinted(const Type& type) {
+ d_printedTypes.insert(type);
+}
+
std::ostream& operator<<(std::ostream& out, CVC4::ProofRule k) {
switch(k) {
case RULE_GIVEN:
- out << "RULE_GIVEN";
+ out << "RULE_GIVEN";
break;
case RULE_DERIVED:
- out << "RULE_DERIVED";
+ out << "RULE_DERIVED";
break;
case RULE_RECONSTRUCT:
- out << "RULE_RECONSTRUCT";
+ out << "RULE_RECONSTRUCT";
break;
case RULE_TRUST:
- out << "RULE_TRUST";
+ out << "RULE_TRUST";
break;
case RULE_INVALID:
- out << "RULE_INVALID";
+ out << "RULE_INVALID";
break;
case RULE_CONFLICT:
- out << "RULE_CONFLICT";
+ out << "RULE_CONFLICT";
break;
case RULE_TSEITIN:
- out << "RULE_TSEITIN";
+ out << "RULE_TSEITIN";
break;
case RULE_SPLIT:
- out << "RULE_SPLIT";
+ out << "RULE_SPLIT";
break;
case RULE_ARRAYS_EXT:
- out << "RULE_ARRAYS";
+ out << "RULE_ARRAYS";
break;
case RULE_ARRAYS_ROW:
- out << "RULE_ARRAYS";
+ out << "RULE_ARRAYS";
break;
default:
out << "ProofRule Unknown! [" << unsigned(k) << "]";
diff --git a/src/proof/proof_manager.h b/src/proof/proof_manager.h
index 96c4e1d61..c74aac237 100644
--- a/src/proof/proof_manager.h
+++ b/src/proof/proof_manager.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file proof_manager.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A manager for Proofs
**
@@ -21,8 +21,11 @@
#include <iosfwd>
#include <map>
-
+#include "proof/proof.h"
+#include "proof/skolemization_manager.h"
+#include "util/proof.h"
#include "expr/node.h"
+#include "proof/clause_id.h"
#include "proof/proof.h"
#include "theory/logic_info.h"
#include "theory/substitutions.h"
@@ -46,13 +49,12 @@ namespace prop {
class SmtEngine;
-typedef unsigned ClauseId;
const ClauseId ClauseIdEmpty(-1);
-const ClauseId ClauseIdUndef(-2);
+const ClauseId ClauseIdUndef(-2);
const ClauseId ClauseIdError(-3);
class Proof;
-template <class Solver> class TSatProof;
+template <class Solver> class TSatProof;
typedef TSatProof< CVC4::Minisat::Solver> CoreSatProof;
class CnfProof;
@@ -60,10 +62,11 @@ class RewriterProof;
class TheoryProofEngine;
class TheoryProof;
class UFProof;
+class ArithProof;
class ArrayProof;
class BitVectorProof;
-template <class Solver> class LFSCSatProof;
+template <class Solver> class LFSCSatProof;
typedef LFSCSatProof< CVC4::Minisat::Solver> LFSCCoreSatProof;
class LFSCCnfProof;
@@ -74,7 +77,7 @@ class LFSCRewriterProof;
template <class Solver> class ProofProxy;
typedef ProofProxy< CVC4::Minisat::Solver> CoreProofProxy;
-typedef ProofProxy< CVC4::BVMinisat::Solver> BVProofProxy;
+typedef ProofProxy< CVC4::BVMinisat::Solver> BVProofProxy;
namespace prop {
typedef uint64_t SatVariable;
@@ -96,8 +99,6 @@ typedef __gnu_cxx::hash_set<Node, NodeHashFunction > NodeSet;
typedef __gnu_cxx::hash_map<Node, std::vector<Node>, NodeHashFunction > NodeToNodes;
typedef std::hash_set<ClauseId> IdHashSet;
-typedef unsigned ClauseId;
-
enum ProofRule {
RULE_GIVEN, /* input assertion */
RULE_DERIVED, /* a "macro" rule */
@@ -107,7 +108,7 @@ enum ProofRule {
RULE_CONFLICT, /* re-construct as a conflict */
RULE_TSEITIN, /* Tseitin CNF transformation */
RULE_SPLIT, /* A splitting lemma of the form a v ~ a*/
-
+
RULE_ARRAYS_EXT, /* arrays, extensional */
RULE_ARRAYS_ROW, /* arrays, read-over-write */
};/* enum ProofRules */
@@ -122,6 +123,8 @@ class ProofManager {
ExprSet d_inputCoreFormulas;
ExprSet d_outputCoreFormulas;
+ SkolemizationManager d_skolemizationManager;
+
int d_nextId;
Proof* d_fullProof;
@@ -131,6 +134,8 @@ class ProofManager {
// trace dependences back to unsat core
void traceDeps(TNode n);
+ std::set<Type> d_printedTypes;
+
protected:
LogicInfo d_logic;
@@ -155,6 +160,9 @@ public:
static UFProof* getUfProof();
static BitVectorProof* getBitVectorProof();
static ArrayProof* getArrayProof();
+ static ArithProof* getArithProof();
+
+ static SkolemizationManager *getSkolemizationManager();
// iterators over data shared by proofs
typedef ExprSet::const_iterator assertions_iterator;
@@ -165,17 +173,17 @@ public:
}
assertions_iterator end_assertions() const { return d_inputFormulas.end(); }
size_t num_assertions() const { return d_inputFormulas.size(); }
-
+
//---from Morgan---
Node mkOp(TNode n);
Node lookupOp(TNode n) const;
bool hasOp(TNode n) const;
-
+
std::map<Node, Node> d_ops;
std::map<Node, Node> d_bops;
//---end from Morgan---
-
-
+
+
// variable prefixes
static std::string getInputClauseName(ClauseId id, const std::string& prefix = "");
static std::string getLemmaClauseName(ClauseId id, const std::string& prefix = "");
@@ -183,7 +191,7 @@ public:
static std::string getLearntClauseName(ClauseId id, const std::string& prefix = "");
static std::string getPreprocessedAssertionName(Node node, const std::string& prefix = "");
static std::string getAssertionName(Node node, const std::string& prefix = "");
-
+
static std::string getVarName(prop::SatVariable var, const std::string& prefix = "");
static std::string getAtomName(prop::SatVariable var, const std::string& prefix = "");
static std::string getAtomName(TNode atom, const std::string& prefix = "");
@@ -192,14 +200,13 @@ public:
// for SMT variable names that have spaces and other things
static std::string sanitize(TNode var);
-
- /** Add proof assertion - unlinke addCoreAssertion this is post definition expansion **/
+ /** Add proof assertion - unlike addCoreAssertion this is post definition expansion **/
void addAssertion(Expr formula);
-
+
/** Public unsat core methods **/
void addCoreAssertion(Expr formula);
-
+
void addDependence(TNode n, TNode dep);
void addUnsatCore(Expr formula);
@@ -214,6 +221,9 @@ public:
const std::string getLogic() const { return d_logic.getLogicString(); }
LogicInfo & getLogicInfo() { return d_logic; }
+ void markPrinted(const Type& type);
+ bool wasPrinted(const Type& type) const;
+
};/* class ProofManager */
class LFSCProof : public Proof {
diff --git a/src/proof/proof_utils.cpp b/src/proof/proof_utils.cpp
index 47b8a235e..5b04c281d 100644
--- a/src/proof/proof_utils.cpp
+++ b/src/proof/proof_utils.cpp
@@ -1,18 +1,18 @@
/********************* */
/*! \file proof_utils.cpp
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: none
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief [[ Add one-line brief description here ]]
-**
-** [[ Add lengthier description here ]]
-** \todo document this file
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
**/
#include "proof/proof_utils.h"
diff --git a/src/proof/proof_utils.h b/src/proof/proof_utils.h
index c27fbe5c2..da10c33a0 100644
--- a/src/proof/proof_utils.h
+++ b/src/proof/proof_utils.h
@@ -1,18 +1,18 @@
/********************* */
/*! \file proof_utils.h
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: none
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief [[ Add one-line brief description here ]]
-**
-** [[ Add lengthier description here ]]
-** \todo document this file
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
**/
#include "cvc4_private.h"
diff --git a/src/proof/sat_proof.h b/src/proof/sat_proof.h
index cd42ab85b..d94b61bf3 100644
--- a/src/proof/sat_proof.h
+++ b/src/proof/sat_proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sat_proof.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Resolution proof
**
@@ -20,21 +20,22 @@
#define __CVC4__SAT__PROOF_H
#include <stdint.h>
+
#include <ext/hash_map>
#include <ext/hash_set>
#include <iosfwd>
#include <set>
#include <sstream>
#include <vector>
+
#include "expr/expr.h"
+#include "proof/clause_id.h"
#include "proof/proof_manager.h"
#include "util/proof.h"
#include "util/statistics_registry.h"
-
namespace CVC4 {
-
class CnfProof;
/**
@@ -123,7 +124,7 @@ protected:
VarSet d_assumptions; // assumption literals for bv solver
IdHashSet d_assumptionConflicts; // assumption conflicts not actually added to SAT solver
IdToConflicts d_assumptionConflictsDebug;
-
+
// resolutions
IdResMap d_resChains;
ResStack d_resStack;
@@ -240,13 +241,13 @@ public:
ClauseId getTrueUnit() const;
ClauseId getFalseUnit() const;
-
+
void registerAssumption(const typename Solver::TVar var);
ClauseId registerAssumptionConflict(const typename Solver::TLitVec& confl);
-
+
ClauseId storeUnitConflict(typename Solver::TLit lit,
ClauseKind kind);
-
+
/**
* Marks the deleted clauses as deleted. Note we may still use them in the final
* resolution.
@@ -296,12 +297,13 @@ public:
virtual void printResolutionEmptyClause(std::ostream& out, std::ostream& paren) = 0;
virtual void printAssumptionsResolution(ClauseId id, std::ostream& out, std::ostream& paren) = 0;
-
void collectClausesUsed(IdToSatClause& inputs,
IdToSatClause& lemmas);
void storeClauseGlue(ClauseId clause, int glue);
+
+
private:
__gnu_cxx::hash_map<ClauseId, int> d_glueMap;
struct Statistics {
@@ -320,7 +322,6 @@ private:
Statistics d_statistics;
};/* class TSatProof */
-
template <class S>
class ProofProxy {
private:
diff --git a/src/proof/sat_proof_implementation.h b/src/proof/sat_proof_implementation.h
index 92645e105..e773e4b47 100644
--- a/src/proof/sat_proof_implementation.h
+++ b/src/proof/sat_proof_implementation.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sat_proof_implementation.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Resolution proof
**
@@ -19,30 +19,31 @@
#ifndef __CVC4__SAT__PROOF_IMPLEMENTATION_H
#define __CVC4__SAT__PROOF_IMPLEMENTATION_H
-#include "proof/sat_proof.h"
+#include "proof/clause_id.h"
#include "proof/cnf_proof.h"
-#include "prop/minisat/minisat.h"
+#include "proof/sat_proof.h"
#include "prop/bvminisat/bvminisat.h"
-#include "prop/minisat/core/Solver.h"
#include "prop/bvminisat/core/Solver.h"
+#include "prop/minisat/core/Solver.h"
+#include "prop/minisat/minisat.h"
#include "prop/sat_solver_types.h"
#include "smt/smt_statistics_registry.h"
namespace CVC4 {
-template <class Solver>
+template <class Solver>
void printLit (typename Solver::TLit l) {
Debug("proof:sat") << (sign(l) ? "-" : "") << var(l) + 1;
}
-template <class Solver>
+template <class Solver>
void printClause (typename Solver::TClause& c) {
for (int i = 0; i < c.size(); i++) {
Debug("proof:sat") << (sign(c[i]) ? "-" : "") << var(c[i]) + 1 << " ";
}
}
-template <class Solver>
+template <class Solver>
void printClause (std::vector<typename Solver::TLit>& c) {
for (unsigned i = 0; i < c.size(); i++) {
Debug("proof:sat") << (sign(c[i]) ? "-" : "") << var(c[i]) + 1 << " ";
@@ -50,7 +51,7 @@ void printClause (std::vector<typename Solver::TLit>& c) {
}
-template <class Solver>
+template <class Solver>
void printLitSet(const std::set<typename Solver::TLit>& s) {
typename std::set < typename Solver::TLit>::const_iterator it = s.begin();
for(; it != s.end(); ++it) {
@@ -61,11 +62,11 @@ void printLitSet(const std::set<typename Solver::TLit>& s) {
}
// purely debugging functions
-template <class Solver>
+template <class Solver>
void printDebug (typename Solver::TLit l) {
Debug("proof:sat") << (sign(l) ? "-" : "") << var(l) + 1 << std::endl;
}
-template <class Solver>
+template <class Solver>
void printDebug (typename Solver::TClause& c) {
for (int i = 0; i < c.size(); i++) {
Debug("proof:sat") << (sign(c[i]) ? "-" : "") << var(c[i]) + 1 << " ";
@@ -80,7 +81,7 @@ void printDebug (typename Solver::TClause& c) {
* @param id the clause id
* @param set the clause converted to a set of literals
*/
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::createLitSet(ClauseId id, LitSet& set) {
Assert(set.empty());
if(isUnit(id)) {
@@ -94,11 +95,11 @@ void TSatProof<Solver>::createLitSet(ClauseId id, LitSet& set) {
if (d_assumptionConflictsDebug.find(id) != d_assumptionConflictsDebug.end()) {
LitVector* clause = d_assumptionConflictsDebug[id];
for (unsigned i = 0; i < clause->size(); ++i) {
- set.insert(clause->operator[](i));
+ set.insert(clause->operator[](i));
}
return;
}
-
+
typename Solver::TCRef ref = getClauseRef(id);
typename Solver::TClause& c = getClause(ref);
for (int i = 0; i < c.size(); i++) {
@@ -114,7 +115,7 @@ void TSatProof<Solver>::createLitSet(ClauseId id, LitSet& set) {
* @param clause1
* @param clause2
*/
-template <class Solver>
+template <class Solver>
bool resolve(const typename Solver::TLit v,
std::set<typename Solver::TLit>& clause1,
std::set<typename Solver::TLit>& clause2, bool s) {
@@ -133,7 +134,7 @@ bool resolve(const typename Solver::TLit v,
}
clause1.erase(var);
clause2.erase(~var);
- typename std::set<typename Solver::TLit>::iterator it = clause2.begin();
+ typename std::set<typename Solver::TLit>::iterator it = clause2.begin();
for (; it!= clause2.end(); ++it) {
clause1.insert(*it);
}
@@ -149,7 +150,7 @@ bool resolve(const typename Solver::TLit v,
}
clause1.erase(~var);
clause2.erase(var);
- typename std::set<typename Solver::TLit>::iterator it = clause2.begin();
+ typename std::set<typename Solver::TLit>::iterator it = clause2.begin();
for (; it!= clause2.end(); ++it) {
clause1.insert(*it);
}
@@ -158,19 +159,19 @@ bool resolve(const typename Solver::TLit v,
}
/// ResChain
-template <class Solver>
+template <class Solver>
ResChain<Solver>::ResChain(ClauseId start) :
d_start(start),
d_steps(),
d_redundantLits(NULL)
{}
-template <class Solver>
+template <class Solver>
void ResChain<Solver>::addStep(typename Solver::TLit lit, ClauseId id, bool sign) {
ResStep<Solver> step(lit, id, sign);
d_steps.push_back(step);
}
-template <class Solver>
+template <class Solver>
void ResChain<Solver>::addRedundantLit(typename Solver::TLit lit) {
if (d_redundantLits) {
d_redundantLits->insert(lit);
@@ -182,19 +183,19 @@ void ResChain<Solver>::addRedundantLit(typename Solver::TLit lit) {
/// ProxyProof
-template <class Solver>
+template <class Solver>
ProofProxy<Solver>::ProofProxy(TSatProof<Solver>* proof):
d_proof(proof)
{}
-template <class Solver>
+template <class Solver>
void ProofProxy<Solver>::updateCRef(typename Solver::TCRef oldref, typename Solver::TCRef newref) {
d_proof->updateCRef(oldref, newref);
}
/// SatProof
-template <class Solver>
+template <class Solver>
TSatProof<Solver>::TSatProof(Solver* solver, const std::string& name, bool checkRes)
: d_solver(solver)
, d_cnfProof(NULL)
@@ -217,7 +218,7 @@ TSatProof<Solver>::TSatProof(Solver* solver, const std::string& name, bool check
, d_unitConflictId()
, d_storedUnitConflict(false)
, d_trueLit(ClauseIdUndef)
- , d_falseLit(ClauseIdUndef)
+ , d_falseLit(ClauseIdUndef)
, d_name(name)
, d_seenLearnt()
, d_seenInputs()
@@ -227,10 +228,10 @@ TSatProof<Solver>::TSatProof(Solver* solver, const std::string& name, bool check
d_proxy = new ProofProxy<Solver>(this);
}
-template <class Solver>
+template <class Solver>
TSatProof<Solver>::~TSatProof() {
delete d_proxy;
-
+
// FIXME: double free if deleted clause also appears in d_seenLemmas?
IdToSatClause::iterator it = d_deletedTheoryLemmas.begin();
IdToSatClause::iterator end = d_deletedTheoryLemmas.end();
@@ -256,8 +257,8 @@ TSatProof<Solver>::~TSatProof() {
delete seen_it->second;
}
}
-
-template <class Solver>
+
+template <class Solver>
void TSatProof<Solver>::setCnfProof(CnfProof* cnf_proof) {
Assert (d_cnfProof == NULL);
d_cnfProof = cnf_proof;
@@ -270,7 +271,7 @@ void TSatProof<Solver>::setCnfProof(CnfProof* cnf_proof) {
*
* @return
*/
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::checkResolution(ClauseId id) {
if(d_checkRes) {
bool validRes = true;
@@ -299,9 +300,9 @@ bool TSatProof<Solver>::checkResolution(ClauseId id) {
if (id == d_emptyClauseId) {
return clause1.empty();
}
-
+
LitVector c;
- getLitVec(id, c);
+ getLitVec(id, c);
for (unsigned i = 0; i < c.size(); ++i) {
int count = clause1.erase(c[i]);
@@ -334,7 +335,7 @@ bool TSatProof<Solver>::checkResolution(ClauseId id) {
/// helper methods
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::getClauseId(typename Solver::TCRef ref) {
if(d_clauseId.find(ref) == d_clauseId.end()) {
Debug("proof:sat") << "Missing clause \n";
@@ -343,12 +344,12 @@ ClauseId TSatProof<Solver>::getClauseId(typename Solver::TCRef ref) {
return d_clauseId[ref];
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::getClauseId(typename Solver::TLit lit) {
Assert(d_unitId.find(toInt(lit)) != d_unitId.end());
return d_unitId[toInt(lit)];
}
-template <class Solver>
+template <class Solver>
typename Solver::TCRef TSatProof<Solver>::getClauseRef(ClauseId id) {
if (d_idClause.find(id) == d_idClause.end()) {
Debug("proof:sat") << "proof:getClauseRef cannot find clause "<<id<<" "
@@ -359,19 +360,19 @@ typename Solver::TCRef TSatProof<Solver>::getClauseRef(ClauseId id) {
return d_idClause[id];
}
-template <class Solver>
+template <class Solver>
typename Solver::TClause& TSatProof<Solver>::getClause(typename Solver::TCRef ref) {
Assert(ref != Solver::TCRef_Undef);
Assert(ref >= 0 && ref < d_solver->ca.size());
return d_solver->ca[ref];
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::getLitVec(ClauseId id, LitVector& vec) {
if (isUnit(id)) {
typename Solver::TLit lit = getUnit(id);
vec.push_back(lit);
- return;
+ return;
}
if (isAssumptionConflict(id)) {
vec = *(d_assumptionConflictsDebug[id]);
@@ -385,44 +386,44 @@ void TSatProof<Solver>::getLitVec(ClauseId id, LitVector& vec) {
}
-template <class Solver>
+template <class Solver>
typename Solver::TLit TSatProof<Solver>::getUnit(ClauseId id) {
Assert(d_idUnit.find(id) != d_idUnit.end());
return d_idUnit[id];
}
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::isUnit(ClauseId id) {
return d_idUnit.find(id) != d_idUnit.end();
}
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::isUnit(typename Solver::TLit lit) {
return d_unitId.find(toInt(lit)) != d_unitId.end();
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::getUnitId(typename Solver::TLit lit) {
Assert(isUnit(lit));
return d_unitId[toInt(lit)];
}
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::hasResolution(ClauseId id) {
return d_resChains.find(id) != d_resChains.end();
}
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::isInputClause(ClauseId id) {
return (d_inputClauses.find(id) != d_inputClauses.end());
}
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::isLemmaClause(ClauseId id) {
return (d_lemmaClauses.find(id) != d_lemmaClauses.end());
}
-template <class Solver>
+template <class Solver>
bool TSatProof<Solver>::isAssumptionConflict(ClauseId id) {
return d_assumptionConflicts.find(id) != d_assumptionConflicts.end();
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::print(ClauseId id) {
if (d_deleted.find(id) != d_deleted.end()) {
Debug("proof:sat") << "del"<<id;
@@ -436,13 +437,13 @@ void TSatProof<Solver>::print(ClauseId id) {
printClause<Solver>(getClause(ref));
}
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::printRes(ClauseId id) {
Assert(hasResolution(id));
Debug("proof:sat") << "id "<< id <<": ";
printRes(d_resChains[id]);
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::printRes(ResChain<Solver>* res) {
ClauseId start_id = res->getStart();
@@ -467,14 +468,14 @@ void TSatProof<Solver>::printRes(ResChain<Solver>* res) {
}
/// registration methods
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::registerClause(typename Solver::TCRef clause,
ClauseKind kind) {
Assert(clause != Solver::TCRef_Undef);
typename ClauseIdMap::iterator it = d_clauseId.find(clause);
if (it == d_clauseId.end()) {
ClauseId newId = ProofManager::currentPM()->nextId();
- d_clauseId.insert(std::make_pair(clause, newId));
+ d_clauseId.insert(std::make_pair(clause, newId));
d_idClause.insert(std::make_pair(newId, clause));
if (kind == INPUT) {
Assert(d_inputClauses.find(newId) == d_inputClauses.end());
@@ -483,6 +484,11 @@ template <class Solver>
if (kind == THEORY_LEMMA) {
Assert(d_lemmaClauses.find(newId) == d_lemmaClauses.end());
d_lemmaClauses.insert(newId);
+ Debug("pf::sat") << "TSatProof::registerClause registering a new lemma clause: "
+ << newId << " = " << *buildClause(newId)
+ << ". Explainer theory: " << d_cnfProof->getExplainerTheory()
+ << std::endl;
+ d_cnfProof->registerExplanationLemma(newId);
}
}
@@ -496,7 +502,7 @@ template <class Solver>
return id;
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::registerUnitClause(typename Solver::TLit lit,
ClauseKind kind) {
Debug("cores") << "registerUnitClause " << kind << std::endl;
@@ -512,49 +518,54 @@ ClauseId TSatProof<Solver>::registerUnitClause(typename Solver::TLit lit,
}
if (kind == THEORY_LEMMA) {
Assert(d_lemmaClauses.find(newId) == d_lemmaClauses.end());
+ Debug("pf::sat") << "TSatProof::registerUnitClause: registering a new lemma (UNIT CLAUSE): "
+ << lit
+ << ". Explainer theory: " << d_cnfProof->getExplainerTheory()
+ << std::endl;
d_lemmaClauses.insert(newId);
+ d_cnfProof->registerExplanationLemma(newId);
}
}
ClauseId id = d_unitId[toInt(lit)];
Assert(kind != INPUT || d_inputClauses.count(id));
Assert(kind != THEORY_LEMMA || d_lemmaClauses.count(id));
- Debug("proof:sat:detailed") << "registerUnitClause id: " << id
+ Debug("proof:sat:detailed") << "registerUnitClause id: " << id
<<" kind: " << kind << "\n";
// ProofManager::currentPM()->setRegisteredClauseId( d_unitId[toInt(lit)] );
return id;
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::registerTrueLit(const typename Solver::TLit lit) {
Assert (d_trueLit == ClauseIdUndef);
d_trueLit = registerUnitClause(lit, INPUT);
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::registerFalseLit(const typename Solver::TLit lit) {
Assert (d_falseLit == ClauseIdUndef);
d_falseLit = registerUnitClause(lit, INPUT);
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::getTrueUnit() const {
Assert (d_trueLit != ClauseIdUndef);
return d_trueLit;
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::getFalseUnit() const {
Assert (d_falseLit != ClauseIdUndef);
return d_falseLit;
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::registerAssumption(const typename Solver::TVar var) {
Assert (d_assumptions.find(var) == d_assumptions.end());
d_assumptions.insert(var);
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::registerAssumptionConflict(const typename Solver::TLitVec& confl) {
Debug("proof:sat:detailed") << "registerAssumptionConflict " << std::endl;
// Uniqueness is checked in the bit-vector proof
@@ -564,13 +575,13 @@ ClauseId TSatProof<Solver>::registerAssumptionConflict(const typename Solver::TL
}
ClauseId new_id = ProofManager::currentPM()->nextId();
d_assumptionConflicts.insert(new_id);
- LitVector* vec_confl = new LitVector(confl.size());
+ LitVector* vec_confl = new LitVector(confl.size());
for (int i = 0; i < confl.size(); ++i) {
vec_confl->operator[](i) = confl[i];
}
if (Debug.isOn("proof:sat:detailed")) {
printClause<Solver>(*vec_confl);
- Debug("proof:sat:detailed") << "\n";
+ Debug("proof:sat:detailed") << "\n";
}
d_assumptionConflictsDebug[new_id] = vec_confl;
@@ -578,7 +589,7 @@ ClauseId TSatProof<Solver>::registerAssumptionConflict(const typename Solver::TL
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::removedDfs(typename Solver::TLit lit, LitSet* removedSet, LitVector& removeStack, LitSet& inClause, LitSet& seen) {
// if we already added the literal return
if (seen.count(lit)) {
@@ -605,7 +616,7 @@ void TSatProof<Solver>::removedDfs(typename Solver::TLit lit, LitSet* removedSet
}
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::removeRedundantFromRes(ResChain<Solver>* res, ClauseId id) {
LitSet* removed = res->getRedundant();
if (removed == NULL) {
@@ -636,8 +647,8 @@ void TSatProof<Solver>::removeRedundantFromRes(ResChain<Solver>* res, ClauseId i
}
removed->clear();
}
-
-template <class Solver>
+
+template <class Solver>
void TSatProof<Solver>::registerResolution(ClauseId id, ResChain<Solver>* res) {
Assert(res != NULL);
@@ -661,14 +672,14 @@ void TSatProof<Solver>::registerResolution(ClauseId id, ResChain<Solver>* res) {
/// recording resolutions
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::startResChain(typename Solver::TCRef start) {
ClauseId id = getClauseId(start);
ResChain<Solver>* res = new ResChain<Solver>(id);
d_resStack.push_back(res);
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::startResChain(typename Solver::TLit start) {
ClauseId id = getUnitId(start);
ResChain<Solver>* res = new ResChain<Solver>(id);
@@ -676,7 +687,7 @@ void TSatProof<Solver>::startResChain(typename Solver::TLit start) {
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::addResolutionStep(typename Solver::TLit lit,
typename Solver::TCRef clause, bool sign) {
ClauseId id = registerClause(clause, LEARNT);
@@ -684,7 +695,7 @@ void TSatProof<Solver>::addResolutionStep(typename Solver::TLit lit,
res->addStep(lit, id, sign);
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::endResChain(ClauseId id) {
Debug("proof:sat:detailed") <<"endResChain " << id << "\n";
Assert(d_resStack.size() > 0);
@@ -694,7 +705,7 @@ void TSatProof<Solver>::endResChain(ClauseId id) {
}
-// template <class Solver>
+// template <class Solver>
// void TSatProof<Solver>::endResChain(typename Solver::TCRef clause) {
// Assert(d_resStack.size() > 0);
// ClauseId id = registerClause(clause, LEARNT);
@@ -703,7 +714,7 @@ void TSatProof<Solver>::endResChain(ClauseId id) {
// d_resStack.pop_back();
// }
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::endResChain(typename Solver::TLit lit) {
Assert(d_resStack.size() > 0);
ClauseId id = registerUnitClause(lit, LEARNT);
@@ -715,14 +726,14 @@ void TSatProof<Solver>::endResChain(typename Solver::TLit lit) {
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::cancelResChain() {
Assert(d_resStack.size() > 0);
d_resStack.pop_back();
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::storeLitRedundant(typename Solver::TLit lit) {
Assert(d_resStack.size() > 0);
ResChain<Solver>* res = d_resStack.back();
@@ -730,18 +741,18 @@ void TSatProof<Solver>::storeLitRedundant(typename Solver::TLit lit) {
}
/// constructing resolutions
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::resolveOutUnit(typename Solver::TLit lit) {
ClauseId id = resolveUnit(~lit);
ResChain<Solver>* res = d_resStack.back();
res->addStep(lit, id, !sign(lit));
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::storeUnitResolution(typename Solver::TLit lit) {
Debug("cores") << "STORE UNIT RESOLUTION" << std::endl;
resolveUnit(lit);
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::resolveUnit(typename Solver::TLit lit) {
// first check if we already have a resolution for lit
if(isUnit(lit)) {
@@ -771,12 +782,12 @@ ClauseId TSatProof<Solver>::resolveUnit(typename Solver::TLit lit) {
registerResolution(unit_id, res);
return unit_id;
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::toStream(std::ostream& out) {
Debug("proof:sat") << "TSatProof<Solver>::printProof\n";
Unimplemented("native proof printing not supported yet");
}
-template <class Solver>
+template <class Solver>
ClauseId TSatProof<Solver>::storeUnitConflict(typename Solver::TLit conflict_lit,
ClauseKind kind) {
Debug("cores") << "STORE UNIT CONFLICT" << std::endl;
@@ -786,7 +797,7 @@ ClauseId TSatProof<Solver>::storeUnitConflict(typename Solver::TLit conflict_lit
Debug("proof:sat:detailed") <<"storeUnitConflict " << d_unitConflictId << "\n";
return d_unitConflictId;
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::finalizeProof(typename Solver::TCRef conflict_ref) {
Assert(d_resStack.size() == 0);
Assert(conflict_ref != Solver::TCRef_Undef);
@@ -828,7 +839,7 @@ void TSatProof<Solver>::finalizeProof(typename Solver::TCRef conflict_ref) {
}
/// CRef manager
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::updateCRef(typename Solver::TCRef oldref,
typename Solver::TCRef newref) {
if (d_clauseId.find(oldref) == d_clauseId.end()) {
@@ -840,7 +851,7 @@ void TSatProof<Solver>::updateCRef(typename Solver::TCRef oldref,
d_temp_clauseId[newref] = id;
d_temp_idClause[id] = newref;
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::finishUpdateCRef() {
d_clauseId.swap(d_temp_clauseId);
d_temp_clauseId.clear();
@@ -848,7 +859,7 @@ void TSatProof<Solver>::finishUpdateCRef() {
d_idClause.swap(d_temp_idClause);
d_temp_idClause.clear();
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::markDeleted(typename Solver::TCRef clause) {
if (d_clauseId.find(clause) != d_clauseId.end()) {
ClauseId id = getClauseId(clause);
@@ -866,18 +877,18 @@ void TSatProof<Solver>::markDeleted(typename Solver::TCRef clause) {
// template<>
// void toSatClause< ::BVMinisat::Solver> (const BVMinisat::Solver::TClause& minisat_cl,
// prop::SatClause& sat_cl) {
-
+
// prop::BVMinisatSatSolver::toSatClause(minisat_cl, sat_cl);
// }
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::constructProof(ClauseId conflict) {
collectClauses(conflict);
}
-template <class Solver>
+template <class Solver>
std::string TSatProof<Solver>::clauseName(ClauseId id) {
std::ostringstream os;
if (isInputClause(id)) {
@@ -893,7 +904,7 @@ std::string TSatProof<Solver>::clauseName(ClauseId id) {
}
}
-template <class Solver>
+template <class Solver>
prop::SatClause* TSatProof<Solver>::buildClause(ClauseId id) {
if (isUnit(id)) {
typename Solver::TLit lit = getUnit(id);
@@ -915,7 +926,7 @@ prop::SatClause* TSatProof<Solver>::buildClause(ClauseId id) {
return clause;
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::collectClauses(ClauseId id) {
if (d_seenInputs.find(id) != d_seenInputs.end() ||
d_seenLemmas.find(id) != d_seenLemmas.end() ||
@@ -948,7 +959,7 @@ void TSatProof<Solver>::collectClauses(ClauseId id) {
}
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::collectClausesUsed(IdToSatClause& inputs,
IdToSatClause& lemmas) {
inputs = d_seenInputs;
@@ -959,13 +970,13 @@ void TSatProof<Solver>::collectClausesUsed(IdToSatClause& inputs,
);
}
-template <class Solver>
+template <class Solver>
void TSatProof<Solver>::storeClauseGlue(ClauseId clause, int glue) {
Assert (d_glueMap.find(clause) == d_glueMap.end());
d_glueMap.insert(std::make_pair(clause, glue));
}
-template <class Solver>
+template <class Solver>
TSatProof<Solver>::Statistics::Statistics(const std::string& prefix)
: d_numLearnedClauses("satproof::"+prefix+"::NumLearnedClauses", 0)
, d_numLearnedInProof("satproof::"+prefix+"::NumLearnedInProof", 0)
@@ -985,7 +996,7 @@ TSatProof<Solver>::Statistics::Statistics(const std::string& prefix)
smtStatisticsRegistry()->registerStat(&d_usedClauseGlue);
}
-template <class Solver>
+template <class Solver>
TSatProof<Solver>::Statistics::~Statistics() {
smtStatisticsRegistry()->unregisterStat(&d_numLearnedClauses);
smtStatisticsRegistry()->unregisterStat(&d_numLearnedInProof);
@@ -999,7 +1010,7 @@ TSatProof<Solver>::Statistics::~Statistics() {
/// LFSCSatProof class
-template <class Solver>
+template <class Solver>
void LFSCSatProof<Solver>::printResolution(ClauseId id, std::ostream& out, std::ostream& paren) {
out << "(satlem_simplify _ _ _ ";
@@ -1029,7 +1040,7 @@ void LFSCSatProof<Solver>::printResolution(ClauseId id, std::ostream& out, std::
}
/// LFSCSatProof class
-template <class Solver>
+template <class Solver>
void LFSCSatProof<Solver>::printAssumptionsResolution(ClauseId id, std::ostream& out, std::ostream& paren) {
Assert (this->isAssumptionConflict(id));
// print the resolution proving the assumption conflict
@@ -1037,7 +1048,7 @@ void LFSCSatProof<Solver>::printAssumptionsResolution(ClauseId id, std::ostream&
// resolve out assumptions to prove empty clause
out << "(satlem_simplify _ _ _ ";
std::vector<typename Solver::TLit>& confl = *(this->d_assumptionConflictsDebug[id]);
-
+
Assert (confl.size());
for (unsigned i = 0; i < confl.size(); ++i) {
@@ -1045,8 +1056,8 @@ void LFSCSatProof<Solver>::printAssumptionsResolution(ClauseId id, std::ostream&
out <<"(";
out << (lit.isNegated() ? "Q" : "R") <<" _ _ ";
}
-
- out << this->clauseName(id)<< " ";
+
+ out << this->clauseName(id)<< " ";
for (int i = confl.size() - 1; i >= 0; --i) {
prop::SatLiteral lit = toSatLiteral<Solver>(confl[i]);
prop::SatVariable v = lit.getSatVariable();
@@ -1073,20 +1084,20 @@ void LFSCSatProof<Solver>::printResolutions(std::ostream& out, std::ostream& par
template <class Solver>
void LFSCSatProof<Solver>::printResolutionEmptyClause(std::ostream& out, std::ostream& paren) {
- printResolution(this->d_emptyClauseId, out, paren);
+ printResolution(this->d_emptyClauseId, out, paren);
}
inline std::ostream& operator<<(std::ostream& out, CVC4::ClauseKind k) {
switch(k) {
case CVC4::INPUT:
- out << "INPUT";
+ out << "INPUT";
break;
case CVC4::THEORY_LEMMA:
- out << "THEORY_LEMMA";
+ out << "THEORY_LEMMA";
break;
case CVC4::LEARNT:
- out << "LEARNT";
+ out << "LEARNT";
break;
default:
out << "ClauseKind Unknown! [" << unsigned(k) << "]";
diff --git a/src/proof/skolemization_manager.cpp b/src/proof/skolemization_manager.cpp
new file mode 100644
index 000000000..12fea82ad
--- /dev/null
+++ b/src/proof/skolemization_manager.cpp
@@ -0,0 +1,68 @@
+/********************* */
+/*! \file skolemization_manager.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
+ **/
+
+#include "proof/skolemization_manager.h"
+
+namespace CVC4 {
+
+void SkolemizationManager::registerSkolem(Node disequality, Node skolem) {
+ Debug("pf::pm") << "SkolemizationManager: registerSkolem: disequality = " << disequality << ", skolem = " << skolem << std::endl;
+
+ if (isSkolem(skolem)) {
+ Assert(d_skolemToDisequality[skolem] == disequality);
+ return;
+ }
+
+ d_disequalityToSkolem[disequality] = skolem;
+ d_skolemToDisequality[skolem] = disequality;
+}
+
+bool SkolemizationManager::hasSkolem(Node disequality) {
+ return (d_disequalityToSkolem.find(disequality) != d_disequalityToSkolem.end());
+}
+
+Node SkolemizationManager::getSkolem(Node disequality) {
+ Debug("pf::pm") << "SkolemizationManager: getSkolem( ";
+ Assert (d_disequalityToSkolem.find(disequality) != d_disequalityToSkolem.end());
+ Debug("pf::pm") << disequality << " ) = " << d_disequalityToSkolem[disequality] << std::endl;
+ return d_disequalityToSkolem[disequality];
+}
+
+Node SkolemizationManager::getDisequality(Node skolem) {
+ Assert (d_skolemToDisequality.find(skolem) != d_skolemToDisequality.end());
+ return d_skolemToDisequality[skolem];
+}
+
+bool SkolemizationManager::isSkolem(Node skolem) {
+ return (d_skolemToDisequality.find(skolem) != d_skolemToDisequality.end());
+}
+
+void SkolemizationManager::clear() {
+ Debug("pf::pm") << "SkolemizationManager: clear" << std::endl;
+ d_disequalityToSkolem.clear();
+ d_skolemToDisequality.clear();
+}
+
+std::hash_map<Node, Node, NodeHashFunction>::const_iterator SkolemizationManager::begin() {
+ return d_disequalityToSkolem.begin();
+}
+
+std::hash_map<Node, Node, NodeHashFunction>::const_iterator SkolemizationManager::end() {
+ return d_disequalityToSkolem.end();
+}
+
+} /* CVC4 namespace */
diff --git a/src/proof/skolemization_manager.h b/src/proof/skolemization_manager.h
new file mode 100644
index 000000000..de510e514
--- /dev/null
+++ b/src/proof/skolemization_manager.h
@@ -0,0 +1,55 @@
+/********************* */
+/*! \file skolemization_manager.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__SKOLEMIZATION_MANAGER_H
+#define __CVC4__SKOLEMIZATION_MANAGER_H
+
+#include <iostream>
+#include <map>
+#include "proof/proof.h"
+#include "util/proof.h"
+#include "expr/node.h"
+#include "theory/logic_info.h"
+#include "theory/substitutions.h"
+
+namespace CVC4 {
+
+class SkolemizationManager {
+public:
+ void registerSkolem(Node disequality, Node skolem);
+ bool hasSkolem(Node disequality);
+ Node getSkolem(Node disequality);
+ Node getDisequality(Node skolem);
+ bool isSkolem(Node skolem);
+
+ void clear();
+
+ std::hash_map<Node, Node, NodeHashFunction>::const_iterator begin();
+ std::hash_map<Node, Node, NodeHashFunction>::const_iterator end();
+
+private:
+ std::hash_map<Node, Node, NodeHashFunction> d_disequalityToSkolem;
+ std::hash_map<Node, Node, NodeHashFunction> d_skolemToDisequality;
+};
+
+}/* CVC4 namespace */
+
+
+
+#endif /* __CVC4__SKOLEMIZATION_MANAGER_H */
diff --git a/src/proof/theory_proof.cpp b/src/proof/theory_proof.cpp
index 6679cf896..088275b3f 100644
--- a/src/proof/theory_proof.cpp
+++ b/src/proof/theory_proof.cpp
@@ -1,31 +1,32 @@
/********************* */
/*! \file theory_proof.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
** [[ Add lengthier description here ]]
** \todo document this file
**/
+#include "proof/theory_proof.h"
#include "base/cvc4_assert.h"
#include "context/context.h"
#include "options/bv_options.h"
+#include "proof/arith_proof.h"
#include "proof/array_proof.h"
#include "proof/bitvector_proof.h"
-#include "proof/cnf_proof.h"
+#include "proof/clause_id.h"
#include "proof/cnf_proof.h"
#include "proof/proof_manager.h"
#include "proof/proof_utils.h"
#include "proof/sat_proof.h"
-#include "proof/theory_proof.h"
#include "proof/uf_proof.h"
#include "prop/sat_solver_types.h"
#include "smt/smt_engine.h"
@@ -79,13 +80,16 @@ public:
return theory::LemmaStatus(TNode::null(), 0);
}
void requirePhase(TNode n, bool b) throw() {
+ Debug("theory-proof-debug") << "ProofOutputChannel::requirePhase called" << std::endl;
Trace("theory-proof-debug") << "requirePhase " << n << " " << b << std::endl;
}
bool flipDecision() throw() {
+ Debug("theory-proof-debug") << "ProofOutputChannel::flipDecision called" << std::endl;
AlwaysAssert(false);
return false;
}
void setIncomplete() throw() {
+ Debug("theory-proof-debug") << "ProofOutputChannel::setIncomplete called" << std::endl;
AlwaysAssert(false);
}
};/* class ProofOutputChannel */
@@ -146,11 +150,18 @@ void TheoryProofEngine::registerTheory(theory::Theory* th) {
((theory::bv::TheoryBV*)th)->setProofLog( bvp );
return;
}
+
if (id == theory::THEORY_ARRAY) {
d_theoryProofTable[id] = new LFSCArrayProof((theory::arrays::TheoryArrays*)th, this);
return;
}
- // TODO other theories
+
+ if (id == theory::THEORY_ARITH) {
+ d_theoryProofTable[id] = new LFSCArithProof((theory::arith::TheoryArith*)th, this);
+ return;
+ }
+
+ // TODO other theories
}
}
}
@@ -164,9 +175,12 @@ void TheoryProofEngine::registerTerm(Expr term) {
if (d_registrationCache.count(term)) {
return;
}
+ Debug("pf::tp") << "TheoryProofEngine::registerTerm: registering new term: " << term << std::endl;
theory::TheoryId theory_id = theory::Theory::theoryOf(term);
+ Debug("pf::tp") << "Term's theory: " << theory_id << std::endl;
+
// don't need to register boolean terms
if (theory_id == theory::THEORY_BUILTIN ||
term.getKind() == kind::ITE) {
@@ -178,20 +192,33 @@ void TheoryProofEngine::registerTerm(Expr term) {
}
if (!supportedTheory(theory_id)) return;
-
+
getTheoryProof(theory_id)->registerTerm(term);
d_registrationCache.insert(term);
}
theory::TheoryId TheoryProofEngine::getTheoryForLemma(ClauseId id) {
- // TODO: now CNF proof has a map from formula to proof rule
- // that should be checked to figure out what theory is responsible for this
ProofManager* pm = ProofManager::currentPM();
- if (pm->getLogic() == "QF_UF") return theory::THEORY_UF;
- if (pm->getLogic() == "QF_BV") return theory::THEORY_BV;
- if (pm->getLogic() == "ALL_SUPPORTED") return theory::THEORY_BV;
- Unreachable();
+ Debug("pf::tp") << "TheoryProofEngine::getTheoryForLemma( " << id << " )"
+ << " = " << pm->getCnfProof()->getOwnerTheory(id) << std::endl;
+
+ if ((pm->getLogic() == "QF_UFLIA") || (pm->getLogic() == "QF_UFLRA")) {
+ Debug("pf::tp") << "TheoryProofEngine::getTheoryForLemma: special hack for Arithmetic-with-holes support. "
+ << "Returning THEORY_ARITH" << std::endl;
+ return theory::THEORY_ARITH;
+ }
+
+ return pm->getCnfProof()->getOwnerTheory(id);
+
+ // if (pm->getLogic() == "QF_UF") return theory::THEORY_UF;
+ // if (pm->getLogic() == "QF_BV") return theory::THEORY_BV;
+ // if (pm->getLogic() == "QF_AX") return theory::THEORY_ARRAY;
+ // if (pm->getLogic() == "ALL_SUPPORTED") return theory::THEORY_BV;
+
+ // Debug("pf::tp") << "Unsupported logic (" << pm->getLogic() << ")" << std::endl;
+
+ // Unreachable();
}
void LFSCTheoryProofEngine::bind(Expr term, LetMap& map, Bindings& let_order) {
@@ -245,6 +272,9 @@ void LFSCTheoryProofEngine::printLetTerm(Expr term, std::ostream& os) {
void LFSCTheoryProofEngine::printTheoryTerm(Expr term, std::ostream& os, const LetMap& map) {
theory::TheoryId theory_id = theory::Theory::theoryOf(term);
+ Debug("pf::tp") << std::endl << "LFSCTheoryProofEngine::printTheoryTerm: term = " << term
+ << ", theory_id = " << theory_id << std::endl;
+
// boolean terms and ITEs are special because they
// are common to all theories
if (theory_id == theory::THEORY_BUILTIN ||
@@ -254,39 +284,55 @@ void LFSCTheoryProofEngine::printTheoryTerm(Expr term, std::ostream& os, const L
return;
}
// dispatch to proper theory
- getTheoryProof(theory_id)->printTerm(term, os, map);
+ getTheoryProof(theory_id)->printOwnedTerm(term, os, map);
}
void LFSCTheoryProofEngine::printSort(Type type, std::ostream& os) {
if (type.isSort()) {
- getTheoryProof(theory::THEORY_UF)->printSort(type, os);
+ getTheoryProof(theory::THEORY_UF)->printOwnedSort(type, os);
return;
}
if (type.isBitVector()) {
- getTheoryProof(theory::THEORY_BV)->printSort(type, os);
+ getTheoryProof(theory::THEORY_BV)->printOwnedSort(type, os);
return;
}
if (type.isArray()) {
- getTheoryProof(theory::THEORY_ARRAY)->printSort(type, os);
+ getTheoryProof(theory::THEORY_ARRAY)->printOwnedSort(type, os);
+ return;
+ }
+
+ if (type.isInteger() || type.isReal()) {
+ getTheoryProof(theory::THEORY_ARITH)->printOwnedSort(type, os);
+ return;
+ }
+
+ if (type.isBoolean()) {
+ getTheoryProof(theory::THEORY_BOOL)->printOwnedSort(type, os);
return;
}
+
Unreachable();
}
-void LFSCTheoryProofEngine::printAssertions(std::ostream& os, std::ostream& paren) {
- unsigned counter = 0;
+void LFSCTheoryProofEngine::registerTermsFromAssertions() {
ProofManager::assertions_iterator it = ProofManager::currentPM()->begin_assertions();
ProofManager::assertions_iterator end = ProofManager::currentPM()->end_assertions();
- // collect declarations first
for(; it != end; ++it) {
registerTerm(*it);
}
- printDeclarations(os, paren);
+}
+
+void LFSCTheoryProofEngine::printAssertions(std::ostream& os, std::ostream& paren) {
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printAssertions called" << std::endl << std::endl;
+
+ unsigned counter = 0;
+ ProofManager::assertions_iterator it = ProofManager::currentPM()->begin_assertions();
+ ProofManager::assertions_iterator end = ProofManager::currentPM()->end_assertions();
- it = ProofManager::currentPM()->begin_assertions();
for (; it != end; ++it) {
+ Debug("pf::tp") << "printAssertions: assertion is: " << *it << std::endl;
// FIXME: merge this with counter
os << "(% A" << counter++ << " (th_holds ";
printLetTerm(*it, os);
@@ -295,13 +341,40 @@ void LFSCTheoryProofEngine::printAssertions(std::ostream& os, std::ostream& pare
}
//store map between assertion and counter
// ProofManager::currentPM()->setAssertion( *it );
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printAssertions done" << std::endl << std::endl;
+}
+
+void LFSCTheoryProofEngine::printSortDeclarations(std::ostream& os, std::ostream& paren) {
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printSortDeclarations called" << std::endl << std::endl;
+
+ TheoryProofTable::const_iterator it = d_theoryProofTable.begin();
+ TheoryProofTable::const_iterator end = d_theoryProofTable.end();
+ for (; it != end; ++it) {
+ it->second->printSortDeclarations(os, paren);
+ }
+
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printSortDeclarations done" << std::endl << std::endl;
+}
+
+void LFSCTheoryProofEngine::printTermDeclarations(std::ostream& os, std::ostream& paren) {
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printTermDeclarations called" << std::endl << std::endl;
+
+ TheoryProofTable::const_iterator it = d_theoryProofTable.begin();
+ TheoryProofTable::const_iterator end = d_theoryProofTable.end();
+ for (; it != end; ++it) {
+ it->second->printTermDeclarations(os, paren);
+ }
+
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printTermDeclarations done" << std::endl << std::endl;
}
-void LFSCTheoryProofEngine::printDeclarations(std::ostream& os, std::ostream& paren) {
+void LFSCTheoryProofEngine::printDeferredDeclarations(std::ostream& os, std::ostream& paren) {
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printDeferredDeclarations called" << std::endl;
+
TheoryProofTable::const_iterator it = d_theoryProofTable.begin();
TheoryProofTable::const_iterator end = d_theoryProofTable.end();
for (; it != end; ++it) {
- it->second->printDeclarations(os, paren);
+ it->second->printDeferredDeclarations(os, paren);
}
}
@@ -313,6 +386,16 @@ void LFSCTheoryProofEngine::printTheoryLemmas(const IdToSatClause& lemmas,
IdToSatClause::const_iterator it = lemmas.begin();
IdToSatClause::const_iterator end = lemmas.end();
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printTheoryLemmas: checking lemma owners..." << std::endl;
+
+ for (; it != end; ++it) {
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printTheoryLemmas: new lemma" << std::endl;
+ ClauseId id = it->first;
+ Debug("pf::tp") << "\tLemma = " << id
+ << ". Owner theory: " << pm->getCnfProof()->getOwnerTheory(id) << std::endl;
+ }
+ it = lemmas.begin();
+
// BitVector theory is special case: must know all
// conflicts needed ahead of time for resolution
// proof lemmas
@@ -353,13 +436,22 @@ void LFSCTheoryProofEngine::printTheoryLemmas(const IdToSatClause& lemmas,
it = lemmas.begin();
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printTheoryLemmas: printing lemmas..." << std::endl;
+
for (; it != end; ++it) {
+ Debug("pf::tp") << "LFSCTheoryProofEngine::printTheoryLemmas: printing a new lemma!" << std::endl;
+
+ // Debug("pf::tp") << "\tLemma = " << it->first << ", " << *(it->second) << std::endl;
ClauseId id = it->first;
+ Debug("pf::tp") << "Owner theory:" << pm->getCnfProof()->getOwnerTheory(id) << std::endl;
const prop::SatClause* clause = it->second;
// printing clause as it appears in resolution proof
os << "(satlem _ _ ";
std::ostringstream clause_paren;
+
+ Debug("pf::tp") << "CnfProof printing clause..." << std::endl;
pm->getCnfProof()->printClause(*clause, os, clause_paren);
+ Debug("pf::tp") << "CnfProof printing clause - Done!" << std::endl;
std::vector<Expr> clause_expr;
for(unsigned i = 0; i < clause->size(); ++i) {
@@ -373,10 +465,14 @@ void LFSCTheoryProofEngine::printTheoryLemmas(const IdToSatClause& lemmas,
clause_expr.push_back(expr_lit);
}
+ Debug("pf::tp") << "Expression printing done!" << std::endl;
+
// query appropriate theory for proof of clause
theory::TheoryId theory_id = getTheoryForLemma(id);
+ Debug("pf::tp") << "Get theory lemma from " << theory_id << "..." << std::endl;
Debug("theory-proof-debug") << ";; Get theory lemma from " << theory_id << "..." << std::endl;
getTheoryProof(theory_id)->printTheoryLemmaProof(clause_expr, os, paren);
+ Debug("pf::tp") << "Get theory lemma from " << theory_id << "... DONE!" << std::endl;
// os << " (clausify_false trust)";
os << clause_paren.str();
os << "( \\ " << pm->getLemmaClauseName(id) <<"\n";
@@ -385,15 +481,19 @@ void LFSCTheoryProofEngine::printTheoryLemmas(const IdToSatClause& lemmas,
}
void LFSCTheoryProofEngine::printBoundTerm(Expr term, std::ostream& os, const LetMap& map) {
+ // Debug("pf::tp") << "LFSCTheoryProofEngine::printBoundTerm( " << term << " ) " << std::endl;
+
LetMap::const_iterator it = map.find(term);
- Assert (it != map.end());
- unsigned id = it->second.id;
- unsigned count = it->second.count;
- if (count > LET_COUNT) {
- os <<"let"<<id;
- return;
+ if (it != map.end()) {
+ unsigned id = it->second.id;
+ unsigned count = it->second.count;
+ if (count > LET_COUNT) {
+ os <<"let"<<id;
+ return;
+ }
}
- printTheoryTerm(term, os, map);
+
+ printTheoryTerm(term, os, map);
}
void LFSCTheoryProofEngine::printCoreTerm(Expr term, std::ostream& os, const LetMap& map) {
@@ -513,32 +613,83 @@ void TheoryProof::printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream&
th = new theory::arrays::TheoryArrays(&fakeContext, &fakeContext, oc, v,
ProofManager::currentPM()->getLogicInfo(),
"replay::");
+ } else if (d_theory->getId() == theory::THEORY_ARITH) {
+ Trace("theory-proof-debug") << "Arith proofs currently not supported. Use 'trust'" << std::endl;
+ os << " (clausify_false trust)";
+ return;
} else {
InternalError(std::string("can't generate theory-proof for ") + ProofManager::currentPM()->getLogic());
}
+
+ Debug("pf::tp") << "TheoryProof::printTheoryLemmaProof - calling th->ProduceProofs()" << std::endl;
th->produceProofs();
+ Debug("pf::tp") << "TheoryProof::printTheoryLemmaProof - th->ProduceProofs() DONE" << std::endl;
+
MyPreRegisterVisitor preRegVisitor(th);
for( unsigned i=0; i<lemma.size(); i++ ){
Node lit = Node::fromExpr( lemma[i] ).negate();
- Trace("theory-proof-debug") << "; preregistering and asserting " << lit << std::endl;
+ Trace("pf::tp") << "; preregistering and asserting " << lit << std::endl;
NodeVisitor<MyPreRegisterVisitor>::run(preRegVisitor, lit);
th->assertFact(lit, false);
}
+
+ Debug("pf::tp") << "TheoryProof::printTheoryLemmaProof - calling th->check()" << std::endl;
th->check(theory::Theory::EFFORT_FULL);
+ Debug("pf::tp") << "TheoryProof::printTheoryLemmaProof - th->check() DONE" << std::endl;
+
if(oc.d_conflict.isNull()) {
- Trace("theory-proof-debug") << "; conflict is null" << std::endl;
+ Trace("pf::tp") << "; conflict is null" << std::endl;
Assert(!oc.d_lemma.isNull());
- Trace("theory-proof-debug") << "; ++ but got lemma: " << oc.d_lemma << std::endl;
- Trace("theory-proof-debug") << "; asserting " << oc.d_lemma[1].negate() << std::endl;
- th->assertFact(oc.d_lemma[1].negate(), false);
+ Trace("pf::tp") << "; ++ but got lemma: " << oc.d_lemma << std::endl;
+
+ // Original, as in Liana's branch
+ // Trace("pf::tp") << "; asserting " << oc.d_lemma[1].negate() << std::endl;
+ // th->assertFact(oc.d_lemma[1].negate(), false);
+ // th->check(theory::Theory::EFFORT_FULL);
+
+ // Altered version, to handle OR lemmas
+
+ if (oc.d_lemma.getKind() == kind::OR) {
+ Debug("pf::tp") << "OR lemma. Negating each child separately" << std::endl;
+ for (unsigned i = 0; i < oc.d_lemma.getNumChildren(); ++i) {
+ if (oc.d_lemma[i].getKind() == kind::NOT) {
+ Trace("pf::tp") << "; asserting fact: " << oc.d_lemma[i][0] << std::endl;
+ th->assertFact(oc.d_lemma[i][0], false);
+ }
+ else {
+ Trace("pf::tp") << "; asserting fact: " << oc.d_lemma[i].notNode() << std::endl;
+ th->assertFact(oc.d_lemma[i].notNode(), false);
+ }
+ }
+ }
+ else {
+ Unreachable();
+
+ Assert(oc.d_lemma.getKind() == kind::NOT);
+ Debug("pf::tp") << "NOT lemma" << std::endl;
+ Trace("pf::tp") << "; asserting fact: " << oc.d_lemma[0] << std::endl;
+ th->assertFact(oc.d_lemma[0], false);
+ }
+
+ // Trace("pf::tp") << "; ++ but got lemma: " << oc.d_lemma << std::endl;
+ // Trace("pf::tp") << "; asserting " << oc.d_lemma[1].negate() << std::endl;
+ // th->assertFact(oc.d_lemma[1].negate(), false);
+
+ //
th->check(theory::Theory::EFFORT_FULL);
}
+ Debug("pf::tp") << "Calling oc.d_proof->toStream(os)" << std::endl;
oc.d_proof->toStream(os);
+ Debug("pf::tp") << "Calling oc.d_proof->toStream(os) -- DONE!" << std::endl;
+
+ Debug("pf::tp") << "About to delete the theory solver used for proving the lemma... " << std::endl;
delete th;
+ Debug("pf::tp") << "About to delete the theory solver used for proving the lemma: DONE! " << std::endl;
}
bool TheoryProofEngine::supportedTheory(theory::TheoryId id) {
return (id == theory::THEORY_ARRAY ||
+ id == theory::THEORY_ARITH ||
id == theory::THEORY_BV ||
id == theory::THEORY_UF ||
id == theory::THEORY_BOOL);
@@ -560,7 +711,7 @@ void BooleanProof::registerTerm(Expr term) {
}
}
-void LFSCBooleanProof::printTerm(Expr term, std::ostream& os, const LetMap& map) {
+void LFSCBooleanProof::printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) {
Assert (term.getType().isBoolean());
if (term.isVariable()) {
os << "(p_app " << ProofManager::sanitize(term) <<")";
@@ -611,11 +762,16 @@ void LFSCBooleanProof::printTerm(Expr term, std::ostream& os, const LetMap& map)
}
-void LFSCBooleanProof::printSort(Type type, std::ostream& os) {
+void LFSCBooleanProof::printOwnedSort(Type type, std::ostream& os) {
Assert (type.isBoolean());
os << "Bool";
}
-void LFSCBooleanProof::printDeclarations(std::ostream& os, std::ostream& paren) {
+
+void LFSCBooleanProof::printSortDeclarations(std::ostream& os, std::ostream& paren) {
+ // Nothing to do here at this point.
+}
+
+void LFSCBooleanProof::printTermDeclarations(std::ostream& os, std::ostream& paren) {
for (ExprSet::const_iterator it = d_declarations.begin(); it != d_declarations.end(); ++it) {
Expr term = *it;
@@ -626,6 +782,10 @@ void LFSCBooleanProof::printDeclarations(std::ostream& os, std::ostream& paren)
}
}
+void LFSCBooleanProof::printDeferredDeclarations(std::ostream& os, std::ostream& paren) {
+ // Nothing to do here at this point.
+}
+
void LFSCBooleanProof::printTheoryLemmaProof(std::vector<Expr>& lemma,
std::ostream& os,
std::ostream& paren) {
diff --git a/src/proof/theory_proof.h b/src/proof/theory_proof.h
index d997d6e23..54c86f3f3 100644
--- a/src/proof/theory_proof.h
+++ b/src/proof/theory_proof.h
@@ -1,19 +1,18 @@
/********************* */
/*! \file theory_proof.h
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: Morgan Deters
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief A manager for UfProofs.
-**
-** A manager for UfProofs.
-**
-**
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
**/
#include "cvc4_private.h"
@@ -21,33 +20,32 @@
#ifndef __CVC4__THEORY_PROOF_H
#define __CVC4__THEORY_PROOF_H
-#include "util/proof.h"
-#include "expr/expr.h"
-#include "prop/sat_solver_types.h"
#include <ext/hash_set>
#include <iosfwd>
+#include "expr/expr.h"
+#include "proof/clause_id.h"
+#include "prop/sat_solver_types.h"
+#include "util/proof.h"
namespace CVC4 {
namespace theory {
class Theory;
-}
-
-typedef unsigned ClauseId;
+} /* namespace CVC4::theory */
struct LetCount {
static unsigned counter;
static void resetCounter() { counter = 0; }
static unsigned newId() { return ++counter; }
-
+
unsigned count;
unsigned id;
LetCount()
: count(0)
, id(-1)
{}
-
+
void increment() { ++count; }
LetCount(unsigned i)
: count(1)
@@ -66,7 +64,7 @@ struct LetCount {
count = rhs.count;
return *this;
}
-};
+};
struct LetOrderElement {
Expr expr;
@@ -85,10 +83,9 @@ struct LetOrderElement {
typedef __gnu_cxx::hash_map < ClauseId, prop::SatClause* > IdToSatClause;
typedef __gnu_cxx::hash_map<Expr, LetCount, ExprHashFunction> LetMap;
-typedef std::vector<LetOrderElement> Bindings;
+typedef std::vector<LetOrderElement> Bindings;
class TheoryProof;
-typedef unsigned ClauseId;
typedef __gnu_cxx::hash_set<Expr, ExprHashFunction > ExprSet;
typedef std::map<theory::TheoryId, TheoryProof* > TheoryProofTable;
@@ -126,6 +123,14 @@ public:
virtual void printSort(Type type, std::ostream& os) = 0;
/**
+ * Go over the assertions and register all terms with the theories.
+ *
+ * @param os
+ * @param paren closing parenthesis
+ */
+ virtual void registerTermsFromAssertions() = 0;
+
+ /**
* Print the theory assertions (arbitrary formulas over
* theory atoms)
*
@@ -133,6 +138,14 @@ public:
* @param paren closing parenthesis
*/
virtual void printAssertions(std::ostream& os, std::ostream& paren) = 0;
+ /**
+ * Print variable declarations that need to appear within the proof,
+ * e.g. skolemized variables.
+ *
+ * @param os
+ * @param paren closing parenthesis
+ */
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren) = 0;
/**
* Print proofs of all the theory lemmas (must prove
@@ -170,11 +183,14 @@ public:
LFSCTheoryProofEngine()
: TheoryProofEngine() {}
- void printDeclarations(std::ostream& os, std::ostream& paren);
+ void registerTermsFromAssertions();
+ void printSortDeclarations(std::ostream& os, std::ostream& paren);
+ void printTermDeclarations(std::ostream& os, std::ostream& paren);
virtual void printCoreTerm(Expr term, std::ostream& os, const LetMap& map);
virtual void printLetTerm(Expr term, std::ostream& os);
virtual void printBoundTerm(Expr term, std::ostream& os, const LetMap& map);
virtual void printAssertions(std::ostream& os, std::ostream& paren);
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren);
virtual void printTheoryLemmas(const IdToSatClause& lemmas,
std::ostream& os,
std::ostream& paren);
@@ -191,41 +207,74 @@ public:
: d_theory(th)
, d_proofEngine(proofEngine)
{}
- virtual ~TheoryProof() {};
- /**
- * Print a term belonging to this theory.
- *
+ virtual ~TheoryProof() {};
+ /**
+ * Print a term belonging some theory, not neccessarily this one.
+ *
* @param term expresion representing term
* @param os output stream
*/
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map) = 0;
- /**
- * Print the proof representation of the given type.
- *
- * @param type
- * @param os
+ void printTerm(Expr term, std::ostream& os, const LetMap& map) {
+ d_proofEngine->printBoundTerm(term, os, map);
+ }
+ /**
+ * Print a term belonging to THIS theory.
+ *
+ * @param term expresion representing term
+ * @param os output stream
*/
- virtual void printSort(Type type, std::ostream& os) = 0;
- /**
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) = 0;
+ /**
+ * Print the proof representation of the given type that belongs to some theory.
+ *
+ * @param type
+ * @param os
+ */
+ void printSort(Type type, std::ostream& os) {
+ d_proofEngine->printSort(type, os);
+ }
+ /**
+ * Print the proof representation of the given type that belongs to THIS theory.
+ *
+ * @param type
+ * @param os
+ */
+ virtual void printOwnedSort(Type type, std::ostream& os) = 0;
+ /**
* Print a proof for the theory lemmas. Must prove
* clause representing lemmas to be used in resolution proof.
- *
+ *
* @param os output stream
*/
virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren);
- /**
- * Print the variable/sorts declarations for this theory.
- *
- * @param os
- * @param paren
+ /**
+ * Print the sorts declarations for this theory.
+ *
+ * @param os
+ * @param paren
*/
- virtual void printDeclarations(std::ostream& os, std::ostream& paren) = 0;
- /**
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ /**
+ * Print the term declarations for this theory.
+ *
+ * @param os
+ * @param paren
+ */
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ /**
+ * Print any deferred variable/sorts declarations for this theory
+ * (those that need to appear inside the actual proof).
+ *
+ * @param os
+ * @param paren
+ */
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ /**
* Register a term of this theory that appears in the proof.
- *
- * @param term
+ *
+ * @param term
*/
- virtual void registerTerm(Expr term) = 0;
+ virtual void registerTerm(Expr term) = 0;
};
class BooleanProof : public TheoryProof {
@@ -235,12 +284,14 @@ public:
BooleanProof(TheoryProofEngine* proofEngine);
virtual void registerTerm(Expr term);
-
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map) = 0;
- virtual void printSort(Type type, std::ostream& os) = 0;
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) = 0;
+
+ virtual void printOwnedSort(Type type, std::ostream& os) = 0;
virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren) = 0;
- virtual void printDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren) = 0;
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren) = 0;
};
class LFSCBooleanProof : public BooleanProof {
@@ -248,13 +299,14 @@ public:
LFSCBooleanProof(TheoryProofEngine* proofEngine)
: BooleanProof(proofEngine)
{}
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map);
- virtual void printSort(Type type, std::ostream& os);
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map);
+ virtual void printOwnedSort(Type type, std::ostream& os);
virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren);
- virtual void printDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren);
};
-
} /* CVC4 namespace */
#endif /* __CVC4__THEORY_PROOF_H */
diff --git a/src/proof/uf_proof.cpp b/src/proof/uf_proof.cpp
index ec0d90ae7..32ca122b0 100644
--- a/src/proof/uf_proof.cpp
+++ b/src/proof/uf_proof.cpp
@@ -1,18 +1,18 @@
/********************* */
/*! \file uf_proof.cpp
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: none
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief [[ Add one-line brief description here ]]
-**
-** [[ Add lengthier description here ]]
-** \todo document this file
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
**/
#include "proof/theory_proof.h"
@@ -21,10 +21,7 @@
#include "theory/uf/theory_uf.h"
#include <stack>
-using namespace CVC4;
-using namespace CVC4::theory;
-using namespace CVC4::theory::uf;
-
+namespace CVC4 {
inline static Node eqNode(TNode n1, TNode n2) {
return NodeManager::currentNM()->mkNode(n1.getType().isBoolean() ? kind::IFF : kind::EQUAL, n1, n2);
@@ -32,14 +29,14 @@ inline static Node eqNode(TNode n1, TNode n2) {
// congrence matching term helper
inline static bool match(TNode n1, TNode n2) {
- Debug("mgd") << "match " << n1 << " " << n2 << std::endl;
+ Debug("pf::uf") << "match " << n1 << " " << n2 << std::endl;
if(ProofManager::currentPM()->hasOp(n1)) {
n1 = ProofManager::currentPM()->lookupOp(n1);
}
if(ProofManager::currentPM()->hasOp(n2)) {
n2 = ProofManager::currentPM()->lookupOp(n2);
}
- Debug("mgd") << "+ match " << n1 << " " << n2 << std::endl;
+ Debug("pf::uf") << "+ match " << n1 << " " << n2 << std::endl;
if(n1 == n2) {
return true;
}
@@ -77,6 +74,7 @@ void ProofUF::toStream(std::ostream& out) {
}
void ProofUF::toStreamLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, const LetMap& map) {
+ Debug("pf::uf") << "ProofUF::toStreamLFSC starting" << std::endl;
Debug("lfsc-uf") << "Printing uf proof in LFSC : " << std::endl;
pf->debug_print("lfsc-uf");
Debug("lfsc-uf") << std::endl;
@@ -84,18 +82,18 @@ void ProofUF::toStreamLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqPr
}
Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, unsigned tb, const LetMap& map) {
- Debug("gk::proof") << std::endl << std::endl << "toStreamRecLFSC called. tb = " << tb << " . proof:" << std::endl;
- pf->debug_print("gk::proof");
- Debug("gk::proof") << std::endl;
+ Debug("pf::uf") << std::endl << std::endl << "toStreamRecLFSC called. tb = " << tb << " . proof:" << std::endl;
+ pf->debug_print("pf::uf");
+ Debug("pf::uf") << std::endl;
if(tb == 0) {
- Assert(pf->d_id == eq::MERGED_THROUGH_TRANS);
+ Assert(pf->d_id == theory::eq::MERGED_THROUGH_TRANS);
Assert(!pf->d_node.isNull());
Assert(pf->d_children.size() >= 2);
int neg = -1;
theory::eq::EqProof subTrans;
- subTrans.d_id = eq::MERGED_THROUGH_TRANS;
+ subTrans.d_id = theory::eq::MERGED_THROUGH_TRANS;
subTrans.d_node = pf->d_node;
size_t i = 0;
@@ -108,38 +106,38 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
}
// Handle congruence closures over equalities.
- else if (pf->d_children[i]->d_id==eq::MERGED_THROUGH_CONGRUENCE && pf->d_children[i]->d_node.isNull()) {
- Debug("gk::proof") << "Handling congruence over equalities" << std::endl;
+ else if (pf->d_children[i]->d_id==theory::eq::MERGED_THROUGH_CONGRUENCE && pf->d_children[i]->d_node.isNull()) {
+ Debug("pf::uf") << "Handling congruence over equalities" << std::endl;
// Gather the sequence of consecutive congruence closures.
std::vector<const theory::eq::EqProof *> congruenceClosures;
unsigned count;
- Debug("gk::proof") << "Collecting congruence sequence" << std::endl;
+ Debug("pf::uf") << "Collecting congruence sequence" << std::endl;
for (count = 0;
i + count < pf->d_children.size() &&
- pf->d_children[i + count]->d_id==eq::MERGED_THROUGH_CONGRUENCE &&
+ pf->d_children[i + count]->d_id==theory::eq::MERGED_THROUGH_CONGRUENCE &&
pf->d_children[i + count]->d_node.isNull();
++count) {
- Debug("gk::proof") << "Found a congruence: " << std::endl;
- pf->d_children[i+count]->debug_print("gk::proof");
+ Debug("pf::uf") << "Found a congruence: " << std::endl;
+ pf->d_children[i+count]->debug_print("pf::uf");
congruenceClosures.push_back(pf->d_children[i+count]);
}
- Debug("gk::proof") << "Total number of congruences found: " << congruenceClosures.size() << std::endl;
+ Debug("pf::uf") << "Total number of congruences found: " << congruenceClosures.size() << std::endl;
// Determine if the "target" of the congruence sequence appears right before or right after the sequence.
bool targetAppearsBefore = true;
bool targetAppearsAfter = true;
if ((i == 0) || (i == 1 && neg == 0)) {
- Debug("gk::proof") << "Target does not appear before" << std::endl;
+ Debug("pf::uf") << "Target does not appear before" << std::endl;
targetAppearsBefore = false;
}
if ((i + count >= pf->d_children.size()) ||
(!pf->d_children[i + count]->d_node.isNull() &&
pf->d_children[i + count]->d_node.getKind() == kind::NOT)) {
- Debug("gk::proof") << "Target does not appear after" << std::endl;
+ Debug("pf::uf") << "Target does not appear after" << std::endl;
targetAppearsAfter = false;
}
@@ -162,16 +160,16 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
// Start with the congruence closure closest to the target clause, and work our way back/forward.
if (targetAppearsBefore) {
for (unsigned j = 0; j < count; ++j) {
- if (pf->d_children[i + j]->d_children[0]->d_id != eq::MERGED_THROUGH_REFLEXIVITY)
+ if (pf->d_children[i + j]->d_children[0]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
orderedEqualities.insert(orderedEqualities.begin(), pf->d_children[i + j]->d_children[0]);
- if (pf->d_children[i + j]->d_children[1]->d_id != eq::MERGED_THROUGH_REFLEXIVITY)
+ if (pf->d_children[i + j]->d_children[1]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
orderedEqualities.insert(orderedEqualities.end(), pf->d_children[i + j]->d_children[1]);
}
} else {
for (unsigned j = 0; j < count; ++j) {
- if (pf->d_children[i + count - 1 - j]->d_children[0]->d_id != eq::MERGED_THROUGH_REFLEXIVITY)
+ if (pf->d_children[i + count - 1 - j]->d_children[0]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
orderedEqualities.insert(orderedEqualities.begin(), pf->d_children[i + count - 1 - j]->d_children[0]);
- if (pf->d_children[i + count - 1 - j]->d_children[1]->d_id != eq::MERGED_THROUGH_REFLEXIVITY)
+ if (pf->d_children[i + count - 1 - j]->d_children[1]->d_id != theory::eq::MERGED_THROUGH_REFLEXIVITY)
orderedEqualities.insert(orderedEqualities.end(), pf->d_children[i + count - 1 - j]->d_children[1]);
}
}
@@ -197,22 +195,22 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
Node n1;
std::stringstream ss;
//Assert(subTrans.d_children.size() == pf->d_children.size() - 1);
- Debug("mgdx") << "\nsubtrans has " << subTrans.d_children.size() << " children\n";
+ Debug("pf::uf") << "\nsubtrans has " << subTrans.d_children.size() << " children\n";
if(pf->d_children.size() > 2) {
n1 = toStreamRecLFSC(ss, tp, &subTrans, 1, map);
} else {
n1 = toStreamRecLFSC(ss, tp, subTrans.d_children[0], 1, map);
- Debug("mgdx") << "\nsubTrans unique child " << subTrans.d_children[0]->d_id << " was proven\ngot: " << n1 << std::endl;
+ Debug("pf::uf") << "\nsubTrans unique child " << subTrans.d_children[0]->d_id << " was proven\ngot: " << n1 << std::endl;
}
Node n2 = pf->d_children[neg]->d_node;
Assert(n2.getKind() == kind::NOT);
out << "(clausify_false (contra _ ";
- Debug("mgdx") << "\nhave proven: " << n1 << std::endl;
- Debug("mgdx") << "n2 is " << n2[0] << std::endl;
+ Debug("pf::uf") << "\nhave proven: " << n1 << std::endl;
+ Debug("pf::uf") << "n2 is " << n2[0] << std::endl;
- if (n2[0].getNumChildren() > 0) { Debug("mgdx") << "\nn2[0]: " << n2[0][0] << std::endl; }
- if (n1.getNumChildren() > 1) { Debug("mgdx") << "n1[1]: " << n1[1] << std::endl; }
+ if (n2[0].getNumChildren() > 0) { Debug("pf::uf") << "\nn2[0]: " << n2[0][0] << std::endl; }
+ if (n1.getNumChildren() > 1) { Debug("pf::uf") << "n1[1]: " << n1[1] << std::endl; }
if(n2[0].getKind() == kind::APPLY_UF) {
out << "(trans _ _ _ _ ";
@@ -232,44 +230,44 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
}
switch(pf->d_id) {
- case eq::MERGED_THROUGH_CONGRUENCE: {
- Debug("mgd") << "\nok, looking at congruence:\n";
- pf->debug_print("mgd");
+ case theory::eq::MERGED_THROUGH_CONGRUENCE: {
+ Debug("pf::uf") << "\nok, looking at congruence:\n";
+ pf->debug_print("pf::uf");
std::stack<const theory::eq::EqProof*> stk;
- for(const theory::eq::EqProof* pf2 = pf; pf2->d_id == eq::MERGED_THROUGH_CONGRUENCE; pf2 = pf2->d_children[0]) {
+ for(const theory::eq::EqProof* pf2 = pf; pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE; pf2 = pf2->d_children[0]) {
Assert(!pf2->d_node.isNull());
Assert(pf2->d_node.getKind() == kind::PARTIAL_APPLY_UF || pf2->d_node.getKind() == kind::BUILTIN || pf2->d_node.getKind() == kind::APPLY_UF || pf2->d_node.getKind() == kind::SELECT || pf2->d_node.getKind() == kind::STORE);
Assert(pf2->d_children.size() == 2);
out << "(cong _ _ _ _ _ _ ";
stk.push(pf2);
}
- Assert(stk.top()->d_children[0]->d_id != eq::MERGED_THROUGH_CONGRUENCE);
+ Assert(stk.top()->d_children[0]->d_id != theory::eq::MERGED_THROUGH_CONGRUENCE);
NodeBuilder<> b1(kind::PARTIAL_APPLY_UF), b2(kind::PARTIAL_APPLY_UF);
const theory::eq::EqProof* pf2 = stk.top();
stk.pop();
- Assert(pf2->d_id == eq::MERGED_THROUGH_CONGRUENCE);
+ Assert(pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE);
Node n1 = toStreamRecLFSC(out, tp, pf2->d_children[0], tb + 1, map);
out << " ";
std::stringstream ss;
Node n2 = toStreamRecLFSC(ss, tp, pf2->d_children[1], tb + 1, map);
- Debug("mgd") << "\nok, in FIRST cong[" << stk.size() << "]" << "\n";
- pf2->debug_print("mgd");
- Debug("mgd") << "looking at " << pf2->d_node << "\n";
- Debug("mgd") << " " << n1 << "\n";
- Debug("mgd") << " " << n2 << "\n";
+ Debug("pf::uf") << "\nok, in FIRST cong[" << stk.size() << "]" << "\n";
+ pf2->debug_print("pf::uf");
+ Debug("pf::uf") << "looking at " << pf2->d_node << "\n";
+ Debug("pf::uf") << " " << n1 << "\n";
+ Debug("pf::uf") << " " << n2 << "\n";
int side = 0;
if(match(pf2->d_node, n1[0])) {
//if(tb == 1) {
- Debug("mgd") << "SIDE IS 0\n";
+ Debug("pf::uf") << "SIDE IS 0\n";
//}
side = 0;
} else {
//if(tb == 1) {
- Debug("mgd") << "SIDE IS 1\n";
+ Debug("pf::uf") << "SIDE IS 1\n";
//}
if(!match(pf2->d_node, n1[1])) {
- Debug("mgd") << "IN BAD CASE, our first subproof is\n";
- pf2->d_children[0]->debug_print("mgd");
+ Debug("pf::uf") << "IN BAD CASE, our first subproof is\n";
+ pf2->d_children[0]->debug_print("pf::uf");
}
Assert(match(pf2->d_node, n1[1]));
side = 1;
@@ -294,11 +292,11 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
} else {
b2 << n1[1-side];
}
- Debug("mgd") << "pf2->d_node " << pf2->d_node << std::endl;
- Debug("mgd") << "b1.getNumChildren() " << b1.getNumChildren() << std::endl;
- Debug("mgd") << "n1 " << n1 << std::endl;
- Debug("mgd") << "n2 " << n2 << std::endl;
- Debug("mgd") << "side " << side << std::endl;
+ Debug("pf::uf") << "pf2->d_node " << pf2->d_node << std::endl;
+ Debug("pf::uf") << "b1.getNumChildren() " << b1.getNumChildren() << std::endl;
+ Debug("pf::uf") << "n1 " << n1 << std::endl;
+ Debug("pf::uf") << "n2 " << n2 << std::endl;
+ Debug("pf::uf") << "side " << side << std::endl;
if(pf2->d_node[b1.getNumChildren() - (pf2->d_node.getMetaKind() == kind::metakind::PARAMETERIZED ? 0 : 1)] == n2[side]) {
b1 << n2[side];
b2 << n2[1-side];
@@ -312,20 +310,20 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
out << ")";
while(!stk.empty()) {
if(tb == 1) {
- Debug("mgd") << "\nMORE TO DO\n";
+ Debug("pf::uf") << "\nMORE TO DO\n";
}
pf2 = stk.top();
stk.pop();
- Assert(pf2->d_id == eq::MERGED_THROUGH_CONGRUENCE);
+ Assert(pf2->d_id == theory::eq::MERGED_THROUGH_CONGRUENCE);
out << " ";
ss.str("");
n2 = toStreamRecLFSC(ss, tp, pf2->d_children[1], tb + 1, map);
- Debug("mgd") << "\nok, in cong[" << stk.size() << "]" << "\n";
- Debug("mgd") << "looking at " << pf2->d_node << "\n";
- Debug("mgd") << " " << n1 << "\n";
- Debug("mgd") << " " << n2 << "\n";
- Debug("mgd") << " " << b1 << "\n";
- Debug("mgd") << " " << b2 << "\n";
+ Debug("pf::uf") << "\nok, in cong[" << stk.size() << "]" << "\n";
+ Debug("pf::uf") << "looking at " << pf2->d_node << "\n";
+ Debug("pf::uf") << " " << n1 << "\n";
+ Debug("pf::uf") << " " << n2 << "\n";
+ Debug("pf::uf") << " " << b1 << "\n";
+ Debug("pf::uf") << " " << b2 << "\n";
if(pf2->d_node[b1.getNumChildren()] == n2[side]) {
b1 << n2[side];
b2 << n2[1-side];
@@ -340,7 +338,7 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
}
n1 = b1;
n2 = b2;
- Debug("mgd") << "at end assert, got " << pf2->d_node << " and " << n1 << std::endl;
+ Debug("pf::uf") << "at end assert, got " << pf2->d_node << " and " << n1 << std::endl;
if(pf2->d_node.getKind() == kind::PARTIAL_APPLY_UF) {
Assert(n1 == pf2->d_node);
}
@@ -353,7 +351,7 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
}
b1.append(n1.begin(), n1.end());
n1 = b1;
- Debug("mgd") << "at[2] end assert, got " << pf2->d_node << " and " << n1 << std::endl;
+ Debug("pf::uf") << "at[2] end assert, got " << pf2->d_node << " and " << n1 << std::endl;
if(pf2->d_node.getKind() == kind::APPLY_UF) {
Assert(n1 == pf2->d_node);
}
@@ -370,12 +368,12 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
}
Node n = (side == 0 ? eqNode(n1, n2) : eqNode(n2, n1));
if(tb == 1) {
- Debug("mgdx") << "\ncong proved: " << n << "\n";
+ Debug("pf::uf") << "\ncong proved: " << n << "\n";
}
return n;
}
- case eq::MERGED_THROUGH_REFLEXIVITY:
+ case theory::eq::MERGED_THROUGH_REFLEXIVITY:
Assert(!pf->d_node.isNull());
Assert(pf->d_children.empty());
out << "(refl _ ";
@@ -383,33 +381,44 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
out << ")";
return eqNode(pf->d_node, pf->d_node);
- case eq::MERGED_THROUGH_EQUALITY:
+ case theory::eq::MERGED_THROUGH_EQUALITY:
Assert(!pf->d_node.isNull());
Assert(pf->d_children.empty());
out << ProofManager::getLitName(pf->d_node.negate());
return pf->d_node;
- case eq::MERGED_THROUGH_TRANS: {
+ case theory::eq::MERGED_THROUGH_TRANS: {
Assert(!pf->d_node.isNull());
Assert(pf->d_children.size() >= 2);
std::stringstream ss;
- Debug("mgd") << "\ndoing trans proof[[\n";
- pf->debug_print("mgd");
- Debug("mgd") << "\n";
+ Debug("pf::uf") << "\ndoing trans proof[[\n";
+ pf->debug_print("pf::uf");
+ Debug("pf::uf") << "\n";
Node n1 = toStreamRecLFSC(ss, tp, pf->d_children[0], tb + 1, map);
- Debug("mgd") << "\ndoing trans proof, got n1 " << n1 << "\n";
+ Debug("pf::uf") << "\ndoing trans proof, got n1 " << n1 << "\n";
if(tb == 1) {
- Debug("mgdx") << "\ntrans proof[0], got n1 " << n1 << "\n";
+ Debug("pf::uf") << "\ntrans proof[0], got n1 " << n1 << "\n";
}
bool identicalEqualities = false;
bool evenLengthSequence;
Node nodeAfterEqualitySequence;
+ std::map<size_t, Node> childToStream;
+
for(size_t i = 1; i < pf->d_children.size(); ++i) {
std::stringstream ss1(ss.str()), ss2;
ss.str("");
- Node n2 = toStreamRecLFSC(ss2, tp, pf->d_children[i], tb + 1, map);
+
+ // It is possible that we've already converted the i'th child to stream. If so,
+ // use previously stored result. Otherwise, convert and store.
+ Node n2;
+ if (childToStream.find(i) != childToStream.end())
+ n2 = childToStream[i];
+ else {
+ n2 = toStreamRecLFSC(ss2, tp, pf->d_children[i], tb + 1, map);
+ childToStream[i] = n2;
+ }
// The following branch is dedicated to handling sequences of identical equalities,
// i.e. trans[ a=b, a=b, a=b ].
@@ -425,13 +434,13 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
if (((n1[0] == n2[0]) && (n1[1] == n2[1])) || ((n1[0] == n2[1]) && (n1[1] == n2[0]))) {
// We are in a sequence of identical equalities
- Debug("gk::proof") << "Detected identical equalities: " << std::endl << "\t" << n1 << std::endl;
+ Debug("pf::uf") << "Detected identical equalities: " << std::endl << "\t" << n1 << std::endl;
if (!identicalEqualities) {
// The sequence of identical equalities has started just now
identicalEqualities = true;
- Debug("gk::proof") << "The sequence is just beginning. Determining length..." << std::endl;
+ Debug("pf::uf") << "The sequence is just beginning. Determining length..." << std::endl;
// Determine whether the length of this sequence is odd or even.
evenLengthSequence = true;
@@ -455,11 +464,11 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
if (evenLengthSequence) {
// If the length is even, we need to apply transitivity for the "correct" hand of the equality.
- Debug("gk::proof") << "Equality sequence of even length" << std::endl;
- Debug("gk::proof") << "n1 is: " << n1 << std::endl;
- Debug("gk::proof") << "n2 is: " << n2 << std::endl;
- Debug("gk::proof") << "pf-d_node is: " << pf->d_node << std::endl;
- Debug("gk::proof") << "Next node is: " << nodeAfterEqualitySequence << std::endl;
+ Debug("pf::uf") << "Equality sequence of even length" << std::endl;
+ Debug("pf::uf") << "n1 is: " << n1 << std::endl;
+ Debug("pf::uf") << "n2 is: " << n2 << std::endl;
+ Debug("pf::uf") << "pf-d_node is: " << pf->d_node << std::endl;
+ Debug("pf::uf") << "Next node is: " << nodeAfterEqualitySequence << std::endl;
ss << "(trans _ _ _ _ ";
@@ -472,7 +481,7 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
n1 = eqNode(n1[1], n1[1]);
ss << " (symm _ _ _ " << ss1.str() << ")" << ss1.str();
} else {
- Debug("gk::proof") << "Error: identical equalities over, but hands don't match what we're proving."
+ Debug("pf::uf") << "Error: identical equalities over, but hands don't match what we're proving."
<< std::endl;
Assert(false);
}
@@ -495,7 +504,7 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
n1 = eqNode(n1[1], n1[1]);
} else {
- Debug("gk::proof") << "Error: even length sequence, but I don't know which hand to keep!" << std::endl;
+ Debug("pf::uf") << "Error: even length sequence, but I don't know which hand to keep!" << std::endl;
Assert(false);
}
}
@@ -503,11 +512,11 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
ss << ")";
} else {
- Debug("gk::proof") << "Equality sequence length is odd!" << std::endl;
+ Debug("pf::uf") << "Equality sequence length is odd!" << std::endl;
ss.str(ss1.str());
}
- Debug("gk::proof") << "Have proven: " << n1 << std::endl;
+ Debug("pf::uf") << "Have proven: " << n1 << std::endl;
} else {
ss.str(ss1.str());
}
@@ -522,21 +531,21 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
identicalEqualities = false;
}
- Debug("mgd") << "\ndoing trans proof, got n2 " << n2 << "\n";
+ Debug("pf::uf") << "\ndoing trans proof, got n2 " << n2 << "\n";
if(tb == 1) {
- Debug("mgdx") << "\ntrans proof[" << i << "], got n2 " << n2 << "\n";
- Debug("mgdx") << (n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) << "\n";
+ Debug("pf::uf") << "\ntrans proof[" << i << "], got n2 " << n2 << "\n";
+ Debug("pf::uf") << (n2.getKind() == kind::EQUAL || n2.getKind() == kind::IFF) << "\n";
if ((n1.getNumChildren() >= 2) && (n2.getNumChildren() >= 2)) {
- Debug("mgdx") << n1[0].getId() << " " << n1[1].getId() << " / " << n2[0].getId() << " " << n2[1].getId() << "\n";
- Debug("mgdx") << n1[0].getId() << " " << n1[0] << "\n";
- Debug("mgdx") << n1[1].getId() << " " << n1[1] << "\n";
- Debug("mgdx") << n2[0].getId() << " " << n2[0] << "\n";
- Debug("mgdx") << n2[1].getId() << " " << n2[1] << "\n";
- Debug("mgdx") << (n1[0] == n2[0]) << "\n";
- Debug("mgdx") << (n1[1] == n2[1]) << "\n";
- Debug("mgdx") << (n1[0] == n2[1]) << "\n";
- Debug("mgdx") << (n1[1] == n2[0]) << "\n";
+ Debug("pf::uf") << n1[0].getId() << " " << n1[1].getId() << " / " << n2[0].getId() << " " << n2[1].getId() << "\n";
+ Debug("pf::uf") << n1[0].getId() << " " << n1[0] << "\n";
+ Debug("pf::uf") << n1[1].getId() << " " << n1[1] << "\n";
+ Debug("pf::uf") << n2[0].getId() << " " << n2[0] << "\n";
+ Debug("pf::uf") << n2[1].getId() << " " << n2[1] << "\n";
+ Debug("pf::uf") << (n1[0] == n2[0]) << "\n";
+ Debug("pf::uf") << (n1[1] == n2[1]) << "\n";
+ Debug("pf::uf") << (n1[0] == n2[1]) << "\n";
+ Debug("pf::uf") << (n1[1] == n2[0]) << "\n";
}
}
ss << "(trans _ _ _ _ ";
@@ -546,32 +555,32 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
// Both elements of the transitivity rule are equalities/iffs
{
if(n1[0] == n2[0]) {
- if(tb == 1) { Debug("mgdx") << "case 1\n"; }
+ if(tb == 1) { Debug("pf::uf") << "case 1\n"; }
n1 = eqNode(n1[1], n2[1]);
ss << "(symm _ _ _ " << ss1.str() << ") " << ss2.str();
} else if(n1[1] == n2[1]) {
- if(tb == 1) { Debug("mgdx") << "case 2\n"; }
+ if(tb == 1) { Debug("pf::uf") << "case 2\n"; }
n1 = eqNode(n1[0], n2[0]);
ss << ss1.str() << " (symm _ _ _ " << ss2.str() << ")";
} else if(n1[0] == n2[1]) {
- if(tb == 1) { Debug("mgdx") << "case 3\n"; }
+ if(tb == 1) { Debug("pf::uf") << "case 3\n"; }
n1 = eqNode(n2[0], n1[1]);
ss << ss2.str() << " " << ss1.str();
- if(tb == 1) { Debug("mgdx") << "++ proved " << n1 << "\n"; }
+ if(tb == 1) { Debug("pf::uf") << "++ proved " << n1 << "\n"; }
} else if(n1[1] == n2[0]) {
- if(tb == 1) { Debug("mgdx") << "case 4\n"; }
+ if(tb == 1) { Debug("pf::uf") << "case 4\n"; }
n1 = eqNode(n1[0], n2[1]);
ss << ss1.str() << " " << ss2.str();
} else {
Warning() << "\n\ntrans proof failure at step " << i << "\n\n";
Warning() << "0 proves " << n1 << "\n";
Warning() << "1 proves " << n2 << "\n\n";
- pf->debug_print("mgdx",0);
+ pf->debug_print("pf::uf",0);
//toStreamRec(Warning.getStream(), pf, 0);
Warning() << "\n\n";
Unreachable();
}
- Debug("mgd") << "++ trans proof[" << i << "], now have " << n1 << std::endl;
+ Debug("pf::uf") << "++ trans proof[" << i << "], now have " << n1 << std::endl;
} else if(n1.getKind() == kind::EQUAL || n1.getKind() == kind::IFF) {
// n1 is an equality/iff, but n2 is a predicate
if(n1[0] == n2) {
@@ -602,90 +611,14 @@ Node ProofUF::toStreamRecLFSC(std::ostream& out, TheoryProof * tp, theory::eq::E
ss << ")";
}
out << ss.str();
- Debug("mgd") << "\n++ trans proof done, have proven " << n1 << std::endl;
+ Debug("pf::uf") << "\n++ trans proof done, have proven " << n1 << std::endl;
return n1;
}
- case eq::MERGED_ARRAYS_ROW: {
- Debug("mgd") << "row lemma: " << pf->d_node << std::endl;
- Assert(pf->d_node.getKind() == kind::EQUAL);
- TNode t1, t2, t3, t4;
- Node ret;
- if(pf->d_node[1].getKind() == kind::SELECT &&
- pf->d_node[1][0].getKind() == kind::STORE &&
- pf->d_node[0].getKind() == kind::SELECT &&
- pf->d_node[0][0] == pf->d_node[1][0][0] &&
- pf->d_node[0][1] == pf->d_node[1][1]) {
- t2 = pf->d_node[1][0][1];
- t3 = pf->d_node[1][1];
- t1 = pf->d_node[0][0];
- t4 = pf->d_node[1][0][2];
- ret = pf->d_node[1].eqNode(pf->d_node[0]);
- Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\nt4 " << t4 << "\n";
- } else {
- Assert(pf->d_node[0].getKind() == kind::SELECT &&
- pf->d_node[0][0].getKind() == kind::STORE &&
- pf->d_node[1].getKind() == kind::SELECT &&
- pf->d_node[1][0] == pf->d_node[0][0][0] &&
- pf->d_node[1][1] == pf->d_node[0][1]);
- t2 = pf->d_node[0][0][1];
- t3 = pf->d_node[0][1];
- t1 = pf->d_node[1][0];
- t4 = pf->d_node[0][0][2];
- ret = pf->d_node;
- Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\nt4 " << t4 << "\n";
- }
- out << "(row _ _ ";
- tp->printTerm(t2.toExpr(), out, map);
- out << " ";
- tp->printTerm(t3.toExpr(), out, map);
- out << " ";
- tp->printTerm(t1.toExpr(), out, map);
- out << " ";
- tp->printTerm(t4.toExpr(), out, map);
- out << " " << ProofManager::getLitName(t2.eqNode(t3)) << ")";
- return ret;
- }
-
- case eq::MERGED_ARRAYS_ROW1: {
- Debug("mgd") << "row1 lemma: " << pf->d_node << std::endl;
- Assert(pf->d_node.getKind() == kind::EQUAL);
- TNode t1, t2, t3;
- Node ret;
- if(pf->d_node[1].getKind() == kind::SELECT &&
- pf->d_node[1][0].getKind() == kind::STORE &&
- pf->d_node[1][0][1] == pf->d_node[1][1] &&
- pf->d_node[1][0][2] == pf->d_node[0]) {
- t1 = pf->d_node[1][0][0];
- t2 = pf->d_node[1][0][1];
- t3 = pf->d_node[0];
- ret = pf->d_node[1].eqNode(pf->d_node[0]);
- Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\n";
- } else {
- Assert(pf->d_node[0].getKind() == kind::SELECT &&
- pf->d_node[0][0].getKind() == kind::STORE &&
- pf->d_node[0][0][1] == pf->d_node[0][1] &&
- pf->d_node[0][0][2] == pf->d_node[1]);
- t1 = pf->d_node[0][0][0];
- t2 = pf->d_node[0][0][1];
- t3 = pf->d_node[1];
- ret = pf->d_node;
- Debug("mgd") << "t1 " << t1 << "\nt2 " << t2 << "\nt3 " << t3 << "\n";
- }
- out << "(row1 _ _ ";
- tp->printTerm(t1.toExpr(), out, map);
- out << " ";
- tp->printTerm(t2.toExpr(), out, map);
- out << " ";
- tp->printTerm(t3.toExpr(), out, map);
- out << ")";
- return ret;
- }
-
default:
Assert(!pf->d_node.isNull());
Assert(pf->d_children.empty());
- Debug("mgd") << "theory proof: " << pf->d_node << " by rule " << int(pf->d_id) << std::endl;
+ Debug("pf::uf") << "theory proof: " << pf->d_node << " by rule " << int(pf->d_id) << std::endl;
AlwaysAssert(false);
return pf->d_node;
}
@@ -722,8 +655,10 @@ void UFProof::registerTerm(Expr term) {
}
}
-void LFSCUFProof::printTerm(Expr term, std::ostream& os, const LetMap& map) {
- Assert (Theory::theoryOf(term) == THEORY_UF);
+void LFSCUFProof::printOwnedTerm(Expr term, std::ostream& os, const LetMap& map) {
+ Debug("pf::uf") << std::endl << "(pf::uf) LFSCUfProof::printOwnedTerm: term = " << term << std::endl;
+
+ Assert (theory::Theory::theoryOf(term) == theory::THEORY_UF);
if (term.getKind() == kind::VARIABLE ||
term.getKind() == kind::SKOLEM) {
@@ -742,7 +677,7 @@ void LFSCUFProof::printTerm(Expr term, std::ostream& os, const LetMap& map) {
}
os << func << " ";
for (unsigned i = 0; i < term.getNumChildren(); ++i) {
- printTerm(term[i], os, map);
+ d_proofEngine->printBoundTerm(term[i], os, map);
os << ")";
}
if(term.getType().isBoolean()) {
@@ -750,7 +685,9 @@ void LFSCUFProof::printTerm(Expr term, std::ostream& os, const LetMap& map) {
}
}
-void LFSCUFProof::printSort(Type type, std::ostream& os) {
+void LFSCUFProof::printOwnedSort(Type type, std::ostream& os) {
+ Debug("pf::uf") << std::endl << "(pf::uf) LFSCArrayProof::printOwnedSort: type is: " << type << std::endl;
+
Assert (type.isSort());
os << type <<" ";
}
@@ -765,13 +702,17 @@ void LFSCUFProof::printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream&
UFProof::printTheoryLemmaProof( lemma, os, paren );
}
-void LFSCUFProof::printDeclarations(std::ostream& os, std::ostream& paren) {
- // declaring the sorts
+void LFSCUFProof::printSortDeclarations(std::ostream& os, std::ostream& paren) {
for (TypeSet::const_iterator it = d_sorts.begin(); it != d_sorts.end(); ++it) {
- os << "(% " << *it << " sort\n";
- paren << ")";
+ if (!ProofManager::currentPM()->wasPrinted(*it)) {
+ os << "(% " << *it << " sort\n";
+ paren << ")";
+ ProofManager::currentPM()->markPrinted(*it);
+ }
}
+}
+void LFSCUFProof::printTermDeclarations(std::ostream& os, std::ostream& paren) {
// declaring the terms
for (ExprSet::const_iterator it = d_declarations.begin(); it != d_declarations.end(); ++it) {
Expr term = *it;
@@ -802,3 +743,9 @@ void LFSCUFProof::printDeclarations(std::ostream& os, std::ostream& paren) {
paren << ")";
}
}
+
+void LFSCUFProof::printDeferredDeclarations(std::ostream& os, std::ostream& paren) {
+ // Nothing to do here at this point.
+}
+
+} /* namespace CVC4 */
diff --git a/src/proof/uf_proof.h b/src/proof/uf_proof.h
index 121db1fcd..e359eaebd 100644
--- a/src/proof/uf_proof.h
+++ b/src/proof/uf_proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file uf_proof.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Guy Katz, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief UF proof
**
@@ -37,7 +37,7 @@ public:
static void toStreamLFSC(std::ostream& out, TheoryProof * tp, theory::eq::EqProof * pf, const LetMap& map);
};
-
+
namespace theory {
namespace uf {
class TheoryUF;
@@ -51,7 +51,7 @@ class UFProof : public TheoryProof {
protected:
TypeSet d_sorts; // all the uninterpreted sorts in this theory
ExprSet d_declarations; // all the variable/function declarations
-
+
public:
UFProof(theory::uf::TheoryUF* uf, TheoryProofEngine* proofEngine);
@@ -63,10 +63,12 @@ public:
LFSCUFProof(theory::uf::TheoryUF* uf, TheoryProofEngine* proofEngine)
: UFProof(uf, proofEngine)
{}
- virtual void printTerm(Expr term, std::ostream& os, const LetMap& map);
- virtual void printSort(Type type, std::ostream& os);
+ virtual void printOwnedTerm(Expr term, std::ostream& os, const LetMap& map);
+ virtual void printOwnedSort(Type type, std::ostream& os);
virtual void printTheoryLemmaProof(std::vector<Expr>& lemma, std::ostream& os, std::ostream& paren);
- virtual void printDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printSortDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printTermDeclarations(std::ostream& os, std::ostream& paren);
+ virtual void printDeferredDeclarations(std::ostream& os, std::ostream& paren);
};
diff --git a/src/proof/unsat_core.cpp b/src/proof/unsat_core.cpp
index 2b559d117..4c940e4be 100644
--- a/src/proof/unsat_core.cpp
+++ b/src/proof/unsat_core.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file unsat_core.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of unsat cores
**
diff --git a/src/proof/unsat_core.h b/src/proof/unsat_core.h
index 8e92fe3d1..a238f0a6a 100644
--- a/src/proof/unsat_core.h
+++ b/src/proof/unsat_core.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file unsat_core.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/prop/bvminisat/bvminisat.cpp b/src/prop/bvminisat/bvminisat.cpp
index 936778e0d..54e3f2e8b 100644
--- a/src/prop/bvminisat/bvminisat.cpp
+++ b/src/prop/bvminisat/bvminisat.cpp
@@ -19,6 +19,7 @@
#include "prop/bvminisat/bvminisat.h"
#include "prop/bvminisat/simp/SimpSolver.h"
+#include "proof/clause_id.h"
#include "proof/sat_proof.h"
#include "util/statistics_registry.h"
diff --git a/src/prop/bvminisat/bvminisat.h b/src/prop/bvminisat/bvminisat.h
index ec8c3455a..20724efd2 100644
--- a/src/prop/bvminisat/bvminisat.h
+++ b/src/prop/bvminisat/bvminisat.h
@@ -21,6 +21,7 @@
#pragma once
#include "context/cdo.h"
+#include "proof/clause_id.h"
#include "prop/bvminisat/simp/SimpSolver.h"
#include "prop/sat_solver.h"
#include "util/statistics_registry.h"
diff --git a/src/prop/bvminisat/core/Solver.cc b/src/prop/bvminisat/core/Solver.cc
index 2100160de..d626a5d15 100644
--- a/src/prop/bvminisat/core/Solver.cc
+++ b/src/prop/bvminisat/core/Solver.cc
@@ -30,11 +30,12 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "mtl/Sort.h"
#include "options/bv_options.h"
#include "options/smt_options.h"
-#include "theory/interrupted.h"
-#include "proof/proof_manager.h"
#include "proof/bitvector_proof.h"
+#include "proof/clause_id.h"
+#include "proof/proof_manager.h"
#include "proof/sat_proof.h"
#include "proof/sat_proof_implementation.h"
+#include "theory/interrupted.h"
#include "util/utility.h"
namespace CVC4 {
diff --git a/src/prop/bvminisat/core/Solver.h b/src/prop/bvminisat/core/Solver.h
index 019c09bcd..555495149 100644
--- a/src/prop/bvminisat/core/Solver.h
+++ b/src/prop/bvminisat/core/Solver.h
@@ -21,20 +21,21 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#ifndef BVMinisat_Solver_h
#define BVMinisat_Solver_h
+#include <ext/hash_set>
+#include <vector>
+
+#include "context/context.h"
+#include "proof/clause_id.h"
+#include "proof/sat_proof.h"
#include "prop/bvminisat/core/SolverTypes.h"
-#include "prop/bvminisat/mtl/Vec.h"
-#include "prop/bvminisat/mtl/Heap.h"
#include "prop/bvminisat/mtl/Alg.h"
+#include "prop/bvminisat/mtl/Heap.h"
+#include "prop/bvminisat/mtl/Vec.h"
#include "prop/bvminisat/utils/Options.h"
-#include "context/cdhashmap.h"
-#include "proof/sat_proof.h"
-#include <ext/hash_set>
-#include <vector>
namespace CVC4 {
-typedef unsigned ClauseId;
namespace BVMinisat {
class Solver;
}
diff --git a/src/prop/bvminisat/simp/SimpSolver.cc b/src/prop/bvminisat/simp/SimpSolver.cc
index 311ed1dd1..cb5929320 100644
--- a/src/prop/bvminisat/simp/SimpSolver.cc
+++ b/src/prop/bvminisat/simp/SimpSolver.cc
@@ -23,8 +23,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "mtl/Sort.h"
#include "options/bv_options.h"
#include "options/smt_options.h"
-#include "utils/System.h"
+#include "proof/clause_id.h"
#include "proof/proof.h"
+#include "utils/System.h"
namespace CVC4 {
namespace BVMinisat {
diff --git a/src/prop/bvminisat/simp/SimpSolver.h b/src/prop/bvminisat/simp/SimpSolver.h
index 5f6f46b91..9854bf77d 100644
--- a/src/prop/bvminisat/simp/SimpSolver.h
+++ b/src/prop/bvminisat/simp/SimpSolver.h
@@ -22,6 +22,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#define BVMinisat_SimpSolver_h
#include "context/context.h"
+#include "proof/clause_id.h"
#include "prop/bvminisat/core/Solver.h"
#include "prop/bvminisat/mtl/Queue.h"
#include "util/statistics_registry.h"
diff --git a/src/prop/cnf_stream.cpp b/src/prop/cnf_stream.cpp
index d54848d26..aa1fc9587 100644
--- a/src/prop/cnf_stream.cpp
+++ b/src/prop/cnf_stream.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cnf_stream.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Dejan Jovanovic
- ** Minor contributors (to current version): Kshitij Bansal, Liana Hadarean, Christopher L. Conway, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A CNF converter that takes in asserts and has the side effect
** of given an equisatisfiable stream of assertions to PropEngine.
@@ -15,6 +15,8 @@
** A CNF converter that takes in asserts and has the side effect
** of given an equisatisfiable stream of assertions to PropEngine.
**/
+#include "prop/cnf_stream.h"
+
#include <queue>
#include "base/cvc4_assert.h"
@@ -22,10 +24,10 @@
#include "expr/expr.h"
#include "expr/node.h"
#include "options/bv_options.h"
+#include "proof/clause_id.h"
+#include "proof/cnf_proof.h"
#include "proof/proof_manager.h"
#include "proof/sat_proof.h"
-#include "proof/cnf_proof.h"
-#include "prop/cnf_stream.h"
#include "prop/minisat/minisat.h"
#include "prop/prop_engine.h"
#include "prop/theory_proxy.h"
@@ -672,7 +674,8 @@ void TseitinCnfStream::convertAndAssert(TNode node,
bool removable,
bool negated,
ProofRule proof_id,
- TNode from) {
+ TNode from,
+ theory::TheoryId ownerTheory) {
Debug("cnf") << "convertAndAssert(" << node
<< ", removable = " << (removable ? "true" : "false")
<< ", negated = " << (negated ? "true" : "false") << ")" << endl;
@@ -682,6 +685,7 @@ void TseitinCnfStream::convertAndAssert(TNode node,
Node assertion = negated ? node.notNode() : (Node)node;
Node from_assertion = negated? from.notNode() : (Node) from;
+ d_cnfProof->setExplainerTheory(ownerTheory);
if (proof_id != RULE_INVALID) {
d_cnfProof->pushCurrentAssertion(from.isNull() ? assertion : from_assertion);
d_cnfProof->registerAssertion(from.isNull() ? assertion : from_assertion, proof_id);
@@ -693,7 +697,10 @@ void TseitinCnfStream::convertAndAssert(TNode node,
});
convertAndAssert(node, negated);
- PROOF(if (d_cnfProof) d_cnfProof->popCurrentAssertion(); );
+ PROOF
+ (if (d_cnfProof) {
+ d_cnfProof->popCurrentAssertion();
+ });
}
void TseitinCnfStream::convertAndAssert(TNode node, bool negated) {
diff --git a/src/prop/cnf_stream.h b/src/prop/cnf_stream.h
index a6b6781ca..cf9d519a7 100644
--- a/src/prop/cnf_stream.h
+++ b/src/prop/cnf_stream.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cnf_stream.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Dejan Jovanovic
- ** Minor contributors (to current version): Clark Barrett, Liana Hadarean, Christopher L. Conway, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This class transforms a sequence of formulas into clauses.
**
@@ -207,9 +207,14 @@ public:
* @param node node to convert and assert
* @param removable whether the sat solver can choose to remove the clauses
* @param negated whether we are asserting the node negated
+ * @param ownerTheory indicates the theory that should invoked to prove the formula.
*/
- virtual void convertAndAssert(TNode node, bool removable, bool negated, ProofRule proof_id, TNode from = TNode::null()) = 0;
-
+ virtual void convertAndAssert(TNode node,
+ bool removable,
+ bool negated,
+ ProofRule proof_id,
+ TNode from = TNode::null(),
+ theory::TheoryId ownerTheory = theory::THEORY_LAST) = 0;
/**
* Get the node that is represented by the given SatLiteral.
* @param literal the literal from the sat solver
@@ -278,7 +283,8 @@ public:
* @param negated true if negated
*/
void convertAndAssert(TNode node, bool removable,
- bool negated, ProofRule rule, TNode from = TNode::null());
+ bool negated, ProofRule rule, TNode from = TNode::null(),
+ theory::TheoryId ownerTheory = theory::THEORY_LAST);
/**
* Constructs the stream to use the given sat solver.
diff --git a/src/prop/minisat/core/Solver.cc b/src/prop/minisat/core/Solver.cc
index b7fb1603d..411b89514 100644
--- a/src/prop/minisat/core/Solver.cc
+++ b/src/prop/minisat/core/Solver.cc
@@ -18,21 +18,22 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
+#include "prop/minisat/core/Solver.h"
+
#include <math.h>
#include <iostream>
#include "base/output.h"
#include "options/prop_options.h"
+#include "proof/clause_id.h"
#include "proof/proof_manager.h"
#include "proof/sat_proof_implementation.h"
#include "proof/sat_proof.h"
-#include "prop/minisat/core/Solver.h"
#include "prop/minisat/minisat.h"
#include "prop/minisat/mtl/Sort.h"
#include "prop/theory_proxy.h"
-
using namespace CVC4::prop;
namespace CVC4 {
@@ -229,7 +230,7 @@ CRef Solver::reason(Var x) {
proxy->explainPropagation(MinisatSatSolver::toSatLiteral(l),
explanation_cl);
vec<Lit> explanation;
- MinisatSatSolver::toMinisatClause(explanation_cl, explanation);
+ MinisatSatSolver::toMinisatClause(explanation_cl, explanation);
// Sort the literals by trail index level
lemma_lt lt(*this);
@@ -602,20 +603,20 @@ Lit Solver::pickBranchLit()
/*_________________________________________________________________________________________________
|
| analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void]
-|
+|
| Description:
| Analyze conflict and produce a reason clause.
-|
+|
| Pre-conditions:
| * 'out_learnt' is assumed to be cleared.
| * Current decision level must be greater than root level.
-|
+|
| Post-conditions:
| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
-| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the
+| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the
| rest of literals. There may be others from the same level though.
| * returns the maximal level of the resolved clauses
-|
+|
|________________________________________________________________________________________________@*/
int Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel)
{
@@ -661,14 +662,14 @@ int Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel)
}
}
}
-
+
// Select next clause to look at:
while (!seen[var(trail[index--])]);
p = trail[index+1];
confl = reason(var(p));
seen[var(p)] = 0;
pathC--;
-
+
if ( pathC > 0 && confl != CRef_Undef ) {
PROOF( ProofManager::getSatProof()->addResolutionStep(p, confl, sign(p)); )
}
@@ -694,13 +695,13 @@ int Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel)
out_learnt[j++] = out_learnt[i];
} else {
PROOF( ProofManager::getSatProof()->storeLitRedundant(out_learnt[i]); )
- // Literal is redundant, to be safe, mark the level as current assertion level
+ // Literal is redundant, to be safe, mark the level as current assertion level
// TODO: maybe optimize
max_resolution_level = std::max(max_resolution_level, user_level(var(out_learnt[i])));
}
}
}
-
+
}else if (ccmin_mode == 1){
Unreachable();
for (i = j = 1; i < out_learnt.size(); i++){
@@ -786,7 +787,7 @@ bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
/*_________________________________________________________________________________________________
|
| analyzeFinal : (p : Lit) -> [void]
-|
+|
| Description:
| Specialized analysis procedure to express the final conflict in terms of assumptions.
| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
@@ -865,7 +866,7 @@ CRef Solver::propagate(TheoryCheckType type)
if (lemmas.size() > 0) {
recheck = true;
confl = updateLemmas();
- return confl;
+ return confl;
} else {
recheck = proxy->theoryNeedCheck();
return confl;
@@ -921,7 +922,7 @@ void Solver::propagateTheory() {
proxy->theoryPropagate(propagatedLiteralsClause);
vec<Lit> propagatedLiterals;
- MinisatSatSolver::toMinisatClause(propagatedLiteralsClause, propagatedLiterals);
+ MinisatSatSolver::toMinisatClause(propagatedLiteralsClause, propagatedLiterals);
int oldTrailSize = trail.size();
Debug("minisat") << "old trail size is " << oldTrailSize << ", propagating " << propagatedLiterals.size() << " lits..." << std::endl;
@@ -963,11 +964,11 @@ void Solver::theoryCheck(CVC4::theory::Theory::Effort effort)
/*_________________________________________________________________________________________________
|
| propagateBool : [void] -> [Clause*]
-|
+|
| Description:
| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
| otherwise CRef_Undef.
-|
+|
| Post-conditions:
| * the propagation queue is empty, even if there was a conflict.
|________________________________________________________________________________________________@*/
@@ -1037,16 +1038,16 @@ CRef Solver::propagateBool()
/*_________________________________________________________________________________________________
|
| reduceDB : () -> [void]
-|
+|
| Description:
| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
| clauses are clauses that are reason to some assignment. Binary clauses are never removed.
|________________________________________________________________________________________________@*/
-struct reduceDB_lt {
+struct reduceDB_lt {
ClauseAllocator& ca;
reduceDB_lt(ClauseAllocator& ca_) : ca(ca_) {}
- bool operator () (CRef x, CRef y) {
- return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); }
+ bool operator () (CRef x, CRef y) {
+ return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); }
};
void Solver::reduceDB()
{
@@ -1114,7 +1115,7 @@ void Solver::rebuildOrderHeap()
/*_________________________________________________________________________________________________
|
| simplify : [void] -> [bool]
-|
+|
| Description:
| Simplify the clause database according to the current top-level assigment. Currently, the only
| thing done here is the removal of satisfied clauses, but more things can be put here.
@@ -1146,11 +1147,11 @@ bool Solver::simplify()
/*_________________________________________________________________________________________________
|
| search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool]
-|
+|
| Description:
-| Search for a model the specified number of conflicts.
+| Search for a model the specified number of conflicts.
| NOTE! Use negative value for 'nof_conflicts' indicate infinity.
-|
+|
| Output:
| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
| all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
@@ -1219,9 +1220,9 @@ lbool Solver::search(int nof_conflicts)
max_learnts *= learntsize_inc;
if (verbosity >= 1)
- printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n",
- (int)conflicts,
- (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
+ printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n",
+ (int)conflicts,
+ (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
(int)max_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progressEstimate()*100);
}
@@ -1417,7 +1418,7 @@ lbool Solver::solve_()
//=================================================================================================
// Writing CNF to DIMACS:
-//
+//
// FIXME: this needs to be rewritten completely.
static Var mapVar(Var x, vec<Var>& map, Var& max)
@@ -1466,7 +1467,7 @@ void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
for (int i = 0; i < clauses_persistent.size(); i++)
if (!satisfied(ca[clauses_persistent[i]]))
cnt++;
-
+
for (int i = 0; i < clauses_persistent.size(); i++)
if (!satisfied(ca[clauses_persistent[i]])){
Clause& c = ca[clauses_persistent[i]];
@@ -1537,11 +1538,11 @@ void Solver::garbageCollect()
{
// Initialize the next region to a size corresponding to the estimated utilization degree. This
// is not precise but should avoid some unnecessary reallocations for the new region:
- ClauseAllocator to(ca.size() - ca.wasted());
+ ClauseAllocator to(ca.size() - ca.wasted());
relocAll(to);
if (verbosity >= 2)
- printf("| Garbage collection: %12d bytes => %12d bytes |\n",
+ printf("| Garbage collection: %12d bytes => %12d bytes |\n",
ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
to.moveTo(ca);
}
@@ -1698,7 +1699,7 @@ CRef Solver::updateLemmas() {
int backtrack_index = trail.size();
PROOF(Assert (lemmas.size() == (int)lemmas_cnf_assertion.size()););
-
+
// Attach all the clauses and enqueue all the propagations
for (int i = 0; i < lemmas.size(); ++ i)
{
@@ -1739,7 +1740,7 @@ CRef Solver::updateLemmas() {
(
Node cnf_assertion = lemmas_cnf_assertion[i].first;
Node cnf_def = lemmas_cnf_assertion[i].second;
-
+
ClauseId id = ProofManager::getSatProof()->registerUnitClause(lemma[0], THEORY_LEMMA);
ProofManager::getCnfProof()->setClauseAssertion(id, cnf_assertion);
ProofManager::getCnfProof()->setClauseDefinition(id, cnf_def);
@@ -1784,20 +1785,20 @@ CRef Solver::updateLemmas() {
void ClauseAllocator::reloc(CRef& cr, ClauseAllocator& to, CVC4::CoreProofProxy* proxy)
{
-
+
// FIXME what is this CRef_lazy
if (cr == CRef_Lazy) return;
-
+
CRef old = cr; // save the old reference
Clause& c = operator[](cr);
if (c.reloced()) { cr = c.relocation(); return; }
-
+
cr = to.alloc(c.level(), c, c.removable());
c.relocate(cr);
if (proxy) {
- proxy->updateCRef(old, cr);
+ proxy->updateCRef(old, cr);
}
- // Copy extra data-fields:
+ // Copy extra data-fields:
// (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
to[cr].mark(c.mark());
if (to[cr].removable()) to[cr].activity() = c.activity();
diff --git a/src/prop/minisat/core/Solver.h b/src/prop/minisat/core/Solver.h
index 777fb1093..99c47e045 100644
--- a/src/prop/minisat/core/Solver.h
+++ b/src/prop/minisat/core/Solver.h
@@ -27,6 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "base/output.h"
#include "context/context.h"
+#include "proof/clause_id.h"
#include "prop/minisat/core/SolverTypes.h"
#include "prop/minisat/mtl/Alg.h"
#include "prop/minisat/mtl/Heap.h"
@@ -43,7 +44,6 @@ namespace prop {
}/* CVC4::prop namespace */
}/* CVC4 namespace */
-typedef unsigned ClauseId;
namespace CVC4 {
namespace Minisat {
diff --git a/src/prop/minisat/minisat.cpp b/src/prop/minisat/minisat.cpp
index 739d9087a..bfbf9da6f 100644
--- a/src/prop/minisat/minisat.cpp
+++ b/src/prop/minisat/minisat.cpp
@@ -23,6 +23,7 @@
#include "options/prop_options.h"
#include "options/smt_options.h"
#include "prop/minisat/simp/SimpSolver.h"
+#include "proof/clause_id.h"
#include "proof/sat_proof.h"
#include "util/statistics_registry.h"
diff --git a/src/prop/minisat/simp/SimpSolver.cc b/src/prop/minisat/simp/SimpSolver.cc
index 5bdaea950..9b551fa70 100644
--- a/src/prop/minisat/simp/SimpSolver.cc
+++ b/src/prop/minisat/simp/SimpSolver.cc
@@ -18,10 +18,12 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
+#include "prop/minisat/simp/SimpSolver.h"
+
#include "options/prop_options.h"
+#include "proof/clause_id.h"
#include "proof/proof.h"
#include "prop/minisat/mtl/Sort.h"
-#include "prop/minisat/simp/SimpSolver.h"
#include "prop/minisat/utils/System.h"
using namespace CVC4;
diff --git a/src/prop/minisat/simp/SimpSolver.h b/src/prop/minisat/simp/SimpSolver.h
index a19bec1ef..a995c1357 100644
--- a/src/prop/minisat/simp/SimpSolver.h
+++ b/src/prop/minisat/simp/SimpSolver.h
@@ -23,6 +23,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "cvc4_private.h"
+#include "proof/clause_id.h"
#include "prop/minisat/mtl/Queue.h"
#include "prop/minisat/core/Solver.h"
diff --git a/src/prop/prop_engine.cpp b/src/prop/prop_engine.cpp
index 583e9da18..54cf4c457 100644
--- a/src/prop/prop_engine.cpp
+++ b/src/prop/prop_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file prop_engine.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Clark Barrett, Liana Hadarean, Kshitij Bansal, Christopher L. Conway, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the propositional engine of CVC4
**
@@ -132,12 +132,13 @@ void PropEngine::assertFormula(TNode node) {
void PropEngine::assertLemma(TNode node, bool negated,
bool removable,
ProofRule rule,
+ theory::TheoryId ownerTheory,
TNode from) {
//Assert(d_inCheckSat, "Sat solver should be in solve()!");
Debug("prop::lemmas") << "assertLemma(" << node << ")" << endl;
// Assert as (possibly) removable
- d_cnfStream->convertAndAssert(node, removable, negated, rule, from);
+ d_cnfStream->convertAndAssert(node, removable, negated, rule, from, ownerTheory);
}
void PropEngine::requirePhase(TNode n, bool phase) {
diff --git a/src/prop/prop_engine.h b/src/prop/prop_engine.h
index a71d4832d..b9ce7ca7e 100644
--- a/src/prop/prop_engine.h
+++ b/src/prop/prop_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file prop_engine.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Clark Barrett, Liana Hadarean, Christopher L. Conway, Kshitij Bansal, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The PropEngine (propositional engine); main interface point
** between CVC4's SMT infrastructure and the SAT solver
@@ -134,7 +134,7 @@ public:
* @param removable whether this lemma can be quietly removed based
* on an activity heuristic (or not)
*/
- void assertLemma(TNode node, bool negated, bool removable, ProofRule rule, TNode from = TNode::null());
+ void assertLemma(TNode node, bool negated, bool removable, ProofRule rule, theory::TheoryId ownerTheory, TNode from = TNode::null());
/**
* If ever n is decided upon, it must be in the given phase. This
diff --git a/src/prop/registrar.h b/src/prop/registrar.h
index b6dd021ab..bd8088921 100644
--- a/src/prop/registrar.h
+++ b/src/prop/registrar.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file registrar.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Tim King, Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Class to encapsulate preregistration duties
**
diff --git a/src/prop/sat_solver.h b/src/prop/sat_solver.h
index 1383308a3..92696ae25 100644
--- a/src/prop/sat_solver.h
+++ b/src/prop/sat_solver.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sat_solver.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters, Liana Hadarean
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief SAT Solver.
**
@@ -26,6 +26,7 @@
#include "context/cdlist.h"
#include "context/context.h"
#include "expr/node.h"
+#include "proof/clause_id.h"
#include "prop/sat_solver_types.h"
#include "util/statistics_registry.h"
@@ -37,8 +38,6 @@ namespace prop {
class TheoryProxy;
-typedef unsigned ClauseId;
-
class SatSolver {
public:
diff --git a/src/prop/sat_solver_factory.cpp b/src/prop/sat_solver_factory.cpp
index c131ca475..092ec72f2 100644
--- a/src/prop/sat_solver_factory.cpp
+++ b/src/prop/sat_solver_factory.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file sat_solver_factory.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Tim King
- ** Minor contributors (to current version): Morgan Deters, Liana Hadarean
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief SAT Solver creation facility.
**
diff --git a/src/prop/sat_solver_factory.h b/src/prop/sat_solver_factory.h
index 6a3053a18..7cc23a8e8 100644
--- a/src/prop/sat_solver_factory.h
+++ b/src/prop/sat_solver_factory.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sat_solver_factory.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Liana Hadarean, Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief SAT Solver.
**
diff --git a/src/prop/sat_solver_types.h b/src/prop/sat_solver_types.h
index c47c2b67b..557f9af65 100644
--- a/src/prop/sat_solver_types.h
+++ b/src/prop/sat_solver_types.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sat_solver_types.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters, Liana Hadarean, Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This class transforms a sequence of formulas into clauses.
**
diff --git a/src/prop/theory_proxy.cpp b/src/prop/theory_proxy.cpp
index 63a09169f..4a4515eb9 100644
--- a/src/prop/theory_proxy.cpp
+++ b/src/prop/theory_proxy.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_proxy.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Kshitij Bansal, Morgan Deters
- ** Minor contributors (to current version): Clark Barrett, Christopher L. Conway, Tim King, Liana Hadarean
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -98,19 +98,30 @@ void TheoryProxy::theoryPropagate(std::vector<SatLiteral>& output) {
void TheoryProxy::explainPropagation(SatLiteral l, SatClause& explanation) {
TNode lNode = d_cnfStream->getNode(l);
Debug("prop-explain") << "explainPropagation(" << lNode << ")" << std::endl;
- Node theoryExplanation = d_theoryEngine->getExplanation(lNode);
- PROOF(ProofManager::getCnfProof()->pushCurrentAssertion(theoryExplanation); );
- Debug("prop-explain") << "explainPropagation() => " << theoryExplanation << std::endl;
- if (theoryExplanation.getKind() == kind::AND) {
- Node::const_iterator it = theoryExplanation.begin();
- Node::const_iterator it_end = theoryExplanation.end();
+
+ NodeTheoryPair theoryExplanation = d_theoryEngine->getExplanationAndExplainer(lNode);
+ Node explanationNode = theoryExplanation.node;
+ theory::TheoryId explainerTheory = theoryExplanation.theory;
+
+ PROOF({
+ ProofManager::getCnfProof()->pushCurrentAssertion(explanationNode);
+ ProofManager::getCnfProof()->setExplainerTheory(explainerTheory);
+
+ Debug("pf::sat") << "TheoryProxy::explainPropagation: setting explainer theory to: "
+ << explainerTheory << std::endl;
+ });
+
+ Debug("prop-explain") << "explainPropagation() => " << explanationNode << std::endl;
+ if (explanationNode.getKind() == kind::AND) {
+ Node::const_iterator it = explanationNode.begin();
+ Node::const_iterator it_end = explanationNode.end();
explanation.push_back(l);
for (; it != it_end; ++ it) {
explanation.push_back(~d_cnfStream->getLiteral(*it));
}
} else {
explanation.push_back(l);
- explanation.push_back(~d_cnfStream->getLiteral(theoryExplanation));
+ explanation.push_back(~d_cnfStream->getLiteral(explanationNode));
}
}
@@ -164,7 +175,7 @@ void TheoryProxy::notifyRestart() {
if(lemmaCount % 1 == 0) {
Debug("shared") << "=) " << asNode << std::endl;
}
- d_propEngine->assertLemma(d_theoryEngine->preprocess(asNode), false, true, RULE_INVALID);
+ d_propEngine->assertLemma(d_theoryEngine->preprocess(asNode), false, true, RULE_INVALID, theory::THEORY_LAST);
} else {
Debug("shared") << "=(" << asNode << std::endl;
}
diff --git a/src/prop/theory_proxy.h b/src/prop/theory_proxy.h
index 0e2b885d9..88c6ca94a 100644
--- a/src/prop/theory_proxy.h
+++ b/src/prop/theory_proxy.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_proxy.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean, Kshitij Bansal, Morgan Deters
- ** Minor contributors (to current version): Christopher L. Conway, Tim King
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief SAT Solver.
**
diff --git a/src/smt/boolean_terms.cpp b/src/smt/boolean_terms.cpp
index 07d78a6fd..40b757598 100644
--- a/src/smt/boolean_terms.cpp
+++ b/src/smt/boolean_terms.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file boolean_terms.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -137,26 +137,6 @@ Node BooleanTermConverter::rewriteAs(TNode in, TypeNode as, std::map< TypeNode,
TypeNode in_t = in.getType();
if( processing.find( in_t )==processing.end() ){
processing[in_t] = true;
- if(in.getType().isRecord()) {
- Assert(as.isRecord());
- const Record& inRec = in.getType().getRecord();
- const Record& asRec = as.getRecord();
- Assert(inRec.getNumFields() == asRec.getNumFields());
- const Datatype & dt = ((DatatypeType)in.getType().toType()).getDatatype();
- NodeBuilder<> nb(kind::APPLY_CONSTRUCTOR);
- nb << NodeManager::currentNM()->mkConst(asRec);
- for(size_t i = 0; i < asRec.getNumFields(); ++i) {
- Assert(inRec[i].first == asRec[i].first);
- Node arg = NodeManager::currentNM()->mkNode(kind::APPLY_SELECTOR_TOTAL, dt[0][i].getSelector(), in);
- if(inRec[i].second != asRec[i].second) {
- arg = rewriteAs(arg, TypeNode::fromType(asRec[i].second), processing);
- }
- nb << arg;
- }
- Node out = nb;
- processing.erase( in_t );
- return out;
- }
if(in.getType().isDatatype()) {
if(as.isBoolean() && in.getType().hasAttribute(BooleanTermAttr())) {
processing.erase( in_t );
diff --git a/src/smt/boolean_terms.h b/src/smt/boolean_terms.h
index e1865f29f..0a63f7fd8 100644
--- a/src/smt/boolean_terms.h
+++ b/src/smt/boolean_terms.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file boolean_terms.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt/command.cpp b/src/smt/command.cpp
index d6ec0769a..bd514e2a8 100644
--- a/src/smt/command.cpp
+++ b/src/smt/command.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file command.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Dejan Jovanovic, Andrew Reynolds, Francois Bobot
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of command objects.
**
@@ -376,6 +376,59 @@ std::string QueryCommand::getCommandName() const throw() {
return "query";
}
+
+/* class CheckSynthCommand */
+
+CheckSynthCommand::CheckSynthCommand() throw() :
+ d_expr() {
+}
+
+CheckSynthCommand::CheckSynthCommand(const Expr& expr, bool inUnsatCore) throw() :
+ d_expr(expr), d_inUnsatCore(inUnsatCore) {
+}
+
+Expr CheckSynthCommand::getExpr() const throw() {
+ return d_expr;
+}
+
+void CheckSynthCommand::invoke(SmtEngine* smtEngine) throw() {
+ try {
+ d_result = smtEngine->checkSynth(d_expr);
+ d_commandStatus = CommandSuccess::instance();
+ } catch(exception& e) {
+ d_commandStatus = new CommandFailure(e.what());
+ }
+}
+
+Result CheckSynthCommand::getResult() const throw() {
+ return d_result;
+}
+
+void CheckSynthCommand::printResult(std::ostream& out, uint32_t verbosity) const throw() {
+ if(! ok()) {
+ this->Command::printResult(out, verbosity);
+ } else {
+ out << d_result << endl;
+ }
+}
+
+Command* CheckSynthCommand::exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap) {
+ CheckSynthCommand* c = new CheckSynthCommand(d_expr.exportTo(exprManager, variableMap), d_inUnsatCore);
+ c->d_result = d_result;
+ return c;
+}
+
+Command* CheckSynthCommand::clone() const {
+ CheckSynthCommand* c = new CheckSynthCommand(d_expr, d_inUnsatCore);
+ c->d_result = d_result;
+ return c;
+}
+
+std::string CheckSynthCommand::getCommandName() const throw() {
+ return "check-synth";
+}
+
+
/* class ResetCommand */
void ResetCommand::invoke(SmtEngine* smtEngine) throw() {
@@ -1233,6 +1286,60 @@ std::string GetSynthSolutionCommand::getCommandName() const throw() {
return "get-instantiations";
}
+/* class GetQuantifierEliminationCommand */
+
+GetQuantifierEliminationCommand::GetQuantifierEliminationCommand() throw() :
+ d_expr() {
+}
+
+GetQuantifierEliminationCommand::GetQuantifierEliminationCommand(const Expr& expr, bool doFull) throw() :
+ d_expr(expr), d_doFull(doFull) {
+}
+
+Expr GetQuantifierEliminationCommand::getExpr() const throw() {
+ return d_expr;
+}
+bool GetQuantifierEliminationCommand::getDoFull() const throw() {
+ return d_doFull;
+}
+
+void GetQuantifierEliminationCommand::invoke(SmtEngine* smtEngine) throw() {
+ try {
+ d_result = smtEngine->doQuantifierElimination(d_expr, d_doFull);
+ d_commandStatus = CommandSuccess::instance();
+ } catch(exception& e) {
+ d_commandStatus = new CommandFailure(e.what());
+ }
+}
+
+Expr GetQuantifierEliminationCommand::getResult() const throw() {
+ return d_result;
+}
+
+void GetQuantifierEliminationCommand::printResult(std::ostream& out, uint32_t verbosity) const throw() {
+ if(! ok()) {
+ this->Command::printResult(out, verbosity);
+ } else {
+ out << d_result << endl;
+ }
+}
+
+Command* GetQuantifierEliminationCommand::exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap) {
+ GetQuantifierEliminationCommand* c = new GetQuantifierEliminationCommand(d_expr.exportTo(exprManager, variableMap), d_doFull);
+ c->d_result = d_result;
+ return c;
+}
+
+Command* GetQuantifierEliminationCommand::clone() const {
+ GetQuantifierEliminationCommand* c = new GetQuantifierEliminationCommand(d_expr, d_doFull);
+ c->d_result = d_result;
+ return c;
+}
+
+std::string GetQuantifierEliminationCommand::getCommandName() const throw() {
+ return d_doFull ? "get-qe" : "get-qe-disjunct";
+}
+
/* class GetUnsatCoreCommand */
GetUnsatCoreCommand::GetUnsatCoreCommand() throw() {
diff --git a/src/smt/command.h b/src/smt/command.h
index 248e69b0e..db4efd819 100644
--- a/src/smt/command.h
+++ b/src/smt/command.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file command.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Christopher L. Conway, Dejan Jovanovic, Francois Bobot, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Francois Bobot
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the command pattern on SmtEngines.
**
@@ -501,6 +501,24 @@ public:
std::string getCommandName() const throw();
};/* class QueryCommand */
+class CVC4_PUBLIC CheckSynthCommand : public Command {
+protected:
+ Expr d_expr;
+ Result d_result;
+ bool d_inUnsatCore;
+public:
+ CheckSynthCommand() throw();
+ CheckSynthCommand(const Expr& expr, bool inUnsatCore = true) throw();
+ ~CheckSynthCommand() throw() {}
+ Expr getExpr() const throw();
+ void invoke(SmtEngine* smtEngine) throw();
+ Result getResult() const throw();
+ void printResult(std::ostream& out, uint32_t verbosity = 2) const throw();
+ Command* exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap);
+ Command* clone() const;
+ std::string getCommandName() const throw();
+};/* class CheckSynthCommand */
+
// this is TRANSFORM in the CVC presentation language
class CVC4_PUBLIC SimplifyCommand : public Command {
protected:
@@ -624,6 +642,25 @@ public:
std::string getCommandName() const throw();
};/* class GetSynthSolutionCommand */
+class CVC4_PUBLIC GetQuantifierEliminationCommand : public Command {
+protected:
+ Expr d_expr;
+ bool d_doFull;
+ Expr d_result;
+public:
+ GetQuantifierEliminationCommand() throw();
+ GetQuantifierEliminationCommand(const Expr& expr, bool doFull) throw();
+ ~GetQuantifierEliminationCommand() throw() {}
+ Expr getExpr() const throw();
+ bool getDoFull() const throw();
+ void invoke(SmtEngine* smtEngine) throw();
+ Expr getResult() const throw();
+ void printResult(std::ostream& out, uint32_t verbosity = 2) const throw();
+ Command* exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap);
+ Command* clone() const;
+ std::string getCommandName() const throw();
+};/* class GetQuantifierEliminationCommand */
+
class CVC4_PUBLIC GetUnsatCoreCommand : public Command {
protected:
UnsatCore d_result;
diff --git a/src/smt/command_list.cpp b/src/smt/command_list.cpp
index 2319d9539..78e5914aa 100644
--- a/src/smt/command_list.cpp
+++ b/src/smt/command_list.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file command_list.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A context-sensitive list of Commands, and their cleanup
**
diff --git a/src/smt/command_list.h b/src/smt/command_list.h
index 47185b365..ea6b64940 100644
--- a/src/smt/command_list.h
+++ b/src/smt/command_list.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file command_list.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A context-sensitive list of Commands, and their cleanup
**
diff --git a/src/smt/dump.cpp b/src/smt/dump.cpp
index 3b9ec3273..eee7b901a 100644
--- a/src/smt/dump.cpp
+++ b/src/smt/dump.cpp
@@ -1,20 +1,21 @@
/********************* */
/*! \file dump.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Dump utility classes and functions
**
** Dump utility classes and functions.
**/
-#include "smt/dump.h"
+#include "smt/dump.h"
+#include "lib/strtok_r.h"
#include "base/output.h"
namespace CVC4 {
diff --git a/src/smt/dump.h b/src/smt/dump.h
index a6fa899da..2abfe5408 100644
--- a/src/smt/dump.h
+++ b/src/smt/dump.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file dump.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Dump utility classes and functions
**
diff --git a/src/smt/ite_removal.cpp b/src/smt/ite_removal.cpp
index c0c6ed02b..fcd0c3254 100644
--- a/src/smt/ite_removal.cpp
+++ b/src/smt/ite_removal.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ite_removal.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Tim King, Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal, Andrew Reynolds, Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Removal of term ITEs
**
diff --git a/src/smt/ite_removal.h b/src/smt/ite_removal.h
index d6d820f89..c0a46c316 100644
--- a/src/smt/ite_removal.h
+++ b/src/smt/ite_removal.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ite_removal.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Kshitij Bansal, Tim King, Morgan Deters
- ** Minor contributors (to current version): Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Removal of term ITEs
**
diff --git a/src/smt/logic_exception.h b/src/smt/logic_exception.h
index a641f8d21..93db29a9b 100644
--- a/src/smt/logic_exception.h
+++ b/src/smt/logic_exception.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file logic_exception.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An exception that is thrown when a feature is used outside
** the logic that CVC4 is currently using
diff --git a/src/smt/logic_request.cpp b/src/smt/logic_request.cpp
index 09559eb8d..dc6a2d6b7 100644
--- a/src/smt/logic_request.cpp
+++ b/src/smt/logic_request.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file logic_request.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt/logic_request.h b/src/smt/logic_request.h
index 94c6c2a5e..7b41886bd 100644
--- a/src/smt/logic_request.h
+++ b/src/smt/logic_request.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file logic_request.h
** \verbatim
- ** Original author: Martin Brain <>
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Martin Brain, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An object to request logic widening in the running SmtEngine
**
diff --git a/src/smt/managed_ostreams.cpp b/src/smt/managed_ostreams.cpp
index 1901f731d..cae6ac67f 100644
--- a/src/smt/managed_ostreams.cpp
+++ b/src/smt/managed_ostreams.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file managed_ostreams.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Wrappers to handle memory management of ostreams.
**
diff --git a/src/smt/managed_ostreams.h b/src/smt/managed_ostreams.h
index 6dc785027..56c517a87 100644
--- a/src/smt/managed_ostreams.h
+++ b/src/smt/managed_ostreams.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file managed_ostreams.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Wrappers to handle memory management of ostreams.
**
diff --git a/src/smt/model.cpp b/src/smt/model.cpp
index 15ecbadfb..a38862307 100644
--- a/src/smt/model.cpp
+++ b/src/smt/model.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file model.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief implementation of Model class
**/
diff --git a/src/smt/model.h b/src/smt/model.h
index 4bbcb5f7d..768cb3e6a 100644
--- a/src/smt/model.h
+++ b/src/smt/model.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file model.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Model class
**/
diff --git a/src/smt/model_postprocessor.cpp b/src/smt/model_postprocessor.cpp
index aa645954b..369c5d48f 100644
--- a/src/smt/model_postprocessor.cpp
+++ b/src/smt/model_postprocessor.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file model_postprocessor.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief
**
diff --git a/src/smt/model_postprocessor.h b/src/smt/model_postprocessor.h
index 024f4f3a3..d9e749677 100644
--- a/src/smt/model_postprocessor.h
+++ b/src/smt/model_postprocessor.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file model_postprocessor.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief
**
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index 007c5e049..5bd1cbdfc 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt_engine.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Christopher L. Conway, Tianyi Liang, Martin Brain <>, Kshitij Bansal, Liana Hadarean, Dejan Jovanovic, Tim King, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The main entry point into the CVC4 library's SMT interface
**
@@ -110,9 +110,18 @@ using namespace CVC4::context;
using namespace CVC4::theory;
namespace CVC4 {
-
namespace smt {
+struct DeleteCommandFunction : public std::unary_function<const Command*, void>
+{
+ void operator()(const Command* command) { delete command; }
+};
+
+void DeleteAndClearCommandVector(std::vector<Command*>& commands) {
+ std::for_each(commands.begin(), commands.end(), DeleteCommandFunction());
+ commands.clear();
+}
+
/** Useful for counting the number of recursive calls. */
class ScopeCounter {
private:
@@ -543,6 +552,11 @@ class SmtEnginePrivate : public NodeManagerListener {
*/
unsigned d_simplifyAssertionsDepth;
+ /** whether certain preprocess steps are necessary */
+ bool d_needsExpandDefs;
+ bool d_needsRewriteBoolTerms;
+ bool d_needsConstrainSubTypes;
+
public:
/**
* Map from skolem variables to index in d_assertions containing
@@ -670,6 +684,9 @@ public:
d_abstractValueMap(&d_fakeContext),
d_abstractValues(),
d_simplifyAssertionsDepth(0),
+ d_needsExpandDefs(true),
+ d_needsRewriteBoolTerms(true),
+ d_needsConstrainSubTypes(true), //TODO
d_iteSkolemMap(),
d_iteRemover(smt.d_userContext),
d_pbsProcessor(smt.d_userContext),
@@ -955,6 +972,45 @@ public:
std::ostream* getReplayLog() const {
return d_managedReplayLog.getReplayLog();
}
+
+ Node replaceQuantifiersWithInstantiations( Node n, std::map< Node, std::vector< Node > >& insts, std::map< Node, Node >& visited ){
+ std::map< Node, Node >::iterator itv = visited.find( n );
+ if( itv!=visited.end() ){
+ return itv->second;
+ }else{
+ Node ret = n;
+ if( n.getKind()==kind::FORALL ){
+ std::map< Node, std::vector< Node > >::iterator it = insts.find( n );
+ if( it==insts.end() ){
+ Trace("smt-qe-debug") << "* " << n << " has no instances" << std::endl;
+ ret = NodeManager::currentNM()->mkConst(true);
+ }else{
+ Trace("smt-qe-debug") << "* " << n << " has " << it->second.size() << " instances" << std::endl;
+ Node reti = it->second.empty() ? NodeManager::currentNM()->mkConst(true) : ( it->second.size()==1 ? it->second[0] : NodeManager::currentNM()->mkNode( kind::AND, it->second ) );
+ Trace("smt-qe-debug") << " return : " << ret << std::endl;
+ //recursive (for nested quantification)
+ ret = replaceQuantifiersWithInstantiations( reti, insts, visited );
+ }
+ }else if( n.getNumChildren()>0 ){
+ bool childChanged = false;
+ std::vector< Node > children;
+ if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
+ children.push_back( n.getOperator() );
+ }
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ Node r = replaceQuantifiersWithInstantiations( n[i], insts, visited );
+ children.push_back( r );
+ childChanged = childChanged || r!=n[i];
+ }
+ if( childChanged ){
+ ret = NodeManager::currentNM()->mkNode( n.getKind(), children );
+ }
+ }
+ visited[n] = ret;
+ return ret;
+ }
+ }
+
};/* class SmtEnginePrivate */
}/* namespace CVC4::smt */
@@ -1007,7 +1063,9 @@ SmtEngine::SmtEngine(ExprManager* em) throw() :
// SatProof and TheoryProofs. The TheoryProofEngine and the SatProof are
// initialized in TheoryEngine and PropEngine respectively.
Assert(d_proofManager == NULL);
- PROOF( d_proofManager = new ProofManager(); );
+#ifdef CVC4_PROOF
+ d_proofManager = new ProofManager();
+#endif
// We have mutual dependency here, so we add the prop engine to the theory
// engine later (it is non-essential there)
@@ -1039,20 +1097,27 @@ SmtEngine::SmtEngine(ExprManager* em) throw() :
}
void SmtEngine::finishInit() {
+ Trace("smt-debug") << "SmtEngine::finishInit" << std::endl;
// ensure that our heuristics are properly set up
setDefaults();
+
+ Trace("smt-debug") << "Making decision engine..." << std::endl;
d_decisionEngine = new DecisionEngine(d_context, d_userContext);
d_decisionEngine->init(); // enable appropriate strategies
+ Trace("smt-debug") << "Making prop engine..." << std::endl;
d_propEngine = new PropEngine(d_theoryEngine, d_decisionEngine, d_context,
d_userContext, d_private->getReplayLog(),
d_replayStream, d_channels);
+ Trace("smt-debug") << "Setting up theory engine..." << std::endl;
d_theoryEngine->setPropEngine(d_propEngine);
d_theoryEngine->setDecisionEngine(d_decisionEngine);
+ Trace("smt-debug") << "Finishing init for theory engine..." << std::endl;
d_theoryEngine->finishInit();
+ Trace("smt-debug") << "Set up assertion list..." << std::endl;
// [MGD 10/20/2011] keep around in incremental mode, due to a
// cleanup ordering issue and Nodes/TNodes. If SAT is popped
// first, some user-context-dependent TNodes might still exist
@@ -1073,6 +1138,7 @@ void SmtEngine::finishInit() {
<< SetBenchmarkLogicCommand(everything.getLogicString());
}
+ Trace("smt-debug") << "Dump declaration commands..." << std::endl;
// dump out any pending declaration commands
for(unsigned i = 0; i < d_dumpCommands.size(); ++i) {
Dump("declarations") << *d_dumpCommands[i];
@@ -1081,6 +1147,7 @@ void SmtEngine::finishInit() {
d_dumpCommands.clear();
PROOF( ProofManager::currentPM()->setLogic(d_logic); );
+ Trace("smt-debug") << "SmtEngine::finishInit done" << std::endl;
}
void SmtEngine::finalOptionsAreSet() {
@@ -1155,6 +1222,8 @@ SmtEngine::~SmtEngine() throw() {
}
d_dumpCommands.clear();
+ DeleteAndClearCommandVector(d_modelGlobalCommands);
+
if(d_modelCommands != NULL) {
d_modelCommands->deleteSelf();
}
@@ -1260,15 +1329,7 @@ void SmtEngine::setDefaults() {
Trace("smt") << "turning on quantifier logic, for strings-exp"
<< std::endl;
}
- if(! options::finiteModelFind.wasSetByUser()) {
- options::finiteModelFind.set( true );
- Trace("smt") << "turning on finite-model-find, for strings-exp"
- << std::endl;
- }
if(! options::fmfBoundInt.wasSetByUser()) {
- if(! options::fmfBoundIntLazy.wasSetByUser()) {
- options::fmfBoundIntLazy.set( true );
- }
options::fmfBoundInt.set( true );
Trace("smt") << "turning on fmf-bound-int, for strings-exp" << std::endl;
}
@@ -1644,16 +1705,25 @@ void SmtEngine::setDefaults() {
options::sortInference.set( false );
options::ufssFairnessMonotone.set( false );
}
+ if( d_logic.hasCardinalityConstraints() ){
+ //must have finite model finding on
+ options::finiteModelFind.set( true );
+ }
+
+ //if it contains a theory with non-termination, do not strictly enforce that quantifiers and theory combination must be interleaved
+ if( d_logic.isTheoryEnabled(THEORY_STRINGS) || (d_logic.isTheoryEnabled(THEORY_ARITH) && !d_logic.isLinear()) ){
+ if( !options::instWhenStrictInterleave.wasSetByUser() ){
+ options::instWhenStrictInterleave.set( false );
+ }
+ }
+
//local theory extensions
if( options::localTheoryExt() ){
if( !options::instMaxLevel.wasSetByUser() ){
options::instMaxLevel.set( 0 );
}
}
- if( d_logic.hasCardinalityConstraints() ){
- //must have finite model finding on
- options::finiteModelFind.set( true );
- }
+
if(options::fmfBoundIntLazy.wasSetByUser() && options::fmfBoundIntLazy()) {
options::fmfBoundInt.set( true );
}
@@ -1752,26 +1822,25 @@ void SmtEngine::setDefaults() {
if( !options::cbqiPreRegInst.wasSetByUser()) {
options::cbqiPreRegInst.set( true );
}
- }else{
- //counterexample-guided instantiation for non-sygus
- // enable if any quantifiers with arithmetic or datatypes
- if( ( d_logic.isQuantified() && ( d_logic.isTheoryEnabled(THEORY_ARITH) || d_logic.isTheoryEnabled(THEORY_DATATYPES) ) ) ||
- options::cbqiAll() ){
- if( !options::cbqi.wasSetByUser() ){
- options::cbqi.set( true );
- }
- }
- if( options::cbqiSplx() ){
- //implies more general option
+ }
+ //counterexample-guided instantiation for non-sygus
+ // enable if any quantifiers with arithmetic or datatypes
+ if( ( d_logic.isQuantified() && ( d_logic.isTheoryEnabled(THEORY_ARITH) || d_logic.isTheoryEnabled(THEORY_DATATYPES) ) ) ||
+ options::cbqiAll() ){
+ if( !options::cbqi.wasSetByUser() ){
options::cbqi.set( true );
}
- if( options::cbqi() ){
- //must rewrite divk
- if( !options::rewriteDivk.wasSetByUser()) {
- options::rewriteDivk.set( true );
- }
+ }
+ if( options::cbqiSplx() ){
+ //implies more general option
+ options::cbqi.set( true );
+ }
+ if( options::cbqi() ){
+ //must rewrite divk
+ if( !options::rewriteDivk.wasSetByUser()) {
+ options::rewriteDivk.set( true );
}
- if( options::cbqi() && d_logic.isPure(THEORY_ARITH) ){
+ if( d_logic.isPure(THEORY_ARITH) ){
options::cbqiAll.set( false );
if( !options::quantConflictFind.wasSetByUser() ){
options::quantConflictFind.set( false );
@@ -1787,8 +1856,12 @@ void SmtEngine::setDefaults() {
}
}
}
-
//implied options...
+ if( options::strictTriggers() ){
+ if( !options::userPatternsQuant.wasSetByUser() ){
+ options::userPatternsQuant.set( quantifiers::USER_PAT_MODE_TRUST );
+ }
+ }
if( options::qcfMode.wasSetByUser() || options::qcfTConstraint() ){
options::quantConflictFind.set( true );
}
@@ -1843,6 +1916,9 @@ void SmtEngine::setDefaults() {
options::preSkolemQuantNested.set( false );
}
}
+ if( !d_logic.isTheoryEnabled(THEORY_DATATYPES) ){
+ options::quantDynamicSplit.set( quantifiers::QUANT_DSPLIT_MODE_NONE );
+ }
//until bugs 371,431 are fixed
if( ! options::minisatUseElim.wasSetByUser()){
@@ -2063,6 +2139,8 @@ CVC4::SExpr SmtEngine::getInfo(const std::string& key) const
void SmtEngine::defineFunction(Expr func,
const std::vector<Expr>& formals,
Expr formula) {
+ SmtScope smts(this);
+ doPendingPops();
Trace("smt") << "SMT defineFunction(" << func << ")" << endl;
for(std::vector<Expr>::const_iterator i = formals.begin(); i != formals.end(); ++i) {
if((*i).getKind() != kind::BOUND_VARIABLE) {
@@ -2081,7 +2159,6 @@ void SmtEngine::defineFunction(Expr func,
DefineFunctionCommand c(ss.str(), func, formals, formula);
addToModelCommandAndDump(c, ExprManager::VAR_FLAG_DEFINED, true, "declarations");
- SmtScope smts(this);
PROOF( if (options::checkUnsatCores()) {
d_defineCommands.push_back(c.clone());
@@ -3572,6 +3649,7 @@ Result SmtEngine::check() {
// Make sure the prop layer has all of the assertions
Trace("smt") << "SmtEngine::check(): processing assertions" << endl;
d_private->processAssertions();
+ Trace("smt") << "SmtEngine::check(): done processing assertions" << endl;
// Turn off stop only for QF_LRA
// TODO: Bring up in a meeting where to put this
@@ -3807,6 +3885,7 @@ void SmtEnginePrivate::processAssertions() {
Debug("smt") << " d_assertions : " << d_assertions.size() << endl;
+
dumpAssertions("pre-constrain-subtypes", d_assertions);
{
// Any variables of subtype types need to be constrained properly.
@@ -4141,6 +4220,7 @@ void SmtEnginePrivate::processAssertions() {
Trace("smt-proc") << "SmtEnginePrivate::processAssertions() end" << endl;
dumpAssertions("post-everything", d_assertions);
+
//set instantiation level of everything to zero
if( options::instLevelInputOnly() && options::instMaxLevel()!=-1 ){
@@ -4210,13 +4290,22 @@ void SmtEngine::ensureBoolean(const Expr& e) throw(TypeCheckingException) {
}
Result SmtEngine::checkSat(const Expr& ex, bool inUnsatCore) throw(TypeCheckingException, ModalException, LogicException) {
+ return checkSatisfiability( ex, inUnsatCore, false );
+}/* SmtEngine::checkSat() */
+
+Result SmtEngine::query(const Expr& ex, bool inUnsatCore) throw(TypeCheckingException, ModalException, LogicException) {
+ Assert(!ex.isNull());
+ return checkSatisfiability( ex, inUnsatCore, true );
+}/* SmtEngine::query() */
+
+Result SmtEngine::checkSatisfiability(const Expr& ex, bool inUnsatCore, bool isQuery) {
try {
Assert(ex.isNull() || ex.getExprManager() == d_exprManager);
SmtScope smts(this);
finalOptionsAreSet();
doPendingPops();
- Trace("smt") << "SmtEngine::checkSat(" << ex << ")" << endl;
+ Trace("smt") << "SmtEngine::" << (isQuery ? "query" : "checkSat") << "(" << ex << ")" << endl;
if(d_queryMade && !options::incrementalSolving()) {
throw ModalException("Cannot make multiple queries unless "
@@ -4247,14 +4336,15 @@ Result SmtEngine::checkSat(const Expr& ex, bool inUnsatCore) throw(TypeCheckingE
// Add the formula
if(!e.isNull()) {
d_problemExtended = true;
+ Expr ea = isQuery ? e.notExpr() : e;
if(d_assertionList != NULL) {
- d_assertionList->push_back(e);
+ d_assertionList->push_back(ea);
}
- d_private->addFormula(e.getNode(), inUnsatCore);
+ d_private->addFormula(ea.getNode(), inUnsatCore);
}
Result r(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON);
- r = check().asSatisfiabilityResult();
+ r = isQuery ? check().asValidityResult() : check().asSatisfiabilityResult();
if (options::solveIntAsBV() > 0 &&r.asSatisfiabilityResult().isSat() == Result::UNSAT) {
r = Result(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON);
@@ -4265,7 +4355,11 @@ Result SmtEngine::checkSat(const Expr& ex, bool inUnsatCore) throw(TypeCheckingE
// Dump the query if requested
if(Dump.isOn("benchmark")) {
// the expr already got dumped out if assertion-dumping is on
- Dump("benchmark") << CheckSatCommand(ex);
+ if( isQuery ){
+ Dump("benchmark") << QueryCommand(ex);
+ }else{
+ Dump("benchmark") << CheckSatCommand(ex);
+ }
}
// Pop the context
@@ -4276,7 +4370,7 @@ Result SmtEngine::checkSat(const Expr& ex, bool inUnsatCore) throw(TypeCheckingE
d_problemExtended = false;
- Trace("smt") << "SmtEngine::checkSat(" << e << ") => " << r << endl;
+ Trace("smt") << "SmtEngine::" << (isQuery ? "query" : "checkSat") << "(" << e << ") => " << r << endl;
// Check that SAT results generate a model correctly.
if(options::checkModels()) {
@@ -4307,98 +4401,85 @@ Result SmtEngine::checkSat(const Expr& ex, bool inUnsatCore) throw(TypeCheckingE
Result::RESOURCEOUT : Result::TIMEOUT;
return Result(Result::SAT_UNKNOWN, why, d_filename);
}
-}/* SmtEngine::checkSat() */
-
-Result SmtEngine::query(const Expr& ex, bool inUnsatCore) throw(TypeCheckingException, ModalException, LogicException) {
- Assert(!ex.isNull());
- Assert(ex.getExprManager() == d_exprManager);
- SmtScope smts(this);
- finalOptionsAreSet();
- doPendingPops();
- Trace("smt") << "SMT query(" << ex << ")" << endl;
-
- try {
- if(d_queryMade && !options::incrementalSolving()) {
- throw ModalException("Cannot make multiple queries unless "
- "incremental solving is enabled "
- "(try --incremental)");
- }
-
- // Substitute out any abstract values in ex
- Expr e = d_private->substituteAbstractValues(Node::fromExpr(ex)).toExpr();
- // Ensure that the expression is type-checked at this point, and Boolean
- ensureBoolean(e);
-
- // check to see if a postsolve() is pending
- if(d_needPostsolve) {
- d_theoryEngine->postsolve();
- d_needPostsolve = false;
- }
-
- // Push the context
- internalPush();
-
- // Note that a query has been made
- d_queryMade = true;
-
- // Add the formula
- d_problemExtended = true;
- if(d_assertionList != NULL) {
- d_assertionList->push_back(e.notExpr());
- }
- d_private->addFormula(e.getNode().notNode(), inUnsatCore);
-
- // Run the check
- Result r(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON);
- r = check().asValidityResult();
- d_needPostsolve = true;
-
- // Dump the query if requested
- if(Dump.isOn("benchmark")) {
- // the expr already got dumped out if assertion-dumping is on
- Dump("benchmark") << QueryCommand(ex);
- }
-
- // Pop the context
- internalPop();
-
- // Remember the status
- d_status = r;
-
- d_problemExtended = false;
+}
- Trace("smt") << "SMT query(" << e << ") ==> " << r << endl;
- // Check that SAT results generate a model correctly.
- if(options::checkModels()) {
- if(r.asSatisfiabilityResult().isSat() == Result::SAT ||
- (r.isUnknown() && r.whyUnknown() == Result::INCOMPLETE) ){
- checkModel(/* hard failure iff */ ! r.isUnknown());
- }
- }
- // Check that UNSAT results generate a proof correctly.
- if(options::checkProofs()) {
- if(r.asSatisfiabilityResult().isSat() == Result::UNSAT) {
- TimerStat::CodeTimer checkProofTimer(d_stats->d_checkProofTime);
- checkProof();
- }
- }
- // Check that UNSAT results generate an unsat core correctly.
- if(options::checkUnsatCores()) {
- if(r.asSatisfiabilityResult().isSat() == Result::UNSAT) {
- TimerStat::CodeTimer checkUnsatCoreTimer(d_stats->d_checkUnsatCoreTime);
- checkUnsatCore();
+Result SmtEngine::checkSynth(const Expr& e) throw(TypeCheckingException, ModalException, LogicException) {
+ SmtScope smts(this);
+ Trace("smt") << "Check synth: " << e << std::endl;
+ Trace("smt-synth") << "Check synthesis conjecture: " << e << std::endl;
+ Expr e_check = e;
+ Node conj = Node::fromExpr( e );
+ Assert( conj.getKind()==kind::FORALL );
+ //possibly run quantifier elimination to make formula into single invocation
+ if( conj[1].getKind()==kind::EXISTS ){
+ Node conj_se = conj[1][1];
+
+ Trace("smt-synth") << "Compute single invocation for " << conj_se << "..." << std::endl;
+ quantifiers::SingleInvocationPartition sip( kind::APPLY );
+ sip.init( conj_se );
+ Trace("smt-synth") << "...finished, got:" << std::endl;
+ sip.debugPrint("smt-synth");
+
+ if( !sip.isPurelySingleInvocation() && sip.isNonGroundSingleInvocation() ){
+ //We are in the case where our synthesis conjecture is exists f. forall xy. P( f( x ), x, y ), P does not contain f.
+ //The following will run QE on (exists z x.) exists y. P( z, x, y ) to obtain Q( z, x ),
+ // and then constructs exists f. forall x. Q( f( x ), x ), where Q does not contain f. We invoke synthesis solver on this result.
+
+ //create new smt engine to do quantifier elimination
+ SmtEngine smt_qe( d_exprManager );
+ smt_qe.setLogic(getLogicInfo());
+ Trace("smt-synth") << "Property is non-ground single invocation, run QE to obtain single invocation." << std::endl;
+ //partition variables
+ std::vector< Node > qe_vars;
+ std::vector< Node > nqe_vars;
+ for( unsigned i=0; i<sip.d_all_vars.size(); i++ ){
+ Node v = sip.d_all_vars[i];
+ if( std::find( sip.d_si_vars.begin(), sip.d_si_vars.end(), v )==sip.d_si_vars.end() ){
+ qe_vars.push_back( v );
+ }else{
+ nqe_vars.push_back( v );
+ }
+ }
+ std::vector< Node > orig;
+ std::vector< Node > subs;
+ //skolemize non-qe variables
+ for( unsigned i=0; i<nqe_vars.size(); i++ ){
+ Node k = NodeManager::currentNM()->mkSkolem( "k", nqe_vars[i].getType(), "qe for non-ground single invocation" );
+ orig.push_back( nqe_vars[i] );
+ subs.push_back( k );
+ Trace("smt-synth") << " subs : " << nqe_vars[i] << " -> " << k << std::endl;
+ }
+ for( std::map< Node, bool >::iterator it = sip.d_funcs.begin(); it != sip.d_funcs.end(); ++it ){
+ orig.push_back( sip.d_func_inv[it->first] );
+ Node k = NodeManager::currentNM()->mkSkolem( "k", sip.d_func_fo_var[it->first].getType(), "qe for function in non-ground single invocation" );
+ subs.push_back( k );
+ Trace("smt-synth") << " subs : " << sip.d_func_inv[it->first] << " -> " << k << std::endl;
+ }
+ Node conj_se_ngsi = sip.getFullSpecification();
+ Node conj_se_ngsi_subs = conj_se_ngsi.substitute( orig.begin(), orig.end(), subs.begin(), subs.end() );
+ Assert( !qe_vars.empty() );
+ conj_se_ngsi_subs = NodeManager::currentNM()->mkNode( kind::EXISTS, NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, qe_vars ), conj_se_ngsi_subs );
+
+ Trace("smt-synth") << "Run quantifier elimination on " << conj_se_ngsi_subs << std::endl;
+ Expr qe_res = smt_qe.doQuantifierElimination( conj_se_ngsi_subs.toExpr(), true, false );
+ Trace("smt-synth") << "Result : " << qe_res << std::endl;
+
+ //create single invocation conjecture
+ Node qe_res_n = Node::fromExpr( qe_res );
+ qe_res_n = qe_res_n.substitute( subs.begin(), subs.end(), orig.begin(), orig.end() );
+ if( !nqe_vars.empty() ){
+ qe_res_n = NodeManager::currentNM()->mkNode( kind::EXISTS, NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, nqe_vars ), qe_res_n );
+ }
+ Assert( conj.getNumChildren()==3 );
+ qe_res_n = NodeManager::currentNM()->mkNode( kind::FORALL, conj[0], qe_res_n, conj[2] );
+ Trace("smt-synth") << "Converted conjecture after QE : " << qe_res_n << std::endl;
+ e_check = qe_res_n.toExpr();
}
}
-
- return r;
- } catch (UnsafeInterruptException& e) {
- AlwaysAssert(d_private->getResourceManager()->out());
- Result::UnknownExplanation why = d_private->getResourceManager()->outOfResources() ?
- Result::RESOURCEOUT : Result::TIMEOUT;
- return Result(Result::VALIDITY_UNKNOWN, why, d_filename);
- }
-}/* SmtEngine::query() */
+
+ return checkSatisfiability( e_check, true, false );
+}
Result SmtEngine::assertFormula(const Expr& ex, bool inUnsatCore) throw(TypeCheckingException, LogicException, UnsafeInterruptException) {
Assert(ex.getExprManager() == d_exprManager);
@@ -5017,6 +5098,77 @@ void SmtEngine::printSynthSolution( std::ostream& out ) {
}
}
+Expr SmtEngine::doQuantifierElimination(const Expr& e, bool doFull, bool strict) throw(TypeCheckingException, ModalException, LogicException) {
+ SmtScope smts(this);
+ if(!d_logic.isPure(THEORY_ARITH) && strict){
+ Warning() << "Unexpected logic for quantifier elimination " << d_logic << endl;
+ }
+ Trace("smt-qe") << "Do quantifier elimination " << e << std::endl;
+ Node n_e = Node::fromExpr( e );
+ if( n_e.getKind()!=kind::EXISTS ){
+ throw ModalException("Expecting an existentially quantified formula as argument to get-qe.");
+ }
+ //tag the quantified formula with the quant-elim attribute
+ TypeNode t = NodeManager::currentNM()->booleanType();
+ Node n_attr = NodeManager::currentNM()->mkSkolem("qe", t, "Auxiliary variable for qe attr.");
+ std::vector< Node > node_values;
+ d_theoryEngine->setUserAttribute( doFull ? "quant-elim" : "quant-elim-partial", n_attr, node_values, "");
+ n_attr = NodeManager::currentNM()->mkNode(kind::INST_ATTRIBUTE, n_attr);
+ n_attr = NodeManager::currentNM()->mkNode(kind::INST_PATTERN_LIST, n_attr);
+ std::vector< Node > e_children;
+ e_children.push_back( n_e[0] );
+ e_children.push_back( n_e[1] );
+ e_children.push_back( n_attr );
+ Node nn_e = NodeManager::currentNM()->mkNode( kind::EXISTS, e_children );
+ Trace("smt-qe-debug") << "Query for quantifier elimination : " << nn_e << std::endl;
+ Assert( nn_e.getNumChildren()==3 );
+ Result r = checkSatisfiability(nn_e.toExpr(), true, true);
+ Trace("smt-qe") << "Query returned " << r << std::endl;
+ if(r.asSatisfiabilityResult().isSat() != Result::UNSAT ) {
+ if( r.asSatisfiabilityResult().isSat() != Result::SAT && doFull ){
+ stringstream ss;
+ ss << "While performing quantifier elimination, unexpected result : " << r << " for query.";
+ InternalError(ss.str().c_str());
+ }
+ //get the instantiations for all quantified formulas
+ std::map< Node, std::vector< Node > > insts;
+ d_theoryEngine->getInstantiations( insts );
+ //find the quantified formula that corresponds to the input
+ Node top_q;
+ for( std::map< Node, std::vector< Node > >::iterator it = insts.begin(); it != insts.end(); ++it ){
+ Trace("smt-qe-debug") << "* quantifier " << it->first << " had " << it->second.size() << " instances." << std::endl;
+ if( it->first.getNumChildren()==3 && it->first[2]==n_attr ){
+ top_q = it->first;
+ }
+ }
+ std::map< Node, Node > visited;
+ Node ret_n;
+ if( top_q.isNull() ){
+ //no instances needed
+ ret_n = NodeManager::currentNM()->mkConst(true);
+ visited[top_q] = ret_n;
+ }else{
+ //replace by a conjunction of instances
+ ret_n = d_private->replaceQuantifiersWithInstantiations( top_q, insts, visited );
+ }
+
+ //ensure all instantiations were accounted for
+ for( std::map< Node, std::vector< Node > >::iterator it = insts.begin(); it != insts.end(); ++it ){
+ if( !it->second.empty() && visited.find( it->first )==visited.end() ){
+ stringstream ss;
+ ss << "While performing quantifier elimination, processed a quantified formula : " << it->first;
+ ss << " that was not related to the query. Try option --simplification=none.";
+ InternalError(ss.str().c_str());
+ }
+ }
+ Trace("smt-qe") << "Returned : " << ret_n << std::endl;
+ ret_n = Rewriter::rewrite( ret_n.negate() );
+ return ret_n.toExpr();
+ }else {
+ return NodeManager::currentNM()->mkConst(true).toExpr();
+ }
+}
+
vector<Expr> SmtEngine::getAssertions() throw(ModalException) {
SmtScope smts(this);
finalOptionsAreSet();
@@ -5174,7 +5326,7 @@ void SmtEngine::resetAssertions() throw() {
Assert(d_userLevels.size() == 0 && d_userContext->getLevel() == 1);
d_context->popto(0);
d_userContext->popto(0);
- d_modelGlobalCommands.clear();
+ DeleteAndClearCommandVector(d_modelGlobalCommands);
d_userContext->push();
d_context->push();
}
diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h
index 3616762bc..2741cea85 100644
--- a/src/smt/smt_engine.h
+++ b/src/smt/smt_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt_engine.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Martin Brain <>, Tim King, Clark Barrett, Christopher L. Conway, Andrew Reynolds, Kshitij Bansal, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief SmtEngine: the main public entry point of libcvc4.
**
@@ -244,11 +244,11 @@ class CVC4_PUBLIC SmtEngine {
bool d_needPostsolve;
/*
- * Whether to call theory preprocessing during simplification - on by default* but gets turned off if arithRewriteEq is on
+ * Whether to call theory preprocessing during simplification - on
+ * by default* but gets turned off if arithRewriteEq is on
*/
bool d_earlyTheoryPP;
-
/**
* Most recent result of last checkSat/query or (set-info :status).
*/
@@ -401,6 +401,8 @@ class CVC4_PUBLIC SmtEngine {
SmtEngine(const SmtEngine&) CVC4_UNDEFINED;
SmtEngine& operator=(const SmtEngine&) CVC4_UNDEFINED;
+ //check satisfiability (for query and check-sat)
+ Result checkSatisfiability(const Expr& e, bool inUnsatCore, bool isQuery);
public:
/**
@@ -494,6 +496,12 @@ public:
Result checkSat(const Expr& e = Expr(), bool inUnsatCore = true) throw(TypeCheckingException, ModalException, LogicException);
/**
+ * Assert a synthesis conjecture to the current context and call
+ * check(). Returns sat, unsat, or unknown result.
+ */
+ Result checkSynth(const Expr& e) throw(TypeCheckingException, ModalException, LogicException);
+
+ /**
* Simplify a formula without doing "much" work. Does not involve
* the SAT Engine in the simplification, but uses the current
* definitions, assertions, and the current partial model, if one
@@ -553,6 +561,11 @@ public:
void printSynthSolution( std::ostream& out );
/**
+ * Do quantifier elimination, doFull false means just output one disjunct, strict is whether to output warnings.
+ */
+ Expr doQuantifierElimination(const Expr& e, bool doFull, bool strict=true) throw(TypeCheckingException, ModalException, LogicException);
+
+ /**
* Get an unsatisfiable core (only if immediately preceded by an
* UNSAT or VALID query). Only permitted if CVC4 was built with
* unsat-core support and produce-unsat-cores is on.
diff --git a/src/smt/smt_engine_check_proof.cpp b/src/smt/smt_engine_check_proof.cpp
index 354a43cc8..5634a4651 100644
--- a/src/smt/smt_engine_check_proof.cpp
+++ b/src/smt/smt_engine_check_proof.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt_engine_check_proof.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -22,7 +22,7 @@
#include <fstream>
#include <string>
-#warning "TODO: Why is lfsc's check.h being included like this?"
+// #warning "TODO: Why is lfsc's check.h being included like this?"
#include "check.h"
#include "base/configuration_private.h"
@@ -63,17 +63,26 @@ void SmtEngine::checkProof() {
Chat() << "checking proof..." << endl;
- if( !(d_logic.isPure(theory::THEORY_BOOL) ||
- d_logic.isPure(theory::THEORY_BV) ||
- (d_logic.isPure(theory::THEORY_UF) &&
- ! d_logic.hasCardinalityConstraints())) ||
- d_logic.isQuantified()) {
+ if ( !(d_logic.isPure(theory::THEORY_BOOL) ||
+ d_logic.isPure(theory::THEORY_BV) ||
+ d_logic.isPure(theory::THEORY_ARRAY) ||
+ (d_logic.isPure(theory::THEORY_UF) &&
+ ! d_logic.hasCardinalityConstraints())) ||
+ d_logic.isQuantified()) {
// no checking for these yet
Notice() << "Notice: no proof-checking for non-UF/Bool/BV proofs yet" << endl;
return;
}
- char* pfFile = strdup("/tmp/cvc4_proof.XXXXXX");
+ char const* tempDir = getenv("TMPDIR");
+ if (!tempDir) {
+ tempDir = "/tmp";
+ }
+
+ stringstream pfPath;
+ pfPath << tempDir << "/cvc4_proof.XXXXXX";
+
+ char* pfFile = strdup(pfPath.str().c_str());
int fd = mkstemp(pfFile);
// ensure this temp file is removed after
diff --git a/src/smt/smt_engine_scope.cpp b/src/smt/smt_engine_scope.cpp
index 25004c85e..c31ea5736 100644
--- a/src/smt/smt_engine_scope.cpp
+++ b/src/smt/smt_engine_scope.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt_engine_scope.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt/smt_engine_scope.h b/src/smt/smt_engine_scope.h
index 5a7e39849..e00be40d4 100644
--- a/src/smt/smt_engine_scope.h
+++ b/src/smt/smt_engine_scope.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt_engine_scope.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt/smt_statistics_registry.cpp b/src/smt/smt_statistics_registry.cpp
index 5aa9085f5..d34498697 100644
--- a/src/smt/smt_statistics_registry.cpp
+++ b/src/smt/smt_statistics_registry.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file smt_statistic_registry.cpp
+/*! \file smt_statistics_registry.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Accessor for the SmtEngine's StatisticsRegistry.
**
diff --git a/src/smt/smt_statistics_registry.h b/src/smt/smt_statistics_registry.h
index 60a5e7c53..7483e8215 100644
--- a/src/smt/smt_statistics_registry.h
+++ b/src/smt/smt_statistics_registry.h
@@ -1,13 +1,13 @@
/********************* */
-/*! \file smt_statistic_registry.h
+/*! \file smt_statistics_registry.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Accessor for the SmtEngine's StatisticsRegistry.
**
diff --git a/src/smt/update_ostream.h b/src/smt/update_ostream.h
index b87ed69d2..9574c5460 100644
--- a/src/smt/update_ostream.h
+++ b/src/smt/update_ostream.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file update_ostream.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2016 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt_util/boolean_simplification.cpp b/src/smt_util/boolean_simplification.cpp
index fba431350..c5c169301 100644
--- a/src/smt_util/boolean_simplification.cpp
+++ b/src/smt_util/boolean_simplification.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file boolean_simplification.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simple routines for Boolean simplification
**
diff --git a/src/smt_util/boolean_simplification.h b/src/smt_util/boolean_simplification.h
index 27fdc3d28..7207dc336 100644
--- a/src/smt_util/boolean_simplification.h
+++ b/src/smt_util/boolean_simplification.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file boolean_simplification.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simple routines for Boolean simplification
**
diff --git a/src/smt_util/lemma_channels.cpp b/src/smt_util/lemma_channels.cpp
index e75866c5e..083c4adfb 100644
--- a/src/smt_util/lemma_channels.cpp
+++ b/src/smt_util/lemma_channels.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file lemma_channels.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This class is a light container for globals that used to live
** in options. This is NOT a good long term solution, but is a reasonable
diff --git a/src/smt_util/lemma_channels.h b/src/smt_util/lemma_channels.h
index 6cd81795e..54a9db137 100644
--- a/src/smt_util/lemma_channels.h
+++ b/src/smt_util/lemma_channels.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file lemma_channels.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief LemmaChannels is a light container for a pair of input and output
** lemma channels.
diff --git a/src/smt_util/lemma_input_channel.h b/src/smt_util/lemma_input_channel.h
index 44f0b87f5..5d2b092e1 100644
--- a/src/smt_util/lemma_input_channel.h
+++ b/src/smt_util/lemma_input_channel.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file lemma_input_channel.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt_util/lemma_output_channel.h b/src/smt_util/lemma_output_channel.h
index df7abd1e9..6664b0d48 100644
--- a/src/smt_util/lemma_output_channel.h
+++ b/src/smt_util/lemma_output_channel.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file lemma_output_channel.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Mechanism for communication about new lemmas
**
diff --git a/src/smt_util/nary_builder.cpp b/src/smt_util/nary_builder.cpp
index ec012308f..686dcf506 100644
--- a/src/smt_util/nary_builder.cpp
+++ b/src/smt_util/nary_builder.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file nary_builder.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt_util/nary_builder.h b/src/smt_util/nary_builder.h
index c98e01b1b..d8201fbc5 100644
--- a/src/smt_util/nary_builder.h
+++ b/src/smt_util/nary_builder.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file nary_builder.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/smt_util/node_visitor.h b/src/smt_util/node_visitor.h
index c8958b7b5..1906124ab 100644
--- a/src/smt_util/node_visitor.h
+++ b/src/smt_util/node_visitor.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file node_visitor.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean, Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A simple visitor for nodes
**
diff --git a/src/theory/arith/approx_simplex.cpp b/src/theory/arith/approx_simplex.cpp
index 5bbe29bc5..9b8efb783 100644
--- a/src/theory/arith/approx_simplex.cpp
+++ b/src/theory/arith/approx_simplex.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file approx_simplex.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/approx_simplex.h b/src/theory/arith/approx_simplex.h
index 97e6d6b3e..8832fce71 100644
--- a/src/theory/arith/approx_simplex.h
+++ b/src/theory/arith/approx_simplex.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file approx_simplex.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arith_ite_utils.cpp b/src/theory/arith/arith_ite_utils.cpp
index cd180e59e..6695e641f 100644
--- a/src/theory/arith/arith_ite_utils.cpp
+++ b/src/theory/arith/arith_ite_utils.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_ite_utils.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arith_ite_utils.h b/src/theory/arith/arith_ite_utils.h
index 84948cd4b..44c3c080b 100644
--- a/src/theory/arith/arith_ite_utils.h
+++ b/src/theory/arith/arith_ite_utils.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_ite_utils.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arith_rewriter.cpp b/src/theory/arith/arith_rewriter.cpp
index ca286d53a..e53e2ee97 100644
--- a/src/theory/arith/arith_rewriter.cpp
+++ b/src/theory/arith/arith_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_rewriter.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arith_rewriter.h b/src/theory/arith/arith_rewriter.h
index abc25b4af..3cb502249 100644
--- a/src/theory/arith/arith_rewriter.h
+++ b/src/theory/arith/arith_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_rewriter.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Dejan Jovanovic
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter for arithmetic.
**
diff --git a/src/theory/arith/arith_static_learner.cpp b/src/theory/arith/arith_static_learner.cpp
index aac792377..7c648c941 100644
--- a/src/theory/arith/arith_static_learner.cpp
+++ b/src/theory/arith/arith_static_learner.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_static_learner.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arith_static_learner.h b/src/theory/arith/arith_static_learner.h
index 2aa9c9332..4951d34d7 100644
--- a/src/theory/arith/arith_static_learner.h
+++ b/src/theory/arith/arith_static_learner.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_static_learner.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arith_utilities.h b/src/theory/arith/arith_utilities.h
index ffa896012..14329ce4d 100644
--- a/src/theory/arith/arith_utilities.h
+++ b/src/theory/arith/arith_utilities.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arith_utilities.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Arith utilities are common inline functions for dealing with nodes.
**
diff --git a/src/theory/arith/arithvar.cpp b/src/theory/arith/arithvar.cpp
index acae61db0..1ab125a47 100644
--- a/src/theory/arith/arithvar.cpp
+++ b/src/theory/arith/arithvar.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file arithvar.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/arithvar.h b/src/theory/arith/arithvar.h
index 9e4dab4c3..f9ff6da26 100644
--- a/src/theory/arith/arithvar.h
+++ b/src/theory/arith/arithvar.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arithvar.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Defines ArithVar which is the internal representation of variables in arithmetic
**
diff --git a/src/theory/arith/arithvar_node_map.h b/src/theory/arith/arithvar_node_map.h
index ede29017b..da0b03ef2 100644
--- a/src/theory/arith/arithvar_node_map.h
+++ b/src/theory/arith/arithvar_node_map.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file arithvar_node_map.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/attempt_solution_simplex.cpp b/src/theory/arith/attempt_solution_simplex.cpp
index d7b31e2e2..333b0bfae 100644
--- a/src/theory/arith/attempt_solution_simplex.cpp
+++ b/src/theory/arith/attempt_solution_simplex.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file attempt_solution_simplex.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/attempt_solution_simplex.h b/src/theory/arith/attempt_solution_simplex.h
index 49a2dda29..00df8c075 100644
--- a/src/theory/arith/attempt_solution_simplex.h
+++ b/src/theory/arith/attempt_solution_simplex.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file attempt_solution_simplex.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
** decision procedure.
diff --git a/src/theory/arith/bound_counts.h b/src/theory/arith/bound_counts.h
index b5e0124c1..b6417ed63 100644
--- a/src/theory/arith/bound_counts.h
+++ b/src/theory/arith/bound_counts.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bound_counts.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/callbacks.cpp b/src/theory/arith/callbacks.cpp
index b6e579465..766c7424a 100644
--- a/src/theory/arith/callbacks.cpp
+++ b/src/theory/arith/callbacks.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file callbacks.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/callbacks.h b/src/theory/arith/callbacks.h
index d180ceab5..606f4111b 100644
--- a/src/theory/arith/callbacks.h
+++ b/src/theory/arith/callbacks.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file callbacks.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/congruence_manager.cpp b/src/theory/arith/congruence_manager.cpp
index 746121b70..cb8cd8dca 100644
--- a/src/theory/arith/congruence_manager.cpp
+++ b/src/theory/arith/congruence_manager.cpp
@@ -1,24 +1,28 @@
+/********************* */
/*! \file congruence_manager.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Dejan Jovanovic, Morgan Deters, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
** [[ Add lengthier description here ]]
** \todo document this file
**/
+
#include "theory/arith/congruence_manager.h"
#include "base/output.h"
#include "smt/smt_statistics_registry.h"
#include "theory/arith/arith_utilities.h"
#include "theory/arith/constraint.h"
+#include "theory/quantifiers/equality_infer.h"
+#include "options/arith_options.h"
namespace CVC4 {
namespace theory {
@@ -28,6 +32,8 @@ ArithCongruenceManager::ArithCongruenceManager(context::Context* c, ConstraintDa
: d_inConflict(c),
d_raiseConflict(raiseConflict),
d_notify(*this),
+ d_eq_infer(NULL),
+ d_eqi_counter(0,c),
d_keepAlive(c),
d_propagatations(c),
d_explanationMap(c),
@@ -35,7 +41,19 @@ ArithCongruenceManager::ArithCongruenceManager(context::Context* c, ConstraintDa
d_setupLiteral(setup),
d_avariables(avars),
d_ee(d_notify, c, "theory::arith::ArithCongruenceManager", true)
-{}
+{
+ //module to infer additional equalities based on normalization
+ if( options::sNormInferEq() ){
+ d_eq_infer = new quantifiers::EqualityInference(c, true);
+ d_true = NodeManager::currentNM()->mkConst( true );
+ }
+}
+
+ArithCongruenceManager::~ArithCongruenceManager() {
+ if( d_eq_infer ){
+ delete d_eq_infer;
+ }
+}
ArithCongruenceManager::Statistics::Statistics():
d_watchedVariables("theory::arith::congruence::watchedVariables", 0),
@@ -98,10 +116,12 @@ void ArithCongruenceManager::ArithCongruenceNotify::eqNotifyConstantTermMerge(TN
}
}
void ArithCongruenceManager::ArithCongruenceNotify::eqNotifyNewClass(TNode t) {
+ d_acm.eqNotifyNewClass(t);
}
void ArithCongruenceManager::ArithCongruenceNotify::eqNotifyPreMerge(TNode t1, TNode t2) {
}
void ArithCongruenceManager::ArithCongruenceNotify::eqNotifyPostMerge(TNode t1, TNode t2) {
+ d_acm.eqNotifyPostMerge(t1,t2);
}
void ArithCongruenceManager::ArithCongruenceNotify::eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {
}
@@ -297,9 +317,9 @@ bool ArithCongruenceManager::propagate(TNode x){
c->setEqualityEngineProof();
}else if(c->hasProof() && x != rewritten){
if(c->assertedToTheTheory()){
- pushBack(x, rewritten, c->getWitness());
+ pushBack(x);
}else{
- pushBack(x, rewritten);
+ pushBack(x);
}
}else{
Assert(c->hasProof() && x == rewritten);
@@ -339,8 +359,24 @@ Node ArithCongruenceManager::explainInternal(TNode internal){
return conjunction;
}
}
+
+void ArithCongruenceManager::eqNotifyNewClass(TNode t) {
+ if( d_eq_infer ){
+ d_eq_infer->eqNotifyNewClass(t);
+ fixpointInfer();
+ }
+}
+void ArithCongruenceManager::eqNotifyPostMerge(TNode t1, TNode t2) {
+ if( d_eq_infer ){
+ d_eq_infer->eqNotifyMerge(t1, t2);
+ fixpointInfer();
+ }
+}
+
Node ArithCongruenceManager::explain(TNode external){
+ Trace("arith-ee") << "Ask for explanation of " << external << std::endl;
Node internal = externalToInternal(external);
+ Trace("arith-ee") << "...internal = " << internal << std::endl;
return explainInternal(internal);
}
@@ -376,6 +412,7 @@ void ArithCongruenceManager::assertionToEqualityEngine(bool isEquality, ArithVar
TNode eq = d_watchedEqualities[s];
Assert(eq.getKind() == kind::EQUAL);
+ Trace("arith-ee") << "Assert " << eq << ", pol " << isEquality << ", reason " << reason << std::endl;
if(isEquality){
d_ee.assertEquality(eq, true, reason);
}else{
@@ -401,6 +438,7 @@ void ArithCongruenceManager::equalsConstant(ConstraintCP c){
Node reason = c->externalExplainByAssertions();
d_keepAlive.push_back(reason);
+ Trace("arith-ee") << "Assert equalsConstant " << eq << ", reason " << reason << std::endl;
d_ee.assertEquality(eq, true, reason);
}
@@ -424,7 +462,7 @@ void ArithCongruenceManager::equalsConstant(ConstraintCP lb, ConstraintCP ub){
d_keepAlive.push_back(eq);
d_keepAlive.push_back(reason);
-
+ Trace("arith-ee") << "Assert equalsConstant2 " << eq << ", reason " << reason << std::endl;
d_ee.assertEquality(eq, true, reason);
}
@@ -432,6 +470,55 @@ void ArithCongruenceManager::addSharedTerm(Node x){
d_ee.addTriggerTerm(x, THEORY_ARITH);
}
+bool ArithCongruenceManager::fixpointInfer() {
+ if( d_eq_infer ){
+ while(! inConflict() && d_eqi_counter.get()<d_eq_infer->getNumPendingMerges() ) {
+ Trace("snorm-infer-eq-debug") << "Processing " << d_eqi_counter.get() << " / " << d_eq_infer->getNumPendingMerges() << std::endl;
+ Node eq = d_eq_infer->getPendingMerge( d_eqi_counter.get() );
+ Trace("snorm-infer-eq") << "ArithCongruenceManager : Infer by normalization : " << eq << std::endl;
+ if( !d_ee.areEqual( eq[0], eq[1] ) ){
+ Node eq_exp = d_eq_infer->getPendingMergeExplanation( d_eqi_counter.get() );
+ Trace("snorm-infer-eq") << " explanation : " << eq_exp << std::endl;
+ //regress explanation
+ std::vector<TNode> assumptions;
+ if( eq_exp.getKind()==kind::AND ){
+ for( unsigned i=0; i<eq_exp.getNumChildren(); i++ ){
+ explain( eq_exp[i], assumptions );
+ }
+ }else if( eq_exp.getKind()==kind::EQUAL ){
+ explain( eq_exp, assumptions );
+ }else{
+ //eq_exp should be true
+ Assert( eq_exp==d_true );
+ }
+ Node req_exp;
+ if( assumptions.empty() ){
+ req_exp = d_true;
+ }else{
+ std::set<TNode> assumptionSet;
+ assumptionSet.insert(assumptions.begin(), assumptions.end());
+ if( assumptionSet.size()==1 ){
+ req_exp = assumptions[0];
+ }else{
+ NodeBuilder<> conjunction(kind::AND);
+ enqueueIntoNB(assumptionSet, conjunction);
+ req_exp = conjunction;
+ }
+ }
+ Trace("snorm-infer-eq") << " regressed explanation : " << req_exp << std::endl;
+ d_ee.assertEquality( eq, true, req_exp );
+ d_keepAlive.push_back( req_exp );
+ }else{
+ Trace("snorm-infer-eq") << "...already equal." << std::endl;
+ }
+ d_eqi_counter = d_eqi_counter.get() + 1;
+ }
+ }
+ return inConflict();
+}
+
+
+
}/* CVC4::theory::arith namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/arith/congruence_manager.h b/src/theory/arith/congruence_manager.h
index 138805b6e..a02f36a0f 100644
--- a/src/theory/arith/congruence_manager.h
+++ b/src/theory/arith/congruence_manager.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file congruence_manager.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -33,6 +33,11 @@
namespace CVC4 {
namespace theory {
+
+namespace quantifiers {
+class EqualityInference;
+}
+
namespace arith {
class ArithCongruenceManager {
@@ -69,6 +74,11 @@ private:
void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);
};
ArithCongruenceNotify d_notify;
+
+ /** module for shostak normalization, d_eqi_counter is how many pending merges in d_eq_infer we have processed */
+ quantifiers::EqualityInference * d_eq_infer;
+ context::CDO< unsigned > d_eqi_counter;
+ Node d_true;
context::CDList<Node> d_keepAlive;
@@ -127,9 +137,12 @@ private:
Node explainInternal(TNode internal);
+ void eqNotifyNewClass(TNode t);
+ void eqNotifyPostMerge(TNode t1, TNode t2);
public:
ArithCongruenceManager(context::Context* satContext, ConstraintDatabase&, SetupLiteralCallBack, const ArithVariables&, RaiseEqualityEngineConflict raiseConflict);
+ ~ArithCongruenceManager();
Node explain(TNode literal);
void explain(TNode lit, NodeBuilder<>& out);
@@ -160,6 +173,8 @@ public:
void addSharedTerm(Node x);
+ /** process inferred equalities based on Shostak normalization */
+ bool fixpointInfer();
private:
class Statistics {
public:
diff --git a/src/theory/arith/constraint.cpp b/src/theory/arith/constraint.cpp
index 5dc0ba1ac..a82ec4c95 100644
--- a/src/theory/arith/constraint.cpp
+++ b/src/theory/arith/constraint.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file constraint.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/constraint.h b/src/theory/arith/constraint.h
index 2c8fa9bcd..3ae2d0b29 100644
--- a/src/theory/arith/constraint.h
+++ b/src/theory/arith/constraint.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file constraint.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Defines Constraint and ConstraintDatabase which is the internal representation of variables in arithmetic
**
diff --git a/src/theory/arith/constraint_forward.h b/src/theory/arith/constraint_forward.h
index bfa42af46..1ebffc1b0 100644
--- a/src/theory/arith/constraint_forward.h
+++ b/src/theory/arith/constraint_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file constraint_forward.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Forward declarations of the ConstraintValue and ConstraintDatabase classes.
**
diff --git a/src/theory/arith/cut_log.cpp b/src/theory/arith/cut_log.cpp
index d94e1c760..3af2a7178 100644
--- a/src/theory/arith/cut_log.cpp
+++ b/src/theory/arith/cut_log.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cut_log.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/cut_log.h b/src/theory/arith/cut_log.h
index 82d45871f..548035aec 100644
--- a/src/theory/arith/cut_log.h
+++ b/src/theory/arith/cut_log.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cut_log.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/delta_rational.cpp b/src/theory/arith/delta_rational.cpp
index 550e4b503..207fd79a4 100644
--- a/src/theory/arith/delta_rational.cpp
+++ b/src/theory/arith/delta_rational.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file delta_rational.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/delta_rational.h b/src/theory/arith/delta_rational.h
index 39d5a9d64..afe4c0eb0 100644
--- a/src/theory/arith/delta_rational.h
+++ b/src/theory/arith/delta_rational.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file delta_rational.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/dio_solver.cpp b/src/theory/arith/dio_solver.cpp
index 71ad6de45..f34bbc67a 100644
--- a/src/theory/arith/dio_solver.cpp
+++ b/src/theory/arith/dio_solver.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file dio_solver.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Diophantine equation solver
**
diff --git a/src/theory/arith/dio_solver.h b/src/theory/arith/dio_solver.h
index ccaff47c7..6c53d6ad0 100644
--- a/src/theory/arith/dio_solver.h
+++ b/src/theory/arith/dio_solver.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file dio_solver.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Diophantine equation solver
**
diff --git a/src/theory/arith/dual_simplex.cpp b/src/theory/arith/dual_simplex.cpp
index 907d5eefb..72d7a8602 100644
--- a/src/theory/arith/dual_simplex.cpp
+++ b/src/theory/arith/dual_simplex.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file dual_simplex.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/dual_simplex.h b/src/theory/arith/dual_simplex.h
index e5ab76da8..25461972c 100644
--- a/src/theory/arith/dual_simplex.h
+++ b/src/theory/arith/dual_simplex.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file dual_simplex.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
** decision procedure.
diff --git a/src/theory/arith/error_set.cpp b/src/theory/arith/error_set.cpp
index e918f4c7d..7c8efc4e8 100644
--- a/src/theory/arith/error_set.cpp
+++ b/src/theory/arith/error_set.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file error_set.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/error_set.h b/src/theory/arith/error_set.h
index fb3117a98..4b88e3f50 100644
--- a/src/theory/arith/error_set.h
+++ b/src/theory/arith/error_set.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file error_set.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/fc_simplex.cpp b/src/theory/arith/fc_simplex.cpp
index 888e29732..ef5ff93c7 100644
--- a/src/theory/arith/fc_simplex.cpp
+++ b/src/theory/arith/fc_simplex.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file fc_simplex.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/fc_simplex.h b/src/theory/arith/fc_simplex.h
index c416af1c6..ca1e666fc 100644
--- a/src/theory/arith/fc_simplex.h
+++ b/src/theory/arith/fc_simplex.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file fc_simplex.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
** decision procedure.
diff --git a/src/theory/arith/infer_bounds.cpp b/src/theory/arith/infer_bounds.cpp
index 05a520d35..96b2a6189 100644
--- a/src/theory/arith/infer_bounds.cpp
+++ b/src/theory/arith/infer_bounds.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file infer_bounds.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/infer_bounds.h b/src/theory/arith/infer_bounds.h
index 770d9d1b3..f65952f7c 100644
--- a/src/theory/arith/infer_bounds.h
+++ b/src/theory/arith/infer_bounds.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file infer_bounds.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/linear_equality.cpp b/src/theory/arith/linear_equality.cpp
index 6d86a1ab1..7e1d84ebb 100644
--- a/src/theory/arith/linear_equality.cpp
+++ b/src/theory/arith/linear_equality.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file linear_equality.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This implements the LinearEqualityModule.
**
diff --git a/src/theory/arith/linear_equality.h b/src/theory/arith/linear_equality.h
index f3cf17d81..aa6b10c5e 100644
--- a/src/theory/arith/linear_equality.h
+++ b/src/theory/arith/linear_equality.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file linear_equality.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Clark Barrett, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This module maintains the relationship between a Tableau and PartialModel.
**
diff --git a/src/theory/arith/matrix.cpp b/src/theory/arith/matrix.cpp
index 9ace1d3d1..25ed96b0c 100644
--- a/src/theory/arith/matrix.cpp
+++ b/src/theory/arith/matrix.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file matrix.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/matrix.h b/src/theory/arith/matrix.h
index 647df886f..f0d4ec42c 100644
--- a/src/theory/arith/matrix.h
+++ b/src/theory/arith/matrix.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file matrix.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sparse matrix implementations for different types.
**
diff --git a/src/theory/arith/normal_form.cpp b/src/theory/arith/normal_form.cpp
index e22a5e2e3..d7c580395 100644
--- a/src/theory/arith/normal_form.cpp
+++ b/src/theory/arith/normal_form.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file normal_form.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/normal_form.h b/src/theory/arith/normal_form.h
index eeb56f597..d57d781f1 100644
--- a/src/theory/arith/normal_form.h
+++ b/src/theory/arith/normal_form.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file normal_form.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/partial_model.cpp b/src/theory/arith/partial_model.cpp
index 0124ee0f9..632be2a81 100644
--- a/src/theory/arith/partial_model.cpp
+++ b/src/theory/arith/partial_model.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file partial_model.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/partial_model.h b/src/theory/arith/partial_model.h
index 1e6f2f5ab..b5eafb2c4 100644
--- a/src/theory/arith/partial_model.h
+++ b/src/theory/arith/partial_model.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file partial_model.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Datastructures that track variable by variable information.
**
diff --git a/src/theory/arith/pseudoboolean_proc.cpp b/src/theory/arith/pseudoboolean_proc.cpp
index c09b0180a..0c1496a89 100644
--- a/src/theory/arith/pseudoboolean_proc.cpp
+++ b/src/theory/arith/pseudoboolean_proc.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file pseudoboolean_proc.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/pseudoboolean_proc.h b/src/theory/arith/pseudoboolean_proc.h
index d1e10f695..23065ca48 100644
--- a/src/theory/arith/pseudoboolean_proc.h
+++ b/src/theory/arith/pseudoboolean_proc.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file pseudoboolean_proc.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/simplex.cpp b/src/theory/arith/simplex.cpp
index 24c6ce432..a1ffe90b5 100644
--- a/src/theory/arith/simplex.cpp
+++ b/src/theory/arith/simplex.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file simplex.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/simplex.h b/src/theory/arith/simplex.h
index 1cd617b64..b4cd54a78 100644
--- a/src/theory/arith/simplex.h
+++ b/src/theory/arith/simplex.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file simplex.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
** decision procedure.
diff --git a/src/theory/arith/simplex_update.cpp b/src/theory/arith/simplex_update.cpp
index 14bdc9a69..adf0dc039 100644
--- a/src/theory/arith/simplex_update.cpp
+++ b/src/theory/arith/simplex_update.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file simplex_update.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This implements UpdateInfo.
**
diff --git a/src/theory/arith/simplex_update.h b/src/theory/arith/simplex_update.h
index 1a5c42188..2c02e3f77 100644
--- a/src/theory/arith/simplex_update.h
+++ b/src/theory/arith/simplex_update.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file simplex_update.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This provides a class for summarizing pivot proposals.
**
diff --git a/src/theory/arith/soi_simplex.cpp b/src/theory/arith/soi_simplex.cpp
index df32ec8a4..0a437cde0 100644
--- a/src/theory/arith/soi_simplex.cpp
+++ b/src/theory/arith/soi_simplex.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file soi_simplex.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/soi_simplex.h b/src/theory/arith/soi_simplex.h
index 73a2330a3..c2afe062a 100644
--- a/src/theory/arith/soi_simplex.h
+++ b/src/theory/arith/soi_simplex.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file soi_simplex.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
** decision procedure.
diff --git a/src/theory/arith/tableau.cpp b/src/theory/arith/tableau.cpp
index 744dda6b7..0bd130985 100644
--- a/src/theory/arith/tableau.cpp
+++ b/src/theory/arith/tableau.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file tableau.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/tableau.h b/src/theory/arith/tableau.h
index 77187c798..c4c8cfba3 100644
--- a/src/theory/arith/tableau.h
+++ b/src/theory/arith/tableau.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file tableau.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/tableau_sizes.cpp b/src/theory/arith/tableau_sizes.cpp
index 64bae22fe..08f7a69d8 100644
--- a/src/theory/arith/tableau_sizes.cpp
+++ b/src/theory/arith/tableau_sizes.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file tableau_sizes.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/tableau_sizes.h b/src/theory/arith/tableau_sizes.h
index fd62e71a2..635330798 100644
--- a/src/theory/arith/tableau_sizes.h
+++ b/src/theory/arith/tableau_sizes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file tableau_sizes.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp
index 3c7a767c6..9627b9a1a 100644
--- a/src/theory/arith/theory_arith.cpp
+++ b/src/theory/arith/theory_arith.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arith.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds, Martin Brain <>, Tianyi Liang, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/theory_arith.h b/src/theory/arith/theory_arith.h
index b69d51966..3e414ca6d 100644
--- a/src/theory/arith/theory_arith.h
+++ b/src/theory/arith/theory_arith.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arith.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Tim King
- ** Minor contributors (to current version): Martin Brain <>, Tianyi Liang, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Arithmetic theory.
** Arithmetic theory.
diff --git a/src/theory/arith/theory_arith_private.cpp b/src/theory/arith/theory_arith_private.cpp
index e6b14d2b1..e47231128 100644
--- a/src/theory/arith/theory_arith_private.cpp
+++ b/src/theory/arith/theory_arith_private.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arith_private.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds, Tianyi Liang, Kshitij Bansal, Martin Brain <>, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Martin Brain
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/theory_arith_private.h b/src/theory/arith/theory_arith_private.h
index 1009dceb8..edc3a5bc0 100644
--- a/src/theory/arith/theory_arith_private.h
+++ b/src/theory/arith/theory_arith_private.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arith_private.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds, Tianyi Liang, Morgan Deters, Martin Brain <>
+ ** Top contributors (to current version):
+ ** Tim King, Martin Brain, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/theory_arith_private_forward.h b/src/theory/arith/theory_arith_private_forward.h
index 10b954c7d..ffab816f1 100644
--- a/src/theory/arith/theory_arith_private_forward.h
+++ b/src/theory/arith/theory_arith_private_forward.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arith_private_forward.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arith/theory_arith_type_rules.h b/src/theory/arith/theory_arith_type_rules.h
index d1cd435a2..071ec9391 100644
--- a/src/theory/arith/theory_arith_type_rules.h
+++ b/src/theory/arith/theory_arith_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arith_type_rules.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Christopher L. Conway, Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add brief comments here ]]
**
diff --git a/src/theory/arith/type_enumerator.h b/src/theory/arith/type_enumerator.h
index dc2b6f115..36b7b543a 100644
--- a/src/theory/arith/type_enumerator.h
+++ b/src/theory/arith/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Enumerators for rationals and integers
**
diff --git a/src/theory/arrays/array_info.cpp b/src/theory/arrays/array_info.cpp
index 55f013f8c..c63d528a7 100644
--- a/src/theory/arrays/array_info.cpp
+++ b/src/theory/arrays/array_info.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file array_info.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Contains additional classes to store context dependent information
** for each term of type array
@@ -44,16 +44,16 @@ Info::~Info() {
in_stores->deleteSelf();
}
-ArrayInfo::ArrayInfo(context::Context* c, Backtracker<TNode>* b)
+ArrayInfo::ArrayInfo(context::Context* c, Backtracker<TNode>* b, std::string statisticsPrefix)
: ct(c), bck(b), info_map(),
- d_mergeInfoTimer("theory::arrays::mergeInfoTimer"),
- d_avgIndexListLength("theory::arrays::avgIndexListLength"),
- d_avgStoresListLength("theory::arrays::avgStoresListLength"),
- d_avgInStoresListLength("theory::arrays::avgInStoresListLength"),
- d_listsCount("theory::arrays::listsCount",0),
- d_callsMergeInfo("theory::arrays::callsMergeInfo",0),
- d_maxList("theory::arrays::maxList",0),
- d_tableSize("theory::arrays::infoTableSize", info_map) {
+ d_mergeInfoTimer(statisticsPrefix + "theory::arrays::mergeInfoTimer"),
+ d_avgIndexListLength(statisticsPrefix + "theory::arrays::avgIndexListLength"),
+ d_avgStoresListLength(statisticsPrefix + "theory::arrays::avgStoresListLength"),
+ d_avgInStoresListLength(statisticsPrefix + "theory::arrays::avgInStoresListLength"),
+ d_listsCount(statisticsPrefix + "theory::arrays::listsCount",0),
+ d_callsMergeInfo(statisticsPrefix + "theory::arrays::callsMergeInfo",0),
+ d_maxList(statisticsPrefix + "theory::arrays::maxList",0),
+ d_tableSize(statisticsPrefix + "theory::arrays::infoTableSize", info_map) {
emptyList = new(true) CTNodeList(ct);
emptyInfo = new Info(ct, bck);
smtStatisticsRegistry()->registerStat(&d_mergeInfoTimer);
@@ -208,7 +208,7 @@ void ArrayInfo::setNonLinear(const TNode a) {
} else {
(*it).second->isNonLinear = true;
}
-
+
}
void ArrayInfo::setRIntro1Applied(const TNode a) {
@@ -222,7 +222,7 @@ void ArrayInfo::setRIntro1Applied(const TNode a) {
} else {
(*it).second->rIntro1Applied = true;
}
-
+
}
void ArrayInfo::setModelRep(const TNode a, const TNode b) {
@@ -236,7 +236,7 @@ void ArrayInfo::setModelRep(const TNode a, const TNode b) {
} else {
(*it).second->modelRep = b;
}
-
+
}
void ArrayInfo::setConstArr(const TNode a, const TNode constArr) {
diff --git a/src/theory/arrays/array_info.h b/src/theory/arrays/array_info.h
index 319864c34..11455a97d 100644
--- a/src/theory/arrays/array_info.h
+++ b/src/theory/arrays/array_info.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file array_info.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Contains additional classes to store context dependent information
** for each term of type array
@@ -155,7 +155,8 @@ public:
currentStatisticsRegistry()->registerStat(&d_maxList);
currentStatisticsRegistry()->registerStat(&d_tableSize);
}*/
- ArrayInfo(context::Context* c, Backtracker<TNode>* b);
+
+ ArrayInfo(context::Context* c, Backtracker<TNode>* b, std::string statisticsPrefix = "");
~ArrayInfo();
diff --git a/src/theory/arrays/array_proof_reconstruction.cpp b/src/theory/arrays/array_proof_reconstruction.cpp
new file mode 100644
index 000000000..11c3dc081
--- /dev/null
+++ b/src/theory/arrays/array_proof_reconstruction.cpp
@@ -0,0 +1,134 @@
+/********************* */
+/*! \file array_proof_reconstruction.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
+**/
+
+#include "theory/arrays/array_proof_reconstruction.h"
+
+namespace CVC4 {
+namespace theory {
+namespace arrays {
+
+ArrayProofReconstruction::ArrayProofReconstruction(const eq::EqualityEngine* equalityEngine)
+ : d_equalityEngine(equalityEngine) {
+}
+
+void ArrayProofReconstruction::setRowMergeTag(unsigned tag) {
+ d_reasonRow = tag;
+}
+
+void ArrayProofReconstruction::setRow1MergeTag(unsigned tag) {
+ d_reasonRow1 = tag;
+}
+
+void ArrayProofReconstruction::setExtMergeTag(unsigned tag) {
+ d_reasonExt = tag;
+}
+
+void ArrayProofReconstruction::notify(unsigned reasonType, Node reason, Node a, Node b,
+ std::vector<TNode>& equalities, eq::EqProof* proof) const {
+
+ Debug("pf::array") << "ArrayProofReconstruction::notify( "
+ << reason << ", " << a << ", " << b << std::endl;
+
+
+ if (reasonType == d_reasonExt) {
+ if (proof) {
+ // Todo: here we assume that a=b is an assertion. We should probably call explain()
+ // recursively, to explain this.
+ eq::EqProof* childProof = new eq::EqProof;
+ childProof->d_node = reason;
+ proof->d_children.push_back(childProof);
+ }
+ }
+
+ else if (reasonType == d_reasonRow) {
+ // ROW rules mean that (i==k) OR ((a[i]:=t)[k] == a[k])
+ // The equality here will be either (i == k) because ((a[i]:=t)[k] != a[k]),
+ // or ((a[i]:=t)[k] == a[k]) because (i != k).
+
+ if (proof) {
+ if (a.getNumChildren() == 2) {
+ // This is the case of ((a[i]:=t)[k] == a[k]) because (i != k).
+
+ // The edge is ((a[i]:=t)[k], a[k]), or (a[k], (a[i]:=t)[k]). This flag should be
+ // false in the first case and true in the second case.
+ bool currentNodeIsUnchangedArray;
+
+ Assert(a.getNumChildren() == 2);
+ Assert(b.getNumChildren() == 2);
+
+ if (a[0].getKind() == kind::VARIABLE || a[0].getKind() == kind::SKOLEM) {
+ currentNodeIsUnchangedArray = true;
+ } else if (b[0].getKind() == kind::VARIABLE || b[0].getKind() == kind::SKOLEM) {
+ currentNodeIsUnchangedArray = false;
+ } else {
+ Assert(a[0].getKind() == kind::STORE);
+ Assert(b[0].getKind() == kind::STORE);
+
+ if (a[0][0] == b[0]) {
+ currentNodeIsUnchangedArray = false;
+ } else if (b[0][0] == a[0]) {
+ currentNodeIsUnchangedArray = true;
+ } else {
+ Unreachable();
+ }
+ }
+
+ Node indexOne = currentNodeIsUnchangedArray ? a[1] : a[0][1];
+ Node indexTwo = currentNodeIsUnchangedArray ? b[0][1] : b[1];
+
+ // Some assertions to ensure that the theory of arrays behaves as expected
+ Assert(a[1] == b[1]);
+ if (currentNodeIsUnchangedArray) {
+ Assert(a[0] == b[0][0]);
+ } else {
+ Assert(a[0][0] == b[0]);
+ }
+
+ Debug("pf::ee") << "Getting explanation for ROW guard: "
+ << indexOne << " != " << indexTwo << std::endl;
+
+ eq::EqProof* childProof = new eq::EqProof;
+ d_equalityEngine->explainEquality(indexOne, indexTwo, false, equalities, childProof);
+ proof->d_children.push_back(childProof);
+ } else {
+ // This is the case of (i == k) because ((a[i]:=t)[k] != a[k]),
+
+ Node indexOne = a;
+ Node indexTwo = b;
+
+ Debug("pf::ee") << "The two indices are: " << indexOne << ", " << indexTwo << std::endl
+ << "The reason for the edge is: " << reason << std::endl;
+
+ Assert(reason.getNumChildren() == 2);
+ Debug("pf::ee") << "Getting explanation for ROW guard: " << reason[1] << std::endl;
+
+ eq::EqProof* childProof = new eq::EqProof;
+ d_equalityEngine->explainEquality(reason[1][0], reason[1][1], false, equalities, childProof);
+ proof->d_children.push_back(childProof);
+ }
+ }
+
+ }
+
+ else if (reasonType == d_reasonRow1) {
+ // No special handling required at this time
+ }
+}
+
+}/* CVC4::theory::arrays namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
diff --git a/src/theory/arrays/array_proof_reconstruction.h b/src/theory/arrays/array_proof_reconstruction.h
new file mode 100644
index 000000000..ef3e09aed
--- /dev/null
+++ b/src/theory/arrays/array_proof_reconstruction.h
@@ -0,0 +1,58 @@
+/********************* */
+/*! \file array_proof_reconstruction.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Guy Katz
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Array-specific proof construction logic to be used during the
+ ** equality engine's path reconstruction
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__ARRAYS__ARRAY_PROOF_RECONSTRUCTION_H
+#define __CVC4__THEORY__ARRAYS__ARRAY_PROOF_RECONSTRUCTION_H
+
+#include "theory/uf/equality_engine.h"
+
+namespace CVC4 {
+namespace theory {
+namespace arrays {
+
+/**
+ * A callback class to be invoked whenever the equality engine traverses
+ * an "array-owned" edge during path reconstruction.
+ */
+
+class ArrayProofReconstruction : public eq::PathReconstructionNotify {
+public:
+ ArrayProofReconstruction(const eq::EqualityEngine* equalityEngine);
+
+ void notify(unsigned reasonType, Node reason, Node a, Node b,
+ std::vector<TNode>& equalities, eq::EqProof* proof) const;
+
+ void setRowMergeTag(unsigned tag);
+ void setRow1MergeTag(unsigned tag);
+ void setExtMergeTag(unsigned tag);
+
+private:
+ /** Merge tag for ROW applications */
+ unsigned d_reasonRow;
+ /** Merge tag for ROW1 applications */
+ unsigned d_reasonRow1;
+ /** Merge tag for EXT applications */
+ unsigned d_reasonExt;
+
+ const eq::EqualityEngine* d_equalityEngine;
+}; /* class ArrayProofReconstruction */
+
+}/* CVC4::theory::arrays namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__ARRAYS__ARRAY_PROOF_RECONSTRUCTION_H */
diff --git a/src/theory/arrays/kinds b/src/theory/arrays/kinds
index d5f313ca1..be16d684d 100644
--- a/src/theory/arrays/kinds
+++ b/src/theory/arrays/kinds
@@ -54,6 +54,11 @@ typerule STORE_ALL ::CVC4::theory::arrays::ArrayStoreTypeRule
typerule ARR_TABLE_FUN ::CVC4::theory::arrays::ArrayTableFunTypeRule
typerule ARRAY_LAMBDA ::CVC4::theory::arrays::ArrayLambdaTypeRule
+operator PARTIAL_SELECT_0 0:2 "partial array select, for internal use only"
+operator PARTIAL_SELECT_1 0:2 "partial array select, for internal use only"
+typerule PARTIAL_SELECT_0 ::CVC4::theory::arrays::ArrayPartialSelectTypeRule
+typerule PARTIAL_SELECT_1 ::CVC4::theory::arrays::ArrayPartialSelectTypeRule
+
# store operations that are ordered (by index) over a store-all are constant
construle STORE ::CVC4::theory::arrays::ArrayStoreTypeRule
diff --git a/src/theory/arrays/static_fact_manager.cpp b/src/theory/arrays/static_fact_manager.cpp
index 0d04ce097..da1d7bba9 100644
--- a/src/theory/arrays/static_fact_manager.cpp
+++ b/src/theory/arrays/static_fact_manager.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file static_fact_manager.cpp
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Path-compressing, backtrackable union-find using an undo
** stack. Refactored from the UF union-find.
diff --git a/src/theory/arrays/static_fact_manager.h b/src/theory/arrays/static_fact_manager.h
index 220bd0437..d40f56e61 100644
--- a/src/theory/arrays/static_fact_manager.h
+++ b/src/theory/arrays/static_fact_manager.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file static_fact_manager.h
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Clark Barrett, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Path-compressing, backtrackable union-find using an undo
** stack. Refactored from the UF union-find.
diff --git a/src/theory/arrays/theory_arrays.cpp b/src/theory/arrays/theory_arrays.cpp
index 8f1ba5fca..6add1b55f 100644
--- a/src/theory/arrays/theory_arrays.cpp
+++ b/src/theory/arrays/theory_arrays.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arrays.cpp
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King, Kshitij Bansal, Andrew Reynolds, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Clark Barrett, Morgan Deters, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the theory of arrays.
**
@@ -21,13 +21,14 @@
#include "expr/kind.h"
#include "options/arrays_options.h"
#include "options/smt_options.h"
+#include "proof/array_proof.h"
+#include "proof/proof_manager.h"
+#include "proof/theory_proof.h"
#include "smt/command.h"
#include "smt/logic_exception.h"
#include "smt/smt_statistics_registry.h"
#include "theory/rewriter.h"
#include "theory/theory_model.h"
-#include "proof/theory_proof.h"
-#include "proof/proof_manager.h"
#include "theory/valuation.h"
using namespace std;
@@ -78,7 +79,7 @@ TheoryArrays::TheoryArrays(context::Context* c, context::UserContext* u,
d_equalityEngine(d_notify, c, name + "theory::arrays::TheoryArrays", true),
d_conflict(c, false),
d_backtracker(c),
- d_infoMap(c, &d_backtracker),
+ d_infoMap(c, &d_backtracker, name),
d_mergeQueue(c),
d_mergeInProgress(false),
d_RowQueue(c),
@@ -98,7 +99,8 @@ TheoryArrays::TheoryArrays(context::Context* c, context::UserContext* u,
d_defValues(c),
d_readTableContext(new context::Context()),
d_arrayMerges(c),
- d_inCheckModel(false)
+ d_inCheckModel(false),
+ d_proofReconstruction(&d_equalityEngine)
{
smtStatisticsRegistry()->registerStat(&d_numRow);
smtStatisticsRegistry()->registerStat(&d_numExt);
@@ -126,6 +128,18 @@ TheoryArrays::TheoryArrays(context::Context* c, context::UserContext* u,
if (d_useArrTable) {
d_equalityEngine.addFunctionKind(kind::ARR_TABLE_FUN);
}
+
+ d_reasonRow = d_equalityEngine.getFreshMergeReasonType();
+ d_reasonRow1 = d_equalityEngine.getFreshMergeReasonType();
+ d_reasonExt = d_equalityEngine.getFreshMergeReasonType();
+
+ d_proofReconstruction.setRowMergeTag(d_reasonRow);
+ d_proofReconstruction.setRow1MergeTag(d_reasonRow1);
+ d_proofReconstruction.setExtMergeTag(d_reasonExt);
+
+ d_equalityEngine.addPathReconstructionTrigger(d_reasonRow, &d_proofReconstruction);
+ d_equalityEngine.addPathReconstructionTrigger(d_reasonRow1, &d_proofReconstruction);
+ d_equalityEngine.addPathReconstructionTrigger(d_reasonExt, &d_proofReconstruction);
}
TheoryArrays::~TheoryArrays() {
@@ -383,21 +397,27 @@ bool TheoryArrays::propagate(TNode literal)
}/* TheoryArrays::propagate(TNode) */
-void TheoryArrays::explain(TNode literal, std::vector<TNode>& assumptions) {
+void TheoryArrays::explain(TNode literal, std::vector<TNode>& assumptions, eq::EqProof *proof) {
// Do the work
bool polarity = literal.getKind() != kind::NOT;
TNode atom = polarity ? literal : literal[0];
//eq::EqProof * eqp = new eq::EqProof;
- eq::EqProof * eqp = NULL;
+ // eq::EqProof * eqp = NULL;
if (atom.getKind() == kind::EQUAL || atom.getKind() == kind::IFF) {
- d_equalityEngine.explainEquality(atom[0], atom[1], polarity, assumptions, eqp);
+ d_equalityEngine.explainEquality(atom[0], atom[1], polarity, assumptions, proof);
} else {
- d_equalityEngine.explainPredicate(atom, polarity, assumptions);
+ d_equalityEngine.explainPredicate(atom, polarity, assumptions, proof);
+ }
+ if(proof){
+ Debug("pf::array") << " Proof is : " << std::endl;
+ proof->debug_print("pf::array");
}
- if( eqp ){
- Debug("array-pf") << " Proof is : " << std::endl;
- eqp->debug_print("array-pf");
+
+ Debug("pf::array") << "Array: explain( " << literal << " ):" << std::endl << "\t";
+ for (unsigned i = 0; i < assumptions.size(); ++i) {
+ Debug("pf::array") << assumptions[i] << " ";
}
+ Debug("pf::array") << std::endl;
}
TNode TheoryArrays::weakEquivGetRep(TNode node) {
@@ -597,7 +617,7 @@ void TheoryArrays::checkWeakEquiv(bool arraysMerged) {
}
}
}
- }
+ }
}
/**
@@ -653,7 +673,7 @@ void TheoryArrays::preRegisterTermInternal(TNode node)
if (ni != node) {
preRegisterTermInternal(ni);
}
- d_equalityEngine.assertEquality(ni.eqNode(s[2]), true, d_true, eq::MERGED_ARRAYS_ROW1);
+ d_equalityEngine.assertEquality(ni.eqNode(s[2]), true, d_true, d_reasonRow1);
Assert(++it == stores->end());
}
}
@@ -739,7 +759,7 @@ void TheoryArrays::preRegisterTermInternal(TNode node)
}
// Apply RIntro1 Rule
- d_equalityEngine.assertEquality(ni.eqNode(v), true, d_true, eq::MERGED_ARRAYS_ROW1);
+ d_equalityEngine.assertEquality(ni.eqNode(v), true, d_true, d_reasonRow1);
}
d_infoMap.addStore(node, node);
@@ -787,6 +807,7 @@ void TheoryArrays::preRegisterTermInternal(TNode node)
else {
d_equalityEngine.addTerm(node);
}
+
break;
}
// Invariant: preregistered terms are exactly the terms in the equality engine
@@ -807,12 +828,16 @@ void TheoryArrays::propagate(Effort e)
}
-Node TheoryArrays::explain(TNode literal)
+Node TheoryArrays::explain(TNode literal) {
+ return explain(literal, NULL);
+}
+
+Node TheoryArrays::explain(TNode literal, eq::EqProof *proof)
{
++d_numExplain;
Debug("arrays") << spaces(getSatContext()->getLevel()) << "TheoryArrays::explain(" << literal << ")" << std::endl;
std::vector<TNode> assumptions;
- explain(literal, assumptions);
+ explain(literal, assumptions, proof);
return mkAnd(assumptions);
}
@@ -1133,7 +1158,7 @@ void TheoryArrays::collectModelInfo( TheoryModel* m, bool fullModel )
TypeSet defaultValuesSet;
// Compute all default values already in use
- if (fullModel) {
+ //if (fullModel) {
for (size_t i=0; i<arrays.size(); ++i) {
TNode nrep = d_equalityEngine.getRepresentative(arrays[i]);
d_mayEqualEqualityEngine.addTerm(nrep); // add the term in case it isn't there already
@@ -1143,14 +1168,14 @@ void TheoryArrays::collectModelInfo( TheoryModel* m, bool fullModel )
defaultValuesSet.add(nrep.getType().getArrayConstituentType(), (*it).second);
}
}
- }
+ //}
// Loop through all array equivalence classes that need a representative computed
for (size_t i=0; i<arrays.size(); ++i) {
TNode n = arrays[i];
TNode nrep = d_equalityEngine.getRepresentative(n);
- if (fullModel) {
+ //if (fullModel) {
// Compute default value for this array - there is one default value for every mayEqual equivalence class
TNode mayRep = d_mayEqualEqualityEngine.getRepresentative(nrep);
it = d_defValues.find(mayRep);
@@ -1171,6 +1196,7 @@ void TheoryArrays::collectModelInfo( TheoryModel* m, bool fullModel )
// Build the STORE_ALL term with the default value
rep = nm->mkConst(ArrayStoreAll(nrep.getType().toType(), rep.toExpr()));
+ /*
}
else {
std::hash_map<Node, Node, NodeHashFunction>::iterator it = d_skolemCache.find(n);
@@ -1182,6 +1208,7 @@ void TheoryArrays::collectModelInfo( TheoryModel* m, bool fullModel )
rep = (*it).second;
}
}
+*/
// For each read, require that the rep stores the right value
vector<Node>& reads = selects[nrep];
@@ -1228,7 +1255,11 @@ Node TheoryArrays::getSkolem(TNode ref, const string& name, const TypeNode& type
makeEqual = false;
}
}
+
+ Debug("pf::array") << "Pregistering a Skolem" << std::endl;
preRegisterTermInternal(skolem);
+ Debug("pf::array") << "Pregistering a Skolem DONE" << std::endl;
+
if (makeEqual) {
Node d = skolem.eqNode(ref);
Debug("arrays-model-based") << "Asserting skolem equality " << d << endl;
@@ -1237,6 +1268,8 @@ Node TheoryArrays::getSkolem(TNode ref, const string& name, const TypeNode& type
d_skolemAssertions.push_back(d);
d_skolemIndex = d_skolemIndex + 1;
}
+
+ Debug("pf::array") << "getSkolem DONE" << std::endl;
return skolem;
}
@@ -1291,28 +1324,76 @@ void TheoryArrays::check(Effort e) {
// Apply ArrDiseq Rule if diseq is between arrays
if(fact[0][0].getType().isArray() && !d_conflict) {
+ if (d_conflict) { Debug("pf::array") << "Entering the skolemization branch" << std::endl; }
+
NodeManager* nm = NodeManager::currentNM();
TypeNode indexType = fact[0][0].getType()[0];
- TNode k = getSkolem(fact,"array_ext_index", indexType, "an extensional lemma index variable from the theory of arrays", false);
+
+ TNode k;
+ // k is the skolem for this disequality.
+ if (!d_proofsEnabled) {
+ Debug("pf::array") << "Check: kind::NOT: array theory making a skolem" << std::endl;
+
+ // If not in replay mode, generate a fresh skolem variable
+ k = getSkolem(fact,
+ "array_ext_index",
+ indexType,
+ "an extensional lemma index variable from the theory of arrays",
+ false);
+
+ // Register this skolem for the proof replay phase
+ PROOF(ProofManager::getSkolemizationManager()->registerSkolem(fact, k));
+ } else {
+ if (!ProofManager::getSkolemizationManager()->hasSkolem(fact)) {
+ // In the solution pass we didn't need this skolem. Therefore, we don't need it
+ // in this reply pass, either.
+ break;
+ }
+
+ // Reuse the same skolem as in the solution pass
+ k = ProofManager::getSkolemizationManager()->getSkolem(fact);
+ Debug("pf::array") << "Skolem = " << k << std::endl;
+ }
Node ak = nm->mkNode(kind::SELECT, fact[0][0], k);
Node bk = nm->mkNode(kind::SELECT, fact[0][1], k);
Node eq = ak.eqNode(bk);
Node lemma = fact[0].orNode(eq.notNode());
+
+ // In solve mode we don't care if ak and bk are registered. If they aren't, they'll be registered
+ // when we output the lemma. However, in replay need the lemma to be propagated, and so we
+ // preregister manually.
+ if (d_proofsEnabled) {
+ if (!d_equalityEngine.hasTerm(ak)) { preRegisterTermInternal(ak); }
+ if (!d_equalityEngine.hasTerm(bk)) { preRegisterTermInternal(bk); }
+ }
+
if (options::arraysPropagate() > 0 && d_equalityEngine.hasTerm(ak) && d_equalityEngine.hasTerm(bk)) {
// Propagate witness disequality - might produce a conflict
d_permRef.push_back(lemma);
- d_equalityEngine.assertEquality(eq, false, lemma, eq::MERGED_ARRAYS_EXT);
+ Debug("pf::array") << "Asserting to the equality engine:" << std::endl
+ << "\teq = " << eq << std::endl
+ << "\treason = " << fact << std::endl;
+
+ d_equalityEngine.assertEquality(eq, false, fact, d_reasonExt);
++d_numProp;
}
- Trace("arrays-lem")<<"Arrays::addExtLemma " << lemma <<"\n";
- d_out->lemma(lemma);
- ++d_numExt;
+
+ if (!d_proofsEnabled) {
+ // If this is the solution pass, generate the lemma. Otherwise, don't generate it -
+ // as this is the lemma that we're reproving...
+ Trace("arrays-lem")<<"Arrays::addExtLemma " << lemma <<"\n";
+ d_out->lemma(lemma);
+ ++d_numExt;
+ }
+ } else {
+ Debug("pf::array") << "Check: kind::NOT: array theory NOT making a skolem" << std::endl;
+ d_modelConstraints.push_back(fact);
}
}
break;
- default:
- Unreachable();
+ default:
+ Unreachable();
}
}
@@ -1387,8 +1468,10 @@ void TheoryArrays::check(Effort e) {
weakEquivBuildCond(r2[0], r[1], conjunctions);
lemma = mkAnd(conjunctions, true);
// LSH FIXME: which kind of arrays lemma is this
+ Trace("arrays-lem") << "Arrays::addExtLemma " << lemma <<"\n";
d_out->lemma(lemma, RULE_INVALID, false, false, true);
d_readTableContext->pop();
+ Trace("arrays") << spaces(getSatContext()->getLevel()) << "Arrays::check(): done" << endl;
return;
}
}
@@ -1399,7 +1482,7 @@ void TheoryArrays::check(Effort e) {
if(!options::arraysEagerLemmas() && fullEffort(e) && !d_conflict && !options::arraysWeakEquivalence()) {
// generate the lemmas on the worklist
- Trace("arrays-lem")<<"Arrays::discharging lemmas: "<<d_RowQueue.size()<<"\n";
+ Trace("arrays-lem")<< "Arrays::discharging lemmas. Number of queued lemmas: " << d_RowQueue.size() << "\n";
while (d_RowQueue.size() > 0 && !d_conflict) {
if (dischargeLemmas()) {
break;
@@ -1594,7 +1677,7 @@ void TheoryArrays::checkRIntro1(TNode a, TNode b)
d_infoMap.setRIntro1Applied(s);
Node ni = nm->mkNode(kind::SELECT, s, s[1]);
preRegisterTermInternal(ni);
- d_equalityEngine.assertEquality(ni.eqNode(s[2]), true, d_true, eq::MERGED_ARRAYS_ROW1);
+ d_equalityEngine.assertEquality(ni.eqNode(s[2]), true, d_true, d_reasonRow1);
}
}
@@ -1863,6 +1946,9 @@ void TheoryArrays::checkRowLemmas(TNode a, TNode b)
void TheoryArrays::propagate(RowLemmaType lem)
{
+ Debug("pf::array") << "TheoryArrays: RowLemma Propagate called. options::arraysPropagate() = "
+ << options::arraysPropagate() << std::endl;
+
TNode a = lem.first;
TNode b = lem.second;
TNode i = lem.third;
@@ -1898,7 +1984,7 @@ void TheoryArrays::propagate(RowLemmaType lem)
if (!bjExists) {
preRegisterTermInternal(bj);
}
- d_equalityEngine.assertEquality(aj_eq_bj, true, reason, eq::MERGED_ARRAYS_ROW);
+ d_equalityEngine.assertEquality(aj_eq_bj, true, reason, d_reasonRow);
++d_numProp;
return;
}
@@ -1908,7 +1994,7 @@ void TheoryArrays::propagate(RowLemmaType lem)
Node i_eq_j = i.eqNode(j);
Node reason = nm->mkNode(kind::OR, i_eq_j, aj_eq_bj);
d_permRef.push_back(reason);
- d_equalityEngine.assertEquality(i_eq_j, true, reason, eq::MERGED_ARRAYS_ROW);
+ d_equalityEngine.assertEquality(i_eq_j, true, reason, d_reasonRow);
++d_numProp;
return;
}
@@ -1917,6 +2003,8 @@ void TheoryArrays::propagate(RowLemmaType lem)
void TheoryArrays::queueRowLemma(RowLemmaType lem)
{
+ Debug("pf::array") << "Array solver: queue row lemma called" << std::endl;
+
if (d_conflict || d_RowAlreadyAdded.contains(lem)) {
return;
}
@@ -1956,15 +2044,20 @@ void TheoryArrays::queueRowLemma(RowLemmaType lem)
// Prefer equality between indexes so as not to introduce new read terms
if (options::arraysEagerIndexSplitting() && !bothExist && !d_equalityEngine.areDisequal(i,j, false)) {
- Node i_eq_j = d_valuation.ensureLiteral(i.eqNode(j));
+ Node i_eq_j;
+ if (!d_proofsEnabled) {
+ i_eq_j = d_valuation.ensureLiteral(i.eqNode(j)); // TODO: think about this
+ } else {
+ i_eq_j = i.eqNode(j);
+ }
+
getOutputChannel().requirePhase(i_eq_j, true);
d_decisionRequests.push(i_eq_j);
}
// TODO: maybe add triggers here
- if (options::arraysEagerLemmas() || bothExist) {
-
+ if ((options::arraysEagerLemmas() || bothExist) && !d_proofsEnabled) {
// Make sure that any terms introduced by rewriting are appropriately stored in the equality database
Node aj2 = Rewriter::rewrite(aj);
if (aj != aj2) {
@@ -2094,6 +2187,7 @@ bool TheoryArrays::dischargeLemmas()
preRegisterTermInternal(bj2);
}
d_equalityEngine.assertEquality(bj.eqNode(bj2), true, d_true);
+
}
if (aj2 == bj2) {
continue;
@@ -2135,18 +2229,31 @@ bool TheoryArrays::dischargeLemmas()
}
void TheoryArrays::conflict(TNode a, TNode b) {
+ Debug("pf::array") << "TheoryArrays::Conflict called" << std::endl;
+ eq::EqProof* proof = d_proofsEnabled ? new eq::EqProof() : NULL;
if (a.getKind() == kind::CONST_BOOLEAN) {
- d_conflictNode = explain(a.iffNode(b));
+ d_conflictNode = explain(a.iffNode(b), proof);
} else {
- d_conflictNode = explain(a.eqNode(b));
+ d_conflictNode = explain(a.eqNode(b), proof);
}
+
if (!d_inCheckModel) {
- d_out->conflict(d_conflictNode);
+ ProofArray* proof_array = NULL;
+
+ if (d_proofsEnabled) {
+ proof->debug_print("pf::array");
+ proof_array = new ProofArray( proof );
+ proof_array->setRowMergeTag(d_reasonRow);
+ proof_array->setRow1MergeTag(d_reasonRow1);
+ proof_array->setExtMergeTag(d_reasonExt);
+ }
+
+ d_out->conflict(d_conflictNode, proof_array);
}
+
d_conflict = true;
}
-
}/* CVC4::theory::arrays namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/arrays/theory_arrays.h b/src/theory/arrays/theory_arrays.h
index eba6c000e..c1223474c 100644
--- a/src/theory/arrays/theory_arrays.h
+++ b/src/theory/arrays/theory_arrays.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arrays.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Clark Barrett
- ** Minor contributors (to current version): Tim King, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory of arrays
**
@@ -23,6 +23,7 @@
#include "context/cdhashset.h"
#include "context/cdqueue.h"
#include "theory/arrays/array_info.h"
+#include "theory/arrays/array_proof_reconstruction.h"
#include "theory/theory.h"
#include "theory/uf/equality_engine.h"
#include "util/statistics_registry.h"
@@ -124,11 +125,20 @@ class TheoryArrays : public Theory {
/** conflicts in setModelVal */
IntStat d_numSetModelValConflicts;
+ // Merge reason types
+
+ /** Merge tag for ROW applications */
+ unsigned d_reasonRow;
+ /** Merge tag for ROW1 applications */
+ unsigned d_reasonRow1;
+ /** Merge tag for EXT applications */
+ unsigned d_reasonExt;
+
public:
TheoryArrays(context::Context* c, context::UserContext* u, OutputChannel& out,
Valuation valuation, const LogicInfo& logicInfo,
- std::string instanceName = "");
+ std::string name = "");
~TheoryArrays();
void setMasterEqualityEngine(eq::EqualityEngine* eq);
@@ -183,7 +193,7 @@ class TheoryArrays : public Theory {
bool propagate(TNode literal);
/** Explain why this literal is true by adding assumptions */
- void explain(TNode literal, std::vector<TNode>& assumptions);
+ void explain(TNode literal, std::vector<TNode>& assumptions, eq::EqProof *proof);
/** For debugging only- checks invariants about when things are preregistered*/
context::CDHashSet<Node, NodeHashFunction > d_isPreRegistered;
@@ -195,6 +205,7 @@ class TheoryArrays : public Theory {
void preRegisterTerm(TNode n);
void propagate(Effort e);
+ Node explain(TNode n, eq::EqProof *proof);
Node explain(TNode n);
/////////////////////////////////////////////////////////////////////////////
@@ -429,6 +440,9 @@ class TheoryArrays : public Theory {
bool d_inCheckModel;
int d_topLevel;
+ /** An equality-engine callback for proof reconstruction */
+ ArrayProofReconstruction d_proofReconstruction;
+
public:
eq::EqualityEngine* getEqualityEngine() {
diff --git a/src/theory/arrays/theory_arrays_rewriter.cpp b/src/theory/arrays/theory_arrays_rewriter.cpp
index 01a7a9584..f1cf1d320 100644
--- a/src/theory/arrays/theory_arrays_rewriter.cpp
+++ b/src/theory/arrays/theory_arrays_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arrays_rewriter.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arrays/theory_arrays_rewriter.h b/src/theory/arrays/theory_arrays_rewriter.h
index 7753e11b9..de10a861b 100644
--- a/src/theory/arrays/theory_arrays_rewriter.h
+++ b/src/theory/arrays/theory_arrays_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arrays_rewriter.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters, Clark Barrett
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Clark Barrett, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/arrays/theory_arrays_type_rules.h b/src/theory/arrays/theory_arrays_type_rules.h
index 70e1c1a5b..d817fb179 100644
--- a/src/theory/arrays/theory_arrays_type_rules.h
+++ b/src/theory/arrays/theory_arrays_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_arrays_type_rules.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Typing and cardinality rules for the theory of arrays
**
@@ -214,6 +214,15 @@ struct ArraysProperties {
}
};/* struct ArraysProperties */
+
+struct ArrayPartialSelectTypeRule {
+ inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+ throw (TypeCheckingExceptionPrivate, AssertionException) {
+ Assert(n.getKind() == kind::PARTIAL_SELECT_0 || n.getKind() == kind::PARTIAL_SELECT_1);
+ return nodeManager->integerType();
+ }
+};/* struct ArrayPartialSelectTypeRule */
+
}/* CVC4::theory::arrays namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/arrays/type_enumerator.h b/src/theory/arrays/type_enumerator.h
index ace23eb82..0208fe52d 100644
--- a/src/theory/arrays/type_enumerator.h
+++ b/src/theory/arrays/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Clark Barrett, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An enumerator for arrays
**
diff --git a/src/theory/arrays/union_find.cpp b/src/theory/arrays/union_find.cpp
index 3f71b350e..7899e85d5 100644
--- a/src/theory/arrays/union_find.cpp
+++ b/src/theory/arrays/union_find.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file union_find.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Path-compressing, backtrackable union-find using an undo
** stack. Refactored from the UF union-find.
diff --git a/src/theory/arrays/union_find.h b/src/theory/arrays/union_find.h
index aef2b8007..5d59e8dcd 100644
--- a/src/theory/arrays/union_find.h
+++ b/src/theory/arrays/union_find.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file union_find.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Path-compressing, backtrackable union-find using an undo
** stack. Refactored from the UF union-find.
diff --git a/src/theory/atom_requests.cpp b/src/theory/atom_requests.cpp
index 22ae054a3..e3f30cc6e 100644
--- a/src/theory/atom_requests.cpp
+++ b/src/theory/atom_requests.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file atom_requests.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/atom_requests.h b/src/theory/atom_requests.h
index 313a50730..7f6194192 100644
--- a/src/theory/atom_requests.h
+++ b/src/theory/atom_requests.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file atom_requests.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/booleans/circuit_propagator.cpp b/src/theory/booleans/circuit_propagator.cpp
index cd6b8dc53..297ff6d9f 100644
--- a/src/theory/booleans/circuit_propagator.cpp
+++ b/src/theory/booleans/circuit_propagator.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file circuit_propagator.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A non-clausal circuit propagator for Boolean simplification
**
diff --git a/src/theory/booleans/circuit_propagator.h b/src/theory/booleans/circuit_propagator.h
index 169ac6fa7..5a6e46269 100644
--- a/src/theory/booleans/circuit_propagator.h
+++ b/src/theory/booleans/circuit_propagator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file circuit_propagator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Tim King, Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A non-clausal circuit propagator for Boolean simplification
**
diff --git a/src/theory/booleans/theory_bool.cpp b/src/theory/booleans/theory_bool.cpp
index a286f1605..d483ba105 100644
--- a/src/theory/booleans/theory_bool.cpp
+++ b/src/theory/booleans/theory_bool.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bool.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The theory of booleans.
**
diff --git a/src/theory/booleans/theory_bool.h b/src/theory/booleans/theory_bool.h
index dc42fc281..eef379bf9 100644
--- a/src/theory/booleans/theory_bool.h
+++ b/src/theory/booleans/theory_bool.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bool.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The theory of booleans
**
diff --git a/src/theory/booleans/theory_bool_rewriter.cpp b/src/theory/booleans/theory_bool_rewriter.cpp
index 05bb99680..cc9eb54b9 100644
--- a/src/theory/booleans/theory_bool_rewriter.cpp
+++ b/src/theory/booleans/theory_bool_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bool_rewriter.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Kshitij Bansal, Tim King
- ** Minor contributors (to current version): Morgan Deters, Clark Barrett
+ ** Top contributors (to current version):
+ ** Tim King, Dejan Jovanovic, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/booleans/theory_bool_rewriter.h b/src/theory/booleans/theory_bool_rewriter.h
index f0f0afe87..b7512ad09 100644
--- a/src/theory/booleans/theory_bool_rewriter.h
+++ b/src/theory/booleans/theory_bool_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bool_rewriter.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/booleans/theory_bool_type_rules.h b/src/theory/booleans/theory_bool_type_rules.h
index 9d12e1bb1..050796e50 100644
--- a/src/theory/booleans/theory_bool_type_rules.h
+++ b/src/theory/booleans/theory_bool_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bool_type_rules.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Christopher L. Conway, Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add brief comments here ]]
**
diff --git a/src/theory/booleans/type_enumerator.h b/src/theory/booleans/type_enumerator.h
index 3849f8435..3949d15d5 100644
--- a/src/theory/booleans/type_enumerator.h
+++ b/src/theory/booleans/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An enumerator for Booleans
**
diff --git a/src/theory/builtin/theory_builtin.cpp b/src/theory/builtin/theory_builtin.cpp
index 07761b72e..cea66dafe 100644
--- a/src/theory/builtin/theory_builtin.cpp
+++ b/src/theory/builtin/theory_builtin.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_builtin.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the builtin theory.
**
diff --git a/src/theory/builtin/theory_builtin.h b/src/theory/builtin/theory_builtin.h
index facc10c67..205db5b4d 100644
--- a/src/theory/builtin/theory_builtin.h
+++ b/src/theory/builtin/theory_builtin.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_builtin.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Built-in theory.
**
diff --git a/src/theory/builtin/theory_builtin_rewriter.cpp b/src/theory/builtin/theory_builtin_rewriter.cpp
index e91c7e411..300a2b0d4 100644
--- a/src/theory/builtin/theory_builtin_rewriter.cpp
+++ b/src/theory/builtin/theory_builtin_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_builtin_rewriter.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/builtin/theory_builtin_rewriter.h b/src/theory/builtin/theory_builtin_rewriter.h
index 83df76d66..9ac259027 100644
--- a/src/theory/builtin/theory_builtin_rewriter.h
+++ b/src/theory/builtin/theory_builtin_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_builtin_rewriter.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/builtin/theory_builtin_type_rules.h b/src/theory/builtin/theory_builtin_type_rules.h
index 977a097d0..af25feaa5 100644
--- a/src/theory/builtin/theory_builtin_type_rules.h
+++ b/src/theory/builtin/theory_builtin_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_builtin_type_rules.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Tim King, Christopher L. Conway, Andrew Reynolds, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Type rules for the builtin theory
**
diff --git a/src/theory/builtin/type_enumerator.h b/src/theory/builtin/type_enumerator.h
index 5ef0e4ab8..3840bb3b1 100644
--- a/src/theory/builtin/type_enumerator.h
+++ b/src/theory/builtin/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Enumerator for uninterpreted sorts
**
diff --git a/src/theory/bv/abstraction.cpp b/src/theory/bv/abstraction.cpp
index 27ca61cfd..fdc36ce72 100644
--- a/src/theory/bv/abstraction.cpp
+++ b/src/theory/bv/abstraction.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file abstraction.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/bv/abstraction.h b/src/theory/bv/abstraction.h
index cba170d76..5d580f6ce 100644
--- a/src/theory/bv/abstraction.h
+++ b/src/theory/bv/abstraction.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file abstraction.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitvector theory.
**
diff --git a/src/theory/bv/aig_bitblaster.cpp b/src/theory/bv/aig_bitblaster.cpp
index d84493daf..887daa1bd 100644
--- a/src/theory/bv/aig_bitblaster.cpp
+++ b/src/theory/bv/aig_bitblaster.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file aig_bitblaster.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief
**
diff --git a/src/theory/bv/bitblast_strategies_template.h b/src/theory/bv/bitblast_strategies_template.h
index bc022a02d..48221aad4 100644
--- a/src/theory/bv/bitblast_strategies_template.h
+++ b/src/theory/bv/bitblast_strategies_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bitblast_strategies_template.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters, Tim King
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of bitblasting functions for various operators.
**
diff --git a/src/theory/bv/bitblast_utils.h b/src/theory/bv/bitblast_utils.h
index adaed31c1..a63c548a2 100644
--- a/src/theory/bv/bitblast_utils.h
+++ b/src/theory/bv/bitblast_utils.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bitblast_utils.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Various utility functions for bit-blasting.
**
diff --git a/src/theory/bv/bitblaster_template.h b/src/theory/bv/bitblaster_template.h
index 9c6c4af9b..cfbadbf32 100644
--- a/src/theory/bv/bitblaster_template.h
+++ b/src/theory/bv/bitblaster_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bitblaster_template.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Wrapper around the SAT solver used for bitblasting
**
@@ -266,6 +266,8 @@ class EagerBitblaster : public TBitblaster<Node> {
TNodeSet d_bbAtoms;
TNodeSet d_variables;
+ MinisatEmptyNotify d_notify;
+
Node getModelFromSatSolver(TNode a, bool fullModel);
bool isSharedTerm(TNode node);
diff --git a/src/theory/bv/bv_eager_solver.cpp b/src/theory/bv/bv_eager_solver.cpp
index 2af8d04d6..cad59f5ca 100644
--- a/src/theory/bv/bv_eager_solver.cpp
+++ b/src/theory/bv/bv_eager_solver.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_eager_solver.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Eager bit-blasting solver.
**
diff --git a/src/theory/bv/bv_eager_solver.h b/src/theory/bv/bv_eager_solver.h
index cfc84dae1..7ac05379b 100644
--- a/src/theory/bv/bv_eager_solver.h
+++ b/src/theory/bv/bv_eager_solver.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_eager_solver.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Eager bit-blasting solver.
**
diff --git a/src/theory/bv/bv_inequality_graph.cpp b/src/theory/bv/bv_inequality_graph.cpp
index dca679194..f03d3a683 100644
--- a/src/theory/bv/bv_inequality_graph.cpp
+++ b/src/theory/bv/bv_inequality_graph.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_inequality_graph.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A graph representation of the currently asserted bv inequalities.
**
diff --git a/src/theory/bv/bv_inequality_graph.h b/src/theory/bv/bv_inequality_graph.h
index 3c67f506f..452172586 100644
--- a/src/theory/bv/bv_inequality_graph.h
+++ b/src/theory/bv/bv_inequality_graph.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_inequality_graph.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_quick_check.cpp b/src/theory/bv/bv_quick_check.cpp
index 40ac3d560..0a9ae819d 100644
--- a/src/theory/bv/bv_quick_check.cpp
+++ b/src/theory/bv/bv_quick_check.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_quick_check.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Wrapper around the SAT solver used for bitblasting.
**
diff --git a/src/theory/bv/bv_quick_check.h b/src/theory/bv/bv_quick_check.h
index 8d2a62287..96f9c246e 100644
--- a/src/theory/bv/bv_quick_check.h
+++ b/src/theory/bv/bv_quick_check.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_quick_check.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sandboxed sat solver for bv quickchecks.
**
diff --git a/src/theory/bv/bv_subtheory.h b/src/theory/bv/bv_subtheory.h
index 402dd6be3..3c5777af9 100644
--- a/src/theory/bv/bv_subtheory.h
+++ b/src/theory/bv/bv_subtheory.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Andrew Reynolds, Dejan Jovanovic
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Dejan Jovanovic, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Interface for bit-vectors sub-solvers.
**
diff --git a/src/theory/bv/bv_subtheory_algebraic.cpp b/src/theory/bv/bv_subtheory_algebraic.cpp
index beca25a88..00d337395 100644
--- a/src/theory/bv/bv_subtheory_algebraic.cpp
+++ b/src/theory/bv/bv_subtheory_algebraic.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_algebraic.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_algebraic.h b/src/theory/bv/bv_subtheory_algebraic.h
index 03588a78f..0e0e02151 100644
--- a/src/theory/bv/bv_subtheory_algebraic.h
+++ b/src/theory/bv/bv_subtheory_algebraic.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_algebraic.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_bitblast.cpp b/src/theory/bv/bv_subtheory_bitblast.cpp
index e7630bb3f..b7619c4bb 100644
--- a/src/theory/bv/bv_subtheory_bitblast.cpp
+++ b/src/theory/bv/bv_subtheory_bitblast.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_bitblast.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Clark Barrett, Liana Hadarean
- ** Minor contributors (to current version): Morgan Deters, Kshitij Bansal, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_bitblast.h b/src/theory/bv/bv_subtheory_bitblast.h
index c69069109..e9300138b 100644
--- a/src/theory/bv/bv_subtheory_bitblast.h
+++ b/src/theory/bv/bv_subtheory_bitblast.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_bitblast.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean
- ** Minor contributors (to current version): Morgan Deters, Andrew Reynolds, Clark Barrett
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_core.cpp b/src/theory/bv/bv_subtheory_core.cpp
index ec257468e..97cbdb215 100644
--- a/src/theory/bv/bv_subtheory_core.cpp
+++ b/src/theory/bv/bv_subtheory_core.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_core.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_core.h b/src/theory/bv/bv_subtheory_core.h
index 0ff193b41..643093327 100644
--- a/src/theory/bv/bv_subtheory_core.h
+++ b/src/theory/bv/bv_subtheory_core.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_core.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_inequality.cpp b/src/theory/bv/bv_subtheory_inequality.cpp
index 7916d941e..7d68f19b2 100644
--- a/src/theory/bv/bv_subtheory_inequality.cpp
+++ b/src/theory/bv/bv_subtheory_inequality.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_inequality.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_subtheory_inequality.h b/src/theory/bv/bv_subtheory_inequality.h
index c9d9dabd3..9607c0296 100644
--- a/src/theory/bv/bv_subtheory_inequality.h
+++ b/src/theory/bv/bv_subtheory_inequality.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_subtheory_inequality.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Andrew Reynolds, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Algebraic solver.
**
diff --git a/src/theory/bv/bv_to_bool.cpp b/src/theory/bv/bv_to_bool.cpp
index 66ad4fec0..36772406d 100644
--- a/src/theory/bv/bv_to_bool.cpp
+++ b/src/theory/bv/bv_to_bool.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_to_bool.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Preprocessing pass that lifts bit-vectors of size 1 to booleans.
**
diff --git a/src/theory/bv/bv_to_bool.h b/src/theory/bv/bv_to_bool.h
index e6c126440..25d67b98e 100644
--- a/src/theory/bv/bv_to_bool.h
+++ b/src/theory/bv/bv_to_bool.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bv_to_bool.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Preprocessing pass that lifts bit-vectors of size 1 to booleans.
**
diff --git a/src/theory/bv/bvintropow2.cpp b/src/theory/bv/bvintropow2.cpp
index 5df170e21..022aaf2fd 100644
--- a/src/theory/bv/bvintropow2.cpp
+++ b/src/theory/bv/bvintropow2.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bvintropow2.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/bvintropow2.h b/src/theory/bv/bvintropow2.h
index 774645560..09d3d9259 100644
--- a/src/theory/bv/bvintropow2.h
+++ b/src/theory/bv/bvintropow2.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bvintropow2.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/cd_set_collection.h b/src/theory/bv/cd_set_collection.h
index 5ffe7032a..456552ebd 100644
--- a/src/theory/bv/cd_set_collection.h
+++ b/src/theory/bv/cd_set_collection.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cd_set_collection.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King, Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/eager_bitblaster.cpp b/src/theory/bv/eager_bitblaster.cpp
index dd561667c..3b54e3794 100644
--- a/src/theory/bv/eager_bitblaster.cpp
+++ b/src/theory/bv/eager_bitblaster.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file eager_bitblaster.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief
**
@@ -36,9 +36,14 @@ void BitblastingRegistrar::preRegister(Node n) {
EagerBitblaster::EagerBitblaster(TheoryBV* theory_bv)
: TBitblaster<Node>()
+ , d_satSolver(NULL)
+ , d_bitblastingRegistrar(NULL)
+ , d_nullContext(NULL)
+ , d_cnfStream(NULL)
, d_bv(theory_bv)
, d_bbAtoms()
, d_variables()
+ , d_notify()
{
d_bitblastingRegistrar = new BitblastingRegistrar(this);
d_nullContext = new context::Context();
@@ -50,8 +55,7 @@ EagerBitblaster::EagerBitblaster(TheoryBV* theory_bv)
d_satSolver, d_bitblastingRegistrar, d_nullContext, options::proof(),
"EagerBitblaster");
- MinisatEmptyNotify* notify = new MinisatEmptyNotify();
- d_satSolver->setNotify(notify);
+ d_satSolver->setNotify(&d_notify);
d_bvp = NULL;
}
@@ -95,7 +99,7 @@ void EagerBitblaster::bbAtom(TNode node) {
// asserting that the atom is true iff the definition holds
Node atom_definition = utils::mkNode(kind::IFF, node, atom_bb);
- AlwaysAssert (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER);
+ AlwaysAssert (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER);
storeBBAtom(node, atom_bb);
d_cnfStream->convertAndAssert(atom_definition, false, false, RULE_INVALID, TNode::null());
}
@@ -104,7 +108,7 @@ void EagerBitblaster::storeBBAtom(TNode atom, Node atom_bb) {
if( d_bvp ){
d_bvp->registerAtomBB(atom.toExpr(), atom_bb.toExpr());
}
- d_bbAtoms.insert(atom);
+ d_bbAtoms.insert(atom);
}
void EagerBitblaster::storeBBTerm(TNode node, const Bits& bits) {
@@ -136,13 +140,13 @@ void EagerBitblaster::bbTerm(TNode node, Bits& bits) {
void EagerBitblaster::makeVariable(TNode var, Bits& bits) {
Assert(bits.size() == 0);
for (unsigned i = 0; i < utils::getSize(var); ++i) {
- bits.push_back(utils::mkBitOf(var, i));
+ bits.push_back(utils::mkBitOf(var, i));
}
- d_variables.insert(var);
+ d_variables.insert(var);
}
Node EagerBitblaster::getBBAtom(TNode node) const {
- return node;
+ return node;
}
diff --git a/src/theory/bv/lazy_bitblaster.cpp b/src/theory/bv/lazy_bitblaster.cpp
index ca21e98c4..c821b50cd 100644
--- a/src/theory/bv/lazy_bitblaster.cpp
+++ b/src/theory/bv/lazy_bitblaster.cpp
@@ -1,17 +1,17 @@
/********************* */
/*! \file lazy_bitblaster.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
- ** \brief Bitblaster for the lazy bv solver.
+ ** \brief Bitblaster for the lazy bv solver.
**
- ** Bitblaster for the lazy bv solver.
+ ** Bitblaster for the lazy bv solver.
**/
#include "bitblaster_template.h"
@@ -123,11 +123,11 @@ void TLazyBitblaster::bbAtom(TNode node) {
}
atom_bb = utils::mkAnd(atoms);
}
- Assert (!atom_bb.isNull());
+ Assert (!atom_bb.isNull());
Node atom_definition = utils::mkNode(kind::IFF, node, atom_bb);
storeBBAtom(node, atom_bb);
d_cnfStream->convertAndAssert(atom_definition, false, false, RULE_INVALID, TNode::null());
- return;
+ return;
}
// the bitblasted definition of the atom
@@ -138,7 +138,7 @@ void TLazyBitblaster::bbAtom(TNode node) {
if (!options::proof()) {
atom_bb = Rewriter::rewrite(atom_bb);
}
-
+
// asserting that the atom is true iff the definition holds
Node atom_definition = utils::mkNode(kind::IFF, node, atom_bb);
storeBBAtom(node, atom_bb);
@@ -150,7 +150,7 @@ void TLazyBitblaster::storeBBAtom(TNode atom, Node atom_bb) {
if( d_bvp != NULL ){
d_bvp->registerAtomBB(atom.toExpr(), atom_bb.toExpr());
}
- d_bbAtoms.insert(atom);
+ d_bbAtoms.insert(atom);
}
void TLazyBitblaster::storeBBTerm(TNode node, const Bits& bits) {
@@ -160,16 +160,16 @@ void TLazyBitblaster::storeBBTerm(TNode node, const Bits& bits) {
bool TLazyBitblaster::hasBBAtom(TNode atom) const {
- return d_bbAtoms.find(atom) != d_bbAtoms.end();
+ return d_bbAtoms.find(atom) != d_bbAtoms.end();
}
void TLazyBitblaster::makeVariable(TNode var, Bits& bits) {
Assert(bits.size() == 0);
for (unsigned i = 0; i < utils::getSize(var); ++i) {
- bits.push_back(utils::mkBitOf(var, i));
+ bits.push_back(utils::mkBitOf(var, i));
}
- d_variables.insert(var);
+ d_variables.insert(var);
}
uint64_t TLazyBitblaster::computeAtomWeight(TNode node, NodeSet& seen) {
@@ -182,7 +182,7 @@ uint64_t TLazyBitblaster::computeAtomWeight(TNode node, NodeSet& seen) {
// cnf conversion ensures the atom represents itself
Node TLazyBitblaster::getBBAtom(TNode node) const {
- return node;
+ return node;
}
void TLazyBitblaster::bbTerm(TNode node, Bits& bits) {
@@ -220,9 +220,9 @@ void TLazyBitblaster::explain(TNode atom, std::vector<TNode>& explanation) {
for (unsigned i = 0; i < literal_explanation.size(); ++i) {
explanation.push_back(d_cnfStream->getNode(literal_explanation[i]));
}
- return;
+ return;
}
-
+
std::vector<prop::SatLiteral> literal_explanation;
d_satSolver->explain(lit, literal_explanation);
for (unsigned i = 0; i < literal_explanation.size(); ++i) {
@@ -285,7 +285,7 @@ bool TLazyBitblaster::solve() {
}
}
Debug("bitvector") << "TLazyBitblaster::solve() asserted atoms " << d_assertedAtoms->size() <<"\n";
- d_satSolverFullModel.set(true);
+ d_satSolverFullModel.set(true);
return prop::SAT_VALUE_TRUE == d_satSolver->solve();
}
@@ -357,11 +357,11 @@ bool TLazyBitblaster::MinisatNotify::notify(prop::SatLiteral lit) {
d_lazyBB->d_explanations->insert(lit, literal_explanation);
} else {
// we propagated it at a lower level
- return true;
+ return true;
}
}
++(d_lazyBB->d_statistics.d_numBitblastingPropagations);
- TNode atom = d_cnf->getNode(lit);
+ TNode atom = d_cnf->getNode(lit);
return d_bv->storePropagation(atom, SUB_BITBLAST);
}
@@ -398,13 +398,13 @@ EqualityStatus TLazyBitblaster::getEqualityStatus(TNode a, TNode b) {
if (a_eq_b == utils::mkTrue()) return theory::EQUALITY_TRUE;
if (!d_satSolverFullModel.get())
- return theory::EQUALITY_UNKNOWN;
-
+ return theory::EQUALITY_UNKNOWN;
+
// Check if cache is valid (invalidated in check and pops)
if (d_bv->d_invalidateModelCache.get()) {
- invalidateModelCache();
+ invalidateModelCache();
}
- d_bv->d_invalidateModelCache.set(false);
+ d_bv->d_invalidateModelCache.set(false);
Node a_value = getTermModel(a, true);
Node b_value = getTermModel(b, true);
@@ -414,10 +414,10 @@ EqualityStatus TLazyBitblaster::getEqualityStatus(TNode a, TNode b) {
if (a_value == b_value) {
Debug("bv-equality-status")<< "theory::EQUALITY_TRUE_IN_MODEL\n";
- return theory::EQUALITY_TRUE_IN_MODEL;
+ return theory::EQUALITY_TRUE_IN_MODEL;
}
Debug("bv-equality-status")<< "theory::EQUALITY_FALSE_IN_MODEL\n";
- return theory::EQUALITY_FALSE_IN_MODEL;
+ return theory::EQUALITY_FALSE_IN_MODEL;
}
@@ -426,9 +426,9 @@ bool TLazyBitblaster::isSharedTerm(TNode node) {
}
bool TLazyBitblaster::hasValue(TNode a) {
- Assert (hasBBTerm(a));
+ Assert (hasBBTerm(a));
Bits bits;
- getBBTerm(a, bits);
+ getBBTerm(a, bits);
for (int i = bits.size() -1; i >= 0; --i) {
prop::SatValue bit_value;
if (d_cnfStream->hasLiteral(bits[i])) {
@@ -456,7 +456,7 @@ Node TLazyBitblaster::getModelFromSatSolver(TNode a, bool fullModel) {
if (!hasBBTerm(a)) {
return fullModel? utils::mkConst(utils::getSize(a), 0u) : Node();
}
-
+
Bits bits;
getBBTerm(a, bits);
Integer value(0);
@@ -486,13 +486,13 @@ void TLazyBitblaster::collectModelInfo(TheoryModel* m, bool fullModel) {
// not actually a leaf of the bit-vector theory
if (d_variables.find(var) == d_variables.end())
continue;
-
- Assert (Theory::theoryOf(var) == theory::THEORY_BV || isSharedTerm(var));
+
+ Assert (Theory::theoryOf(var) == theory::THEORY_BV || isSharedTerm(var));
// only shared terms could not have been bit-blasted
Assert (hasBBTerm(var) || isSharedTerm(var));
-
+
Node const_value = getModelFromSatSolver(var, fullModel);
- Assert (const_value.isNull() || const_value.isConst());
+ Assert (const_value.isNull() || const_value.isConst());
if(const_value != Node()) {
Debug("bitvector-model") << "TLazyBitblaster::collectModelInfo (assert (= "
<< var << " "
diff --git a/src/theory/bv/slicer.cpp b/src/theory/bv/slicer.cpp
index 0e6815f47..150f73ac9 100644
--- a/src/theory/bv/slicer.cpp
+++ b/src/theory/bv/slicer.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file slicer.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitvector theory.
**
diff --git a/src/theory/bv/slicer.h b/src/theory/bv/slicer.h
index 68642784f..4eae27963 100644
--- a/src/theory/bv/slicer.h
+++ b/src/theory/bv/slicer.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file slicer.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitvector theory.
**
diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp
index 191f70638..2edadce72 100644
--- a/src/theory/bv/theory_bv.cpp
+++ b/src/theory/bv/theory_bv.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean
- ** Minor contributors (to current version): Tim King, Kshitij Bansal, Clark Barrett, Andrew Reynolds, Morgan Deters, Martin Brain <>
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/bv/theory_bv.h b/src/theory/bv/theory_bv.h
index 1da15abf8..0bbcba9b0 100644
--- a/src/theory/bv/theory_bv.h
+++ b/src/theory/bv/theory_bv.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic, Liana Hadarean
- ** Minor contributors (to current version): Clark Barrett, Kshitij Bansal, Tim King, Andrew Reynolds, Martin Brain <>
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitvector theory.
**
diff --git a/src/theory/bv/theory_bv_rewrite_rules.h b/src/theory/bv/theory_bv_rewrite_rules.h
index 9f3c34e8e..7200d1dec 100644
--- a/src/theory/bv/theory_bv_rewrite_rules.h
+++ b/src/theory/bv/theory_bv_rewrite_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewrite_rules.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean
- ** Minor contributors (to current version): Tim King, Clark Barrett, Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h b/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h
index 1f8799682..a7e50974c 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewrite_rules_constant_evaluation.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Morgan Deters, Tim King
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewrite_rules_core.h b/src/theory/bv/theory_bv_rewrite_rules_core.h
index 185985b3b..395949f03 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_core.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_core.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewrite_rules_core.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King, Clark Barrett, Liana Hadarean, Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Liana Hadarean, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewrite_rules_normalization.h b/src/theory/bv/theory_bv_rewrite_rules_normalization.h
index 0911b6ccf..4abd02e73 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_normalization.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_normalization.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewrite_rules_normalization.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Clark Barrett
- ** Minor contributors (to current version): Dejan Jovanovic, Morgan Deters, Tim King
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h b/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h
index d5d6c39dd..152a335a5 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewrite_rules_operator_elimination.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters, Clark Barrett
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Clark Barrett, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewrite_rules_simplification.h b/src/theory/bv/theory_bv_rewrite_rules_simplification.h
index 4d3b676c9..d84a07780 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_simplification.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_simplification.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewrite_rules_simplification.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters, Dejan Jovanovic, Tim King, Clark Barrett
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewriter.cpp b/src/theory/bv/theory_bv_rewriter.cpp
index 6e2fdf58e..acb12d649 100644
--- a/src/theory/bv/theory_bv_rewriter.cpp
+++ b/src/theory/bv/theory_bv_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewriter.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean
- ** Minor contributors (to current version): Tim King, Clark Barrett, Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_rewriter.h b/src/theory/bv/theory_bv_rewriter.h
index 3f0fa8194..538754a4b 100644
--- a/src/theory/bv/theory_bv_rewriter.h
+++ b/src/theory/bv/theory_bv_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_rewriter.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters, Liana Hadarean
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_type_rules.h b/src/theory/bv/theory_bv_type_rules.h
index fbb285fe0..b531129f7 100644
--- a/src/theory/bv/theory_bv_type_rules.h
+++ b/src/theory/bv/theory_bv_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_type_rules.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Christopher L. Conway, Liana Hadarean, Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bitvector theory typing rules
**
diff --git a/src/theory/bv/theory_bv_utils.cpp b/src/theory/bv/theory_bv_utils.cpp
index f57ccec48..f743e2d64 100644
--- a/src/theory/bv/theory_bv_utils.cpp
+++ b/src/theory/bv/theory_bv_utils.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_utils.cpp
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/theory_bv_utils.h b/src/theory/bv/theory_bv_utils.h
index 993be309b..dc3463c84 100644
--- a/src/theory/bv/theory_bv_utils.h
+++ b/src/theory/bv/theory_bv_utils.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_bv_utils.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Liana Hadarean
- ** Minor contributors (to current version): Kshitij Bansal, Clark Barrett, Morgan Deters
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/bv/type_enumerator.h b/src/theory/bv/type_enumerator.h
index da06b1152..39f1e87f6 100644
--- a/src/theory/bv/type_enumerator.h
+++ b/src/theory/bv/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An enumerator for bitvectors
**
diff --git a/src/theory/datatypes/datatypes_rewriter.h b/src/theory/datatypes/datatypes_rewriter.h
index 0c00ed8df..dd2803d30 100644
--- a/src/theory/datatypes/datatypes_rewriter.h
+++ b/src/theory/datatypes/datatypes_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file datatypes_rewriter.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter for the theory of inductive datatypes
**
@@ -200,20 +200,24 @@ public:
}
}
- if(in.getKind() == kind::EQUAL && in[0] == in[1]) {
- return RewriteResponse(REWRITE_DONE,
- NodeManager::currentNM()->mkConst(true));
- }
if(in.getKind() == kind::EQUAL ) {
- std::vector< Node > rew;
- if( checkClash(in[0], in[1], rew) ){
- Trace("datatypes-rewrite") << "Rewrite clashing equality " << in << " to false" << std::endl;
- return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(false));
- }else if( rew.size()==1 && rew[0]!=in ){
- Trace("datatypes-rewrite") << "Rewrite equality " << in << " to " << rew[0] << std::endl;
- return RewriteResponse(REWRITE_AGAIN_FULL, rew[0] );
+ if(in[0] == in[1]) {
+ return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(true));
}else{
- Trace("datatypes-rewrite-debug") << "Did not rewrite equality " << in << " " << in[0].getKind() << " " << in[1].getKind() << std::endl;
+ std::vector< Node > rew;
+ if( checkClash(in[0], in[1], rew) ){
+ Trace("datatypes-rewrite") << "Rewrite clashing equality " << in << " to false" << std::endl;
+ return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(false));
+ //}else if( rew.size()==1 && rew[0]!=in ){
+ // Trace("datatypes-rewrite") << "Rewrite equality " << in << " to " << rew[0] << std::endl;
+ // return RewriteResponse(REWRITE_AGAIN_FULL, rew[0] );
+ }else if( in[1]<in[0] ){
+ Node ins = NodeManager::currentNM()->mkNode(in.getKind(), in[1], in[0]);
+ Trace("datatypes-rewrite") << "Swap equality " << in << " to " << ins << std::endl;
+ return RewriteResponse(REWRITE_DONE, ins);
+ }else{
+ Trace("datatypes-rewrite-debug") << "Did not rewrite equality " << in << " " << in[0].getKind() << " " << in[1].getKind() << std::endl;
+ }
}
}
@@ -256,10 +260,6 @@ public:
/** get instantiate cons */
static Node getInstCons( Node n, const Datatype& dt, int index ) {
Assert( index>=0 && index<(int)dt.getNumConstructors() );
- Type tspec;
- if( dt.isParametric() ){
- tspec = dt[index].getSpecializedConstructorType(n.getType().toType());
- }
std::vector< Node > children;
children.push_back( Node::fromExpr( dt[index].getConstructor() ) );
for( int i=0; i<(int)dt[index].getNumArgs(); i++ ){
diff --git a/src/theory/datatypes/datatypes_sygus.cpp b/src/theory/datatypes/datatypes_sygus.cpp
index 07fb60e57..5bd6680f2 100644
--- a/src/theory/datatypes/datatypes_sygus.cpp
+++ b/src/theory/datatypes/datatypes_sygus.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file theory_datatypes.cpp
+/*! \file datatypes_sygus.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of sygus utilities for theory of datatypes
**
diff --git a/src/theory/datatypes/datatypes_sygus.h b/src/theory/datatypes/datatypes_sygus.h
index b00fade36..0add578f0 100644
--- a/src/theory/datatypes/datatypes_sygus.h
+++ b/src/theory/datatypes/datatypes_sygus.h
@@ -1,13 +1,13 @@
/********************* */
-/*! \file theory_datatypes.h
+/*! \file datatypes_sygus.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sygus utilities for theory of datatypes
**
diff --git a/src/theory/datatypes/kinds b/src/theory/datatypes/kinds
index c31a462bd..d035f0fa7 100644
--- a/src/theory/datatypes/kinds
+++ b/src/theory/datatypes/kinds
@@ -85,12 +85,6 @@ typerule APPLY_TYPE_ASCRIPTION ::CVC4::theory::datatypes::DatatypeAscriptionType
# constructor applications are constant if they are applied only to constants
construle APPLY_CONSTRUCTOR ::CVC4::theory::datatypes::DatatypeConstructorTypeRule
-## for co-datatypes
-operator MU 2 "a mu operator, first argument is a bound variable, second argument is body"
-typerule MU ::CVC4::theory::datatypes::DatatypeMuTypeRule
-# mu applications are constant expressions
-construle MU ::CVC4::theory::datatypes::DatatypeMuTypeRule
-
constant TUPLE_UPDATE_OP \
::CVC4::TupleUpdate \
::CVC4::TupleUpdateHashFunction \
@@ -99,22 +93,6 @@ constant TUPLE_UPDATE_OP \
parameterized TUPLE_UPDATE TUPLE_UPDATE_OP 2 "tuple update; first parameter is a TUPLE_UPDATE_OP (which references an index), second is the tuple, third is the element to store in the tuple at the given index"
typerule TUPLE_UPDATE ::CVC4::theory::datatypes::TupleUpdateTypeRule
-constant RECORD_TYPE \
- ::CVC4::Record \
- ::CVC4::RecordHashFunction \
- "expr/record.h" \
- "record type"
-cardinality RECORD_TYPE \
- "::CVC4::theory::datatypes::RecordProperties::computeCardinality(%TYPE%)" \
- "theory/datatypes/theory_datatypes_type_rules.h"
-well-founded RECORD_TYPE \
- "::CVC4::theory::datatypes::RecordProperties::isWellFounded(%TYPE%)" \
- "::CVC4::theory::datatypes::RecordProperties::mkGroundTerm(%TYPE%)" \
- "theory/datatypes/theory_datatypes_type_rules.h"
-enumerator RECORD_TYPE \
- "::CVC4::theory::datatypes::RecordEnumerator" \
- "theory/datatypes/type_enumerator.h"
-
constant RECORD_UPDATE_OP \
::CVC4::RecordUpdate \
::CVC4::RecordUpdateHashFunction \
diff --git a/src/theory/datatypes/theory_datatypes.cpp b/src/theory/datatypes/theory_datatypes.cpp
index ad2b1a297..eb8b23973 100644
--- a/src/theory/datatypes/theory_datatypes.cpp
+++ b/src/theory/datatypes/theory_datatypes.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_datatypes.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the theory of datatypes
**
@@ -75,6 +75,12 @@ TheoryDatatypes::TheoryDatatypes(Context* c, UserContext* u, OutputChannel& out,
}
TheoryDatatypes::~TheoryDatatypes() {
+ for(std::map< Node, EqcInfo* >::iterator i = d_eqc_info.begin(), iend = d_eqc_info.end();
+ i != iend; ++i){
+ EqcInfo* current = (*i).second;
+ Assert(current != NULL);
+ delete current;
+ }
}
void TheoryDatatypes::setMasterEqualityEngine(eq::EqualityEngine* eq) {
@@ -91,7 +97,7 @@ TheoryDatatypes::EqcInfo* TheoryDatatypes::getOrMakeEqcInfo( TNode n, bool doMak
std::map< Node, EqcInfo* >::iterator eqc_i = d_eqc_info.find( n );
EqcInfo* ei;
- if( eqc_i!=d_eqc_info.end() ){
+ if( eqc_i != d_eqc_info.end() ){
ei = eqc_i->second;
}else{
ei = new EqcInfo( getSatContext() );
@@ -159,20 +165,19 @@ void TheoryDatatypes::check(Effort e) {
if( e == EFFORT_FULL && !d_conflict && !d_addedLemma && !d_valuation.needCheck() ) {
//check for cycles
Assert( d_pending.empty() && d_pending_merge.empty() );
- bool addedFact;
do {
+ d_addedFact = false;
checkCycles();
- addedFact = !d_pending.empty() || !d_pending_merge.empty();
flushPendingFacts();
if( d_conflict || d_addedLemma ){
return;
}
- }while( addedFact );
+ }while( d_addedFact );
//check for splits
Trace("datatypes-debug") << "Check for splits " << e << endl;
- addedFact = false;
do {
+ d_addedFact = false;
std::map< TypeNode, Node > rec_singletons;
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( &d_equalityEngine );
while( !eqcs_i.isFinished() ){
@@ -233,9 +238,11 @@ void TheoryDatatypes::check(Effort e) {
//all other cases
std::vector< bool > pcons;
getPossibleCons( eqc, n, pcons );
+ //std::map< int, bool > sel_apps;
+ //getSelectorsForCons( n, sel_apps );
//check if we do not need to resolve the constructor type for this equivalence class.
- // this is if there are no selectors for this equivalence class, its possible values are infinite,
- // and we are not producing a model, then do not split.
+ // this is if there are no selectors for this equivalence class, and its possible values are infinite,
+ // then do not split.
int consIndex = -1;
int fconsIndex = -1;
bool needSplit = true;
@@ -317,7 +324,6 @@ void TheoryDatatypes::check(Effort e) {
++eqcs_i;
}
Trace("datatypes-debug") << "Flush pending facts..." << std::endl;
- addedFact = !d_pending.empty() || !d_pending_merge.empty();
flushPendingFacts();
/*
if( !d_conflict ){
@@ -331,8 +337,8 @@ void TheoryDatatypes::check(Effort e) {
}
}
*/
- }while( !d_conflict && !d_addedLemma && addedFact );
- Trace("datatypes-debug") << "Finished. " << d_conflict << std::endl;
+ }while( !d_conflict && !d_addedLemma && d_addedFact );
+ Trace("datatypes-debug") << "Finished, conflict=" << d_conflict << ", lemmas=" << d_addedLemma << std::endl;
if( !d_conflict ){
Trace("dt-model-debug") << std::endl;
printModelDebug("dt-model-debug");
@@ -347,6 +353,7 @@ void TheoryDatatypes::check(Effort e) {
void TheoryDatatypes::flushPendingFacts(){
doPendingMerges();
+ //pending lemmas: used infrequently, only for definitional lemmas
if( !d_pending_lem.empty() ){
int i = 0;
while( i<(int)d_pending_lem.size() ){
@@ -368,16 +375,31 @@ void TheoryDatatypes::flushPendingFacts(){
Trace("dt-lemma-debug") << "Trivial explanation." << std::endl;
}else{
Trace("dt-lemma-debug") << "Get explanation..." << std::endl;
- Node ee_exp = explain( exp );
- Trace("dt-lemma-debug") << "Explanation : " << ee_exp << std::endl;
- lem = NodeManager::currentNM()->mkNode( OR, ee_exp.negate(), fact );
- lem = Rewriter::rewrite( lem );
+ std::vector< TNode > assumptions;
+ //if( options::dtRExplainLemmas() ){
+ explain( exp, assumptions );
+ //}else{
+ // ee_exp = exp;
+ //}
+ //Trace("dt-lemma-debug") << "Explanation : " << ee_exp << std::endl;
+ if( assumptions.empty() ){
+ lem = fact;
+ }else{
+ std::vector< Node > children;
+ for( unsigned i=0; i<assumptions.size(); i++ ){
+ children.push_back( assumptions[i].negate() );
+ }
+ children.push_back( fact );
+ lem = NodeManager::currentNM()->mkNode( OR, children );
+ }
}
Trace("dt-lemma") << "Datatypes lemma : " << lem << std::endl;
- doSendLemma( lem );
- d_addedLemma = true;
+ if( doSendLemma( lem ) ){
+ d_addedLemma = true;
+ }
}else{
assertFact( fact, exp );
+ d_addedFact = true;
}
Trace("datatypes-debug") << "Finished fact " << fact << ", now = " << d_conflict << " " << d_pending.size() << std::endl;
i++;
@@ -518,8 +540,9 @@ Node TheoryDatatypes::expandDefinition(LogicRequest &logicRequest, Node n) {
if( tst==d_true ){
n_ret = sel;
}else{
- mkExpDefSkolem( selector, n[0].getType(), n.getType() );
- Node sk = NodeManager::currentNM()->mkNode( kind::APPLY_UF, d_exp_def_skolem[ selector ], n[0] );
+ TypeNode ndt = n[0].getType();
+ mkExpDefSkolem( selector, ndt, n.getType() );
+ Node sk = NodeManager::currentNM()->mkNode( kind::APPLY_UF, d_exp_def_skolem[ndt][ selector ], n[0] );
if( tst==NodeManager::currentNM()->mkConst( false ) ){
n_ret = sk;
}else{
@@ -582,20 +605,6 @@ Node TheoryDatatypes::ppRewrite(TNode in) {
return n;
}
- if((t.isTuple() || t.isRecord()) && in.hasAttribute(smt::BooleanTermAttr())) {
- Debug("tuprec") << "should map " << in << " of type " << t << " back to " << in.getAttribute(smt::BooleanTermAttr()).getType() << endl;
- Debug("tuprec") << "so " << t.getDatatype() << " goes to " << in.getAttribute(smt::BooleanTermAttr()).getType().getDatatype() << endl;
- if(t.isTuple()) {
- Debug("tuprec") << "current datatype-tuple-attr is " << t.getAttribute(expr::DatatypeTupleAttr()) << endl;
- Debug("tuprec") << "setting to " << in.getAttribute(smt::BooleanTermAttr()).getType().getAttribute(expr::DatatypeTupleAttr()) << endl;
- t.setAttribute(expr::DatatypeTupleAttr(), in.getAttribute(smt::BooleanTermAttr()).getType().getAttribute(expr::DatatypeTupleAttr()));
- } else {
- Debug("tuprec") << "current datatype-record-attr is " << t.getAttribute(expr::DatatypeRecordAttr()) << endl;
- Debug("tuprec") << "setting to " << in.getAttribute(smt::BooleanTermAttr()).getType().getAttribute(expr::DatatypeRecordAttr()) << endl;
- t.setAttribute(expr::DatatypeRecordAttr(), in.getAttribute(smt::BooleanTermAttr()).getType().getAttribute(expr::DatatypeRecordAttr()));
- }
- }
-
if( in.getKind()==EQUAL ){
Node nn;
std::vector< Node > rew;
@@ -907,10 +916,11 @@ void TheoryDatatypes::eqNotifyDisequal(TNode t1, TNode t2, TNode reason){
}
-TheoryDatatypes::EqcInfo::EqcInfo( context::Context* c ) :
-d_inst( c, false ), d_constructor( c, Node::null() ), d_selectors( c, false ){
-
-}
+TheoryDatatypes::EqcInfo::EqcInfo( context::Context* c )
+ : d_inst( c, false )
+ , d_constructor( c, Node::null() )
+ , d_selectors( c, false )
+{}
bool TheoryDatatypes::hasLabel( EqcInfo* eqc, Node n ){
return ( eqc && !eqc->d_constructor.get().isNull() ) || !getLabel( n ).isNull();
@@ -973,11 +983,22 @@ void TheoryDatatypes::getPossibleCons( EqcInfo* eqc, Node n, std::vector< bool >
}
}
+void TheoryDatatypes::getSelectorsForCons( Node r, std::map< int, bool >& sels ) {
+ NodeListMap::iterator sel_i = d_selector_apps.find( r );
+ if( sel_i != d_selector_apps.end() ){
+ NodeList* sel = (*sel_i).second;
+ for( NodeList::const_iterator j = sel->begin(); j != sel->end(); j++ ){
+ int sindex = Datatype::indexOf( (*j).getOperator().toExpr() );
+ sels[sindex] = true;
+ }
+ }
+}
+
void TheoryDatatypes::mkExpDefSkolem( Node sel, TypeNode dt, TypeNode rt ) {
- if( d_exp_def_skolem.find( sel )==d_exp_def_skolem.end() ){
+ if( d_exp_def_skolem[dt].find( sel )==d_exp_def_skolem[dt].end() ){
std::stringstream ss;
ss << sel << "_uf";
- d_exp_def_skolem[ sel ] = NodeManager::currentNM()->mkSkolem( ss.str().c_str(),
+ d_exp_def_skolem[dt][ sel ] = NodeManager::currentNM()->mkSkolem( ss.str().c_str(),
NodeManager::currentNM()->mkFunctionType( dt, rt ) );
}
}
@@ -1279,7 +1300,8 @@ void TheoryDatatypes::computeCareGraph(){
TNode y = f2[k];
Assert(d_equalityEngine.hasTerm(x));
Assert(d_equalityEngine.hasTerm(y));
- if( areDisequal(x, y) ){
+ //need to consider types for parametric selectors
+ if( x.getType()!=y.getType() || areDisequal(x, y) ){
somePairIsDisequal = true;
break;
}else if( !d_equalityEngine.areEqual( x, y ) ){
@@ -1927,14 +1949,9 @@ bool TheoryDatatypes::mustCommunicateFact( Node n, Node exp ){
//We may need to communicate outwards if the conclusions involve other theories. Also communicate (6) and OR conclusions.
Trace("dt-lemma-debug") << "Compute for " << exp << " => " << n << std::endl;
bool addLemma = false;
- if( n.getKind()==EQUAL || n.getKind()==IFF ){
- /*
- for( unsigned i=0; i<2; i++ ){
- if( !n[i].isVar() && n[i].getKind()!=APPLY_SELECTOR_TOTAL && n[i].getKind()!=APPLY_CONSTRUCTOR ){
- addLemma = true;
- }
- }
- */
+ if( options::dtInferAsLemmas() && exp!=d_true ){
+ addLemma = true;
+ }else if( n.getKind()==EQUAL ){
TypeNode tn = n[0].getType();
if( !DatatypesRewriter::isTypeDatatype( tn ) ){
addLemma = true;
@@ -1942,35 +1959,16 @@ bool TheoryDatatypes::mustCommunicateFact( Node n, Node exp ){
const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
addLemma = dt.involvesExternalType();
}
- //for( int j=0; j<(int)n[1].getNumChildren(); j++ ){
- // if( !DatatypesRewriter::isTermDatatype( n[1][j] ) ){
- // addLemma = true;
- // break;
- // }
- //}
- }else if( n.getKind()==LEQ ){
- addLemma = true;
- }else if( n.getKind()==OR ){
+ }else if( n.getKind()==LEQ || n.getKind()==IFF || n.getKind()==OR ){
addLemma = true;
}
if( addLemma ){
- //check if we have already added this lemma
- //if( std::find( d_inst_lemmas[ n[0] ].begin(), d_inst_lemmas[ n[0] ].end(), n[1] )==d_inst_lemmas[ n[0] ].end() ){
- // d_inst_lemmas[ n[0] ].push_back( n[1] );
Trace("dt-lemma-debug") << "Communicate " << n << std::endl;
return true;
- //}else{
- // Trace("dt-lemma-debug") << "Already communicated " << n << std::endl;
- // return false;
- //}
+ }else{
+ Trace("dt-lemma-debug") << "Do not need to communicate " << n << std::endl;
+ return false;
}
- //else if( exp.getKind()==APPLY_TESTER ){
- //if( n.getKind()==EQUAL && !DatatypesRewriter::isTermDatatype( n[0] ) ){
- // return true;
- //}
- //}
- Trace("dt-lemma-debug") << "Do not need to communicate " << n << std::endl;
- return false;
}
bool TheoryDatatypes::hasTerm( TNode a ){
@@ -2109,6 +2107,40 @@ bool TheoryDatatypes::checkClashModEq( TNode n1, TNode n2, std::vector< Node >&
return false;
}
+std::pair<bool, Node> TheoryDatatypes::entailmentCheck(TNode lit, const EntailmentCheckParameters* params, EntailmentCheckSideEffects* out) {
+ Trace("dt-entail") << "Check entailed : " << lit << std::endl;
+ Node atom = lit.getKind()==NOT ? lit[0] : lit;
+ bool pol = lit.getKind()!=NOT;
+ if( atom.getKind()==APPLY_TESTER ){
+ Node n = atom[0];
+ if( hasTerm( n ) ){
+ Node r = d_equalityEngine.getRepresentative( n );
+ EqcInfo * ei = getOrMakeEqcInfo( r, false );
+ int l_index = getLabelIndex( ei, r );
+ int t_index = (int)Datatype::indexOf( atom.getOperator().toExpr() );
+ Trace("dt-entail") << " Tester indices are " << t_index << " and " << l_index << std::endl;
+ if( l_index!=-1 && (l_index==t_index)==pol ){
+ std::vector< TNode > exp_c;
+ if( ei && !ei->d_constructor.get().isNull() ){
+ explainEquality( n, ei->d_constructor.get(), true, exp_c );
+ }else{
+ Node lbl = getLabel( n );
+ Assert( !lbl.isNull() );
+ exp_c.push_back( lbl );
+ Assert( areEqual( n, lbl[0] ) );
+ explainEquality( n, lbl[0], true, exp_c );
+ }
+ Node exp = mkAnd( exp_c );
+ Trace("dt-entail") << " entailed, explanation is " << exp << std::endl;
+ return make_pair(true, exp);
+ }
+ }
+ }else{
+
+ }
+ return make_pair(false, Node::null());
+}
+
} /* namepsace CVC4::theory::datatypes */
} /* namepsace CVC4::theory */
} /* namepsace CVC4 */
diff --git a/src/theory/datatypes/theory_datatypes.h b/src/theory/datatypes/theory_datatypes.h
index d56538b2a..4bf04e08c 100644
--- a/src/theory/datatypes/theory_datatypes.h
+++ b/src/theory/datatypes/theory_datatypes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_datatypes.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory of datatypes.
**
@@ -87,19 +87,19 @@ private:
d_dt.conflict(t1, t2);
}
void eqNotifyNewClass(TNode t) {
- Debug("dt") << "NotifyClass::eqNotifyNewClass(" << t << std::endl;
+ Debug("dt") << "NotifyClass::eqNotifyNewClass(" << t << ")" << std::endl;
d_dt.eqNotifyNewClass(t);
}
void eqNotifyPreMerge(TNode t1, TNode t2) {
- Debug("dt") << "NotifyClass::eqNotifyPreMerge(" << t1 << ", " << t2 << std::endl;
+ Debug("dt") << "NotifyClass::eqNotifyPreMerge(" << t1 << ", " << t2 << ")" << std::endl;
d_dt.eqNotifyPreMerge(t1, t2);
}
void eqNotifyPostMerge(TNode t1, TNode t2) {
- Debug("dt") << "NotifyClass::eqNotifyPostMerge(" << t1 << ", " << t2 << std::endl;
+ Debug("dt") << "NotifyClass::eqNotifyPostMerge(" << t1 << ", " << t2 << ")" << std::endl;
d_dt.eqNotifyPostMerge(t1, t2);
}
void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {
- Debug("dt") << "NotifyClass::eqNotifyDisequal(" << t1 << ", " << t2 << ", " << reason << std::endl;
+ Debug("dt") << "NotifyClass::eqNotifyDisequal(" << t1 << ", " << t2 << ", " << reason << ")" << std::endl;
d_dt.eqNotifyDisequal(t1, t2, reason);
}
};/* class TheoryDatatypes::NotifyClass */
@@ -131,9 +131,10 @@ private:
bool hasTester( Node n );
/** get the possible constructors for n */
void getPossibleCons( EqcInfo* eqc, Node n, std::vector< bool >& cons );
+ void getSelectorsForCons( Node r, std::map< int, bool >& sels );
/** mkExpDefSkolem */
- void mkExpDefSkolem( Node sel, TypeNode dt, TypeNode rt );
- /** skolems for terms */
+ void mkExpDefSkolem( Node sel, TypeNode dt, TypeNode rt );
+ /** skolems for terms */
NodeMap d_term_sk;
Node getTermSkolemFor( Node n );
private:
@@ -165,6 +166,7 @@ private:
context::CDO<bool> d_conflict;
/** Added lemma ? */
bool d_addedLemma;
+ bool d_addedFact;
/** The conflict node */
Node d_conflictNode;
/** cache for which terms we have called collectTerms(...) on */
@@ -181,7 +183,7 @@ private:
/** counter for forcing assignments (ensures fairness) */
unsigned d_dtfCounter;
/** expand definition skolem functions */
- std::map< Node, Node > d_exp_def_skolem;
+ std::map< TypeNode, std::map< Node, Node > > d_exp_def_skolem;
/** sygus utilities */
SygusSplit * d_sygus_split;
SygusSymBreak * d_sygus_sym_break;
@@ -260,6 +262,8 @@ public:
std::string identify() const { return std::string("TheoryDatatypes"); }
/** debug print */
void printModelDebug( const char* c );
+ /** entailment check */
+ virtual std::pair<bool, Node> entailmentCheck(TNode lit, const EntailmentCheckParameters* params = NULL, EntailmentCheckSideEffects* out = NULL);
private:
/** add tester to equivalence class info */
void addTester( int ttindex, Node t, EqcInfo* eqc, Node n, Node t_arg );
diff --git a/src/theory/datatypes/theory_datatypes_type_rules.h b/src/theory/datatypes/theory_datatypes_type_rules.h
index 477ce6ba5..5a3645691 100644
--- a/src/theory/datatypes/theory_datatypes_type_rules.h
+++ b/src/theory/datatypes/theory_datatypes_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_datatypes_type_rules.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory of datatypes
**
@@ -210,49 +210,6 @@ struct DatatypeAscriptionTypeRule {
}
};/* struct DatatypeAscriptionTypeRule */
-/* For co-datatypes */
-class DatatypeMuTypeRule {
-private:
- //a Mu-expression is constant iff its body is composed of constructors applied to constant expr and bound variables only
- inline static bool computeIsConstNode(TNode n, std::vector< TNode >& fv ){
- if( n.getKind()==kind::MU ){
- fv.push_back( n[0] );
- bool ret = computeIsConstNode( n[1], fv );
- fv.pop_back();
- return ret;
- }else if( n.isConst() || std::find( fv.begin(), fv.end(), n )!=fv.end() ){
- return true;
- }else if( n.getKind()==kind::APPLY_CONSTRUCTOR ){
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- if( !computeIsConstNode( n[i], fv ) ){
- return false;
- }
- }
- return true;
- }else{
- return false;
- }
- }
-public:
- inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) {
- if( n[0].getKind()!=kind::BOUND_VARIABLE ) {
- std::stringstream ss;
- ss << "expected a bound var for MU expression, got `"
- << n[0] << "'";
- throw TypeCheckingExceptionPrivate(n, ss.str());
- }
- return n[1].getType(check);
- }
- inline static bool computeIsConst(NodeManager* nodeManager, TNode n)
- throw(AssertionException) {
- Assert(n.getKind() == kind::MU);
- NodeManagerScope nms(nodeManager);
- std::vector< TNode > fv;
- return computeIsConstNode( n, fv );
- }
-};
-
-
struct ConstructorProperties {
inline static Cardinality computeCardinality(TypeNode type) {
// Constructors aren't exactly functions, they're like
@@ -276,7 +233,6 @@ struct TupleUpdateTypeRule {
if(check) {
if(!tupleType.isTuple()) {
throw TypeCheckingExceptionPrivate(n, "Tuple-update expression formed over non-tuple");
- tupleType = tupleType.getAttribute(expr::DatatypeTupleAttr());
}
if(tu.getIndex() >= tupleType.getTupleLength()) {
std::stringstream ss;
@@ -313,23 +269,6 @@ struct RecordUpdateTypeRule {
}
};/* struct RecordUpdateTypeRule */
-struct RecordProperties {
- inline static Node mkGroundTerm(TypeNode type) {
- Assert(type.getKind() == kind::RECORD_TYPE);
- return Node::null();
- }
- inline static bool computeIsConst(NodeManager* nodeManager, TNode n) {
- return true;
- }
- inline static Cardinality computeCardinality(TypeNode type) {
- Cardinality card(1);
- return card;
- }
- inline static bool isWellFounded(TypeNode type) {
- return true;
- }
-};/* struct RecordProperties */
-
class DtSizeTypeRule {
public:
inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
diff --git a/src/theory/datatypes/type_enumerator.cpp b/src/theory/datatypes/type_enumerator.cpp
index 77db1968a..6c1155237 100644
--- a/src/theory/datatypes/type_enumerator.cpp
+++ b/src/theory/datatypes/type_enumerator.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Enumerators for datatypes
**
diff --git a/src/theory/datatypes/type_enumerator.h b/src/theory/datatypes/type_enumerator.h
index 1f30498d6..bbfd951b3 100644
--- a/src/theory/datatypes/type_enumerator.h
+++ b/src/theory/datatypes/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An enumerator for datatypes
**
@@ -177,92 +177,6 @@ public:
};/* DatatypesEnumerator */
-
-class RecordEnumerator : public TypeEnumeratorBase<RecordEnumerator> {
- TypeEnumeratorProperties * d_tep;
- TypeEnumerator** d_enumerators;
-
- /** Allocate and initialize the delegate enumerators */
- void newEnumerators() {
- const Record& rec = getType().getConst<Record>();
- d_enumerators = new TypeEnumerator*[rec.getNumFields()];
- for(size_t i = 0; i < rec.getNumFields(); ++i) {
- d_enumerators[i] = new TypeEnumerator(TypeNode::fromType(rec[i].second));
- }
- }
-
- void deleteEnumerators() throw() {
- if(d_enumerators != NULL) {
- const Record& rec = getType().getConst<Record>();
- for(size_t i = 0; i < rec.getNumFields(); ++i) {
- delete d_enumerators[i];
- }
- delete [] d_enumerators;
- d_enumerators = NULL;
- }
- }
-
-public:
-
- RecordEnumerator(TypeNode type, TypeEnumeratorProperties * tep = NULL) throw() :
- TypeEnumeratorBase<RecordEnumerator>(type), d_tep(tep) {
- Assert(type.isRecord());
- newEnumerators();
- }
-
- RecordEnumerator(const RecordEnumerator& re) throw() :
- TypeEnumeratorBase<RecordEnumerator>(re.getType()),
- d_tep(re.d_tep),
- d_enumerators(NULL) {
-
- if(re.d_enumerators != NULL) {
- newEnumerators();
- for(size_t i = 0; i < getType().getNumChildren(); ++i) {
- *d_enumerators[i] = TypeEnumerator(*re.d_enumerators[i]);
- }
- }
- }
-
- virtual ~RecordEnumerator() throw() {
- deleteEnumerators();
- }
-
- Node operator*() throw(NoMoreValuesException) {
- if(isFinished()) {
- throw NoMoreValuesException(getType());
- }
-
-
- return Node::null();
- }
-
- RecordEnumerator& operator++() throw() {
- if(isFinished()) {
- return *this;
- }
-
- size_t i;
- const Record& rec = getType().getConst<Record>();
- for(i = 0; i < rec.getNumFields(); ++i) {
- if(d_enumerators[i]->isFinished()) {
- *d_enumerators[i] = TypeEnumerator(TypeNode::fromType(rec[i].second));
- } else {
- ++*d_enumerators[i];
- return *this;
- }
- }
-
- deleteEnumerators();
-
- return *this;
- }
-
- bool isFinished() throw() {
- return d_enumerators == NULL;
- }
-
-};/* RecordEnumerator */
-
}/* CVC4::theory::datatypes namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/example/ecdata.cpp b/src/theory/example/ecdata.cpp
index f9e3b53e7..a85db3cc9 100644
--- a/src/theory/example/ecdata.cpp
+++ b/src/theory/example/ecdata.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ecdata.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of equivalence class data for UF theory.
**
diff --git a/src/theory/example/ecdata.h b/src/theory/example/ecdata.h
index 3f4b1b97d..cd582c150 100644
--- a/src/theory/example/ecdata.h
+++ b/src/theory/example/ecdata.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ecdata.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Context dependent equivalence class datastructure for nodes.
**
diff --git a/src/theory/example/theory_uf_tim.cpp b/src/theory/example/theory_uf_tim.cpp
index 139a811b8..825c8fbe4 100644
--- a/src/theory/example/theory_uf_tim.cpp
+++ b/src/theory/example/theory_uf_tim.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_tim.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the theory of uninterpreted functions.
**
diff --git a/src/theory/example/theory_uf_tim.h b/src/theory/example/theory_uf_tim.h
index ef74a04f8..7470b4d57 100644
--- a/src/theory/example/theory_uf_tim.h
+++ b/src/theory/example/theory_uf_tim.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_tim.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is a basic implementation of the Theory of Uninterpreted Functions
** with Equality.
diff --git a/src/theory/fp/theory_fp.cpp b/src/theory/fp/theory_fp.cpp
index 18bf993ad..f3212277b 100644
--- a/src/theory/fp/theory_fp.cpp
+++ b/src/theory/fp/theory_fp.cpp
@@ -1,3 +1,20 @@
+/********************* */
+/*! \file theory_fp.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Martin Brain, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
+
#include "theory/fp/theory_fp.h"
using namespace std;
diff --git a/src/theory/fp/theory_fp.h b/src/theory/fp/theory_fp.h
index ac2c68ac4..b1915e3b7 100644
--- a/src/theory/fp/theory_fp.h
+++ b/src/theory/fp/theory_fp.h
@@ -1,3 +1,20 @@
+/********************* */
+/*! \file theory_fp.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Martin Brain, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
+
#include "cvc4_private.h"
#ifndef __CVC4__THEORY__FP__THEORY_FP_H
diff --git a/src/theory/fp/theory_fp_rewriter.cpp b/src/theory/fp/theory_fp_rewriter.cpp
index 59ff4692f..612112db7 100644
--- a/src/theory/fp/theory_fp_rewriter.cpp
+++ b/src/theory/fp/theory_fp_rewriter.cpp
@@ -1,13 +1,14 @@
/********************* */
/*! \file theory_fp_rewriter.cpp
** \verbatim
- ** Original author: Martin Brain
- ** Major contributors:
- ** Minor contributors (to current version):
- ** This file is part of the CVC4 project.
+ ** Top contributors (to current version):
+ ** Martin Brain, Tim King, Clark Barrett
** Copyright (c) 2013 University of Oxford
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Rewrite rules for floating point theories. ]]
**
diff --git a/src/theory/fp/theory_fp_rewriter.h b/src/theory/fp/theory_fp_rewriter.h
index 8a8f1c933..93547b4de 100644
--- a/src/theory/fp/theory_fp_rewriter.h
+++ b/src/theory/fp/theory_fp_rewriter.h
@@ -1,3 +1,20 @@
+/********************* */
+/*! \file theory_fp_rewriter.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Martin Brain
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
+
#include "cvc4_private.h"
#ifndef __CVC4__THEORY__FP__THEORY_FP_REWRITER_H
diff --git a/src/theory/fp/theory_fp_type_rules.h b/src/theory/fp/theory_fp_type_rules.h
index 2c9a67984..f9bf2e432 100644
--- a/src/theory/fp/theory_fp_type_rules.h
+++ b/src/theory/fp/theory_fp_type_rules.h
@@ -1,3 +1,20 @@
+/********************* */
+/*! \file theory_fp_type_rules.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Martin Brain
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief [[ Add one-line brief description here ]]
+ **
+ ** [[ Add lengthier description here ]]
+ ** \todo document this file
+ **/
+
#include "cvc4_private.h"
#ifndef __CVC4__THEORY__FP__THEORY_FP_TYPE_RULES_H
diff --git a/src/theory/idl/idl_assertion.cpp b/src/theory/idl/idl_assertion.cpp
index c6a1a5c0e..1d42f771d 100644
--- a/src/theory/idl/idl_assertion.cpp
+++ b/src/theory/idl/idl_assertion.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file idl_assertion.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/idl_assertion.h b/src/theory/idl/idl_assertion.h
index 9a31f283d..5db1db0fe 100644
--- a/src/theory/idl/idl_assertion.h
+++ b/src/theory/idl/idl_assertion.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file idl_assertion.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/idl_assertion_db.cpp b/src/theory/idl/idl_assertion_db.cpp
index f2c29cb20..c08cb644f 100644
--- a/src/theory/idl/idl_assertion_db.cpp
+++ b/src/theory/idl/idl_assertion_db.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file idl_assertion_db.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/idl_assertion_db.h b/src/theory/idl/idl_assertion_db.h
index 23f5e84d5..6481deba5 100644
--- a/src/theory/idl/idl_assertion_db.h
+++ b/src/theory/idl/idl_assertion_db.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file idl_assertion_db.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/idl_model.cpp b/src/theory/idl/idl_model.cpp
index 848399fbc..4d2071962 100644
--- a/src/theory/idl/idl_model.cpp
+++ b/src/theory/idl/idl_model.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file idl_model.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/idl_model.h b/src/theory/idl/idl_model.h
index 5a284457a..35663a256 100644
--- a/src/theory/idl/idl_model.h
+++ b/src/theory/idl/idl_model.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file idl_model.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/theory_idl.cpp b/src/theory/idl/theory_idl.cpp
index 815f5e76a..8f85dc9b0 100644
--- a/src/theory/idl/theory_idl.cpp
+++ b/src/theory/idl/theory_idl.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_idl.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/idl/theory_idl.h b/src/theory/idl/theory_idl.h
index 7c879e722..1d2aecad6 100644
--- a/src/theory/idl/theory_idl.h
+++ b/src/theory/idl/theory_idl.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_idl.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/interrupted.h b/src/theory/interrupted.h
index 6c59146e1..e56f3513c 100644
--- a/src/theory/interrupted.h
+++ b/src/theory/interrupted.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file interrupted.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An exception signaling that a Theory should immediately
** stop performing processing
diff --git a/src/theory/ite_utilities.cpp b/src/theory/ite_utilities.cpp
index 2791a9555..6fab100de 100644
--- a/src/theory/ite_utilities.cpp
+++ b/src/theory/ite_utilities.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ite_utilities.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simplifications for ITE expressions
**
@@ -657,6 +657,8 @@ ITESimplifier::NodeVec* ITESimplifier::computeConstantLeaves(TNode ite){
// special case 2 constant children
if(thenB.isConst() && elseB.isConst()){
NodeVec* pair = new NodeVec(2);
+ d_allocatedConstantLeaves.push_back(pair);
+
(*pair)[0] = std::min(thenB, elseB);
(*pair)[1] = std::max(thenB, elseB);
d_constantLeaves[ite] = pair;
@@ -694,6 +696,7 @@ ITESimplifier::NodeVec* ITESimplifier::computeConstantLeaves(TNode ite){
}
NodeVec* both = new NodeVec(defChildren->size()+maybeChildren->size());
+ d_allocatedConstantLeaves.push_back(both);
NodeVec::iterator newEnd;
newEnd = std::set_union(defChildren->begin(), defChildren->end(),
maybeChildren->begin(), maybeChildren->end(),
@@ -1399,25 +1402,32 @@ Node ITESimplifier::simpITE(TNode assertion)
}
ITECareSimplifier::ITECareSimplifier()
- : d_usedSets()
+ : d_careSetsOutstanding(0)
+ , d_usedSets()
{
d_true = NodeManager::currentNM()->mkConst<bool>(true);
d_false = NodeManager::currentNM()->mkConst<bool>(false);
}
-ITECareSimplifier::~ITECareSimplifier(){}
+ITECareSimplifier::~ITECareSimplifier(){
+ Assert(d_usedSets.empty());
+ Assert(d_careSetsOutstanding == 0);
+}
void ITECareSimplifier::clear(){
- d_usedSets.clear();
+ Assert(d_usedSets.empty());
+ Assert(d_careSetsOutstanding == 0);
}
ITECareSimplifier::CareSetPtr ITECareSimplifier::getNewSet()
{
if (d_usedSets.empty()) {
+ d_careSetsOutstanding++;
return ITECareSimplifier::CareSetPtr::mkNew(*this);
}
else {
- ITECareSimplifier::CareSetPtr cs = ITECareSimplifier::CareSetPtr::recycle(d_usedSets.back());
+ ITECareSimplifier::CareSetPtr cs =
+ ITECareSimplifier::CareSetPtr::recycle(d_usedSets.back());
cs.getCareSet().clear();
d_usedSets.pop_back();
return cs;
@@ -1488,125 +1498,144 @@ Node ITECareSimplifier::substitute(TNode e, TNodeMap& substTable, TNodeMap& cach
Node ITECareSimplifier::simplifyWithCare(TNode e)
{
TNodeMap substTable;
- CareMap queue;
- CareMap::iterator it;
- ITECareSimplifier::CareSetPtr cs = getNewSet();
- ITECareSimplifier::CareSetPtr cs2;
- queue[e] = cs;
-
- TNode v;
- bool done;
- unsigned i;
-
- while (!queue.empty()) {
- it = queue.end();
- --it;
- v = it->first;
- cs = it->second;
- set<Node>& css = cs.getCareSet();
- queue.erase(v);
-
- done = false;
- set<Node>::iterator iCare, iCareEnd = css.end();
-
- switch (v.getKind()) {
- case kind::ITE: {
- iCare = css.find(v[0]);
- if (iCare != iCareEnd) {
- Assert(substTable.find(v) == substTable.end());
- substTable[v] = v[1];
- updateQueue(queue, v[1], cs);
- done = true;
- break;
- }
- else {
- iCare = css.find(v[0].negate());
+
+ /* This extra block is to trigger the destructors for cs and cs2
+ * before starting garbage collection.
+ */
+ {
+ CareMap queue;
+ CareMap::iterator it;
+ ITECareSimplifier::CareSetPtr cs = getNewSet();
+ ITECareSimplifier::CareSetPtr cs2;
+ queue[e] = cs;
+
+ TNode v;
+ bool done;
+ unsigned i;
+
+ while (!queue.empty()) {
+ it = queue.end();
+ --it;
+ v = it->first;
+ cs = it->second;
+ set<Node>& css = cs.getCareSet();
+ queue.erase(v);
+
+ done = false;
+ set<Node>::iterator iCare, iCareEnd = css.end();
+
+ switch (v.getKind()) {
+ case kind::ITE: {
+ iCare = css.find(v[0]);
if (iCare != iCareEnd) {
Assert(substTable.find(v) == substTable.end());
- substTable[v] = v[2];
- updateQueue(queue, v[2], cs);
+ substTable[v] = v[1];
+ updateQueue(queue, v[1], cs);
done = true;
break;
}
- }
- updateQueue(queue, v[0], cs);
- cs2 = getNewSet();
- cs2.getCareSet() = css;
- cs2.getCareSet().insert(v[0]);
- updateQueue(queue, v[1], cs2);
- cs2 = getNewSet();
- cs2.getCareSet() = css;
- cs2.getCareSet().insert(v[0].negate());
- updateQueue(queue, v[2], cs2);
- done = true;
- break;
- }
- case kind::AND: {
- for (i = 0; i < v.getNumChildren(); ++i) {
- iCare = css.find(v[i].negate());
- if (iCare != iCareEnd) {
- Assert(substTable.find(v) == substTable.end());
- substTable[v] = d_false;
- done = true;
- break;
+ else {
+ iCare = css.find(v[0].negate());
+ if (iCare != iCareEnd) {
+ Assert(substTable.find(v) == substTable.end());
+ substTable[v] = v[2];
+ updateQueue(queue, v[2], cs);
+ done = true;
+ break;
+ }
}
+ updateQueue(queue, v[0], cs);
+ cs2 = getNewSet();
+ cs2.getCareSet() = css;
+ cs2.getCareSet().insert(v[0]);
+ updateQueue(queue, v[1], cs2);
+ cs2 = getNewSet();
+ cs2.getCareSet() = css;
+ cs2.getCareSet().insert(v[0].negate());
+ updateQueue(queue, v[2], cs2);
+ done = true;
+ break;
}
- if (done) break;
-
- Assert(v.getNumChildren() > 1);
- updateQueue(queue, v[0], cs);
- cs2 = getNewSet();
- cs2.getCareSet() = css;
- cs2.getCareSet().insert(v[0]);
- for (i = 1; i < v.getNumChildren(); ++i) {
- updateQueue(queue, v[i], cs2);
- }
- done = true;
- break;
- }
- case kind::OR: {
- for (i = 0; i < v.getNumChildren(); ++i) {
- iCare = css.find(v[i]);
- if (iCare != iCareEnd) {
- Assert(substTable.find(v) == substTable.end());
- substTable[v] = d_true;
- done = true;
- break;
+ case kind::AND: {
+ for (i = 0; i < v.getNumChildren(); ++i) {
+ iCare = css.find(v[i].negate());
+ if (iCare != iCareEnd) {
+ Assert(substTable.find(v) == substTable.end());
+ substTable[v] = d_false;
+ done = true;
+ break;
+ }
+ }
+ if (done) break;
+
+ Assert(v.getNumChildren() > 1);
+ updateQueue(queue, v[0], cs);
+ cs2 = getNewSet();
+ cs2.getCareSet() = css;
+ cs2.getCareSet().insert(v[0]);
+ for (i = 1; i < v.getNumChildren(); ++i) {
+ updateQueue(queue, v[i], cs2);
}
+ done = true;
+ break;
}
- if (done) break;
-
- Assert(v.getNumChildren() > 1);
- updateQueue(queue, v[0], cs);
- cs2 = getNewSet();
- cs2.getCareSet() = css;
- cs2.getCareSet().insert(v[0].negate());
- for (i = 1; i < v.getNumChildren(); ++i) {
- updateQueue(queue, v[i], cs2);
+ case kind::OR: {
+ for (i = 0; i < v.getNumChildren(); ++i) {
+ iCare = css.find(v[i]);
+ if (iCare != iCareEnd) {
+ Assert(substTable.find(v) == substTable.end());
+ substTable[v] = d_true;
+ done = true;
+ break;
+ }
+ }
+ if (done) break;
+
+ Assert(v.getNumChildren() > 1);
+ updateQueue(queue, v[0], cs);
+ cs2 = getNewSet();
+ cs2.getCareSet() = css;
+ cs2.getCareSet().insert(v[0].negate());
+ for (i = 1; i < v.getNumChildren(); ++i) {
+ updateQueue(queue, v[i], cs2);
+ }
+ done = true;
+ break;
}
- done = true;
- break;
+ default:
+ break;
}
- default:
- break;
- }
- if (done) {
- continue;
- }
+ if (done) {
+ continue;
+ }
- for (unsigned i = 0; i < v.getNumChildren(); ++i) {
- updateQueue(queue, v[i], cs);
+ for (unsigned i = 0; i < v.getNumChildren(); ++i) {
+ updateQueue(queue, v[i], cs);
+ }
}
}
+ /* Perform garbage collection. */
while (!d_usedSets.empty()) {
- delete d_usedSets.back();
+ CareSetPtrVal* used = d_usedSets.back();
d_usedSets.pop_back();
+ Assert(used->safeToGarbageCollect());
+ delete used;
+ Assert(d_careSetsOutstanding > 0);
+ d_careSetsOutstanding--;
}
TNodeMap cache;
return substitute(e, substTable, cache);
}
+ITECareSimplifier::CareSetPtr ITECareSimplifier::CareSetPtr::mkNew(
+ ITECareSimplifier& simp) {
+ CareSetPtrVal* val = new CareSetPtrVal(simp);
+ return CareSetPtr(val);
+}
+
+
+
} /* namespace theory */
} /* namespace CVC4 */
diff --git a/src/theory/ite_utilities.h b/src/theory/ite_utilities.h
index 10fe2853b..98141d4e3 100644
--- a/src/theory/ite_utilities.h
+++ b/src/theory/ite_utilities.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ite_utilities.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simplifications for ITE expressions
**
@@ -133,7 +133,7 @@ public:
private:
typedef std::hash_map<Node, uint32_t, NodeHashFunction> NodeCountMap;
NodeCountMap d_termITEHeight;
-};
+}; /* class TermITEHeightCounter */
/**
* A routine designed to undo the potentially large blow up
@@ -177,7 +177,7 @@ private:
~Statistics();
};
Statistics d_statistics;
-};
+}; /* class ITECompressor */
class ITESimplifier {
public:
@@ -302,6 +302,15 @@ public:
void clear();
private:
+
+ /**
+ * This should always equal the number of care sets allocated by
+ * this object - the number of these that have been deleted. This is
+ * initially 0 and should always be 0 at the *start* of
+ * ~ITECareSimplifier().
+ */
+ unsigned d_careSetsOutstanding;
+
Node d_true;
Node d_false;
@@ -309,12 +318,16 @@ private:
class CareSetPtr;
class CareSetPtrVal {
+ public:
+ bool safeToGarbageCollect() const { return d_refCount == 0; }
+ private:
friend class ITECareSimplifier::CareSetPtr;
ITECareSimplifier& d_iteSimplifier;
unsigned d_refCount;
std::set<Node> d_careSet;
- CareSetPtrVal(ITECareSimplifier& simp) : d_iteSimplifier(simp), d_refCount(1) {}
- };
+ CareSetPtrVal(ITECareSimplifier& simp)
+ : d_iteSimplifier(simp), d_refCount(1) {}
+ }; /* class ITECareSimplifier::CareSetPtrVal */
std::vector<CareSetPtrVal*> d_usedSets;
void careSetPtrGC(CareSetPtrVal* val) {
@@ -350,16 +363,14 @@ private:
return *this;
}
std::set<Node>& getCareSet() { return d_val->d_careSet; }
- static CareSetPtr mkNew(ITECareSimplifier& simp) {
- CareSetPtrVal* val = new CareSetPtrVal(simp);
- return CareSetPtr(val);
- }
+
+ static CareSetPtr mkNew(ITECareSimplifier& simp);
static CareSetPtr recycle(CareSetPtrVal* val) {
Assert(val != NULL && val->d_refCount == 0);
val->d_refCount = 1;
return CareSetPtr(val);
}
- };
+ }; /* class ITECareSimplifier::CareSetPtr */
CareSetPtr getNewSet();
diff --git a/src/theory/logic_info.cpp b/src/theory/logic_info.cpp
index fb689609d..04cac7ae5 100644
--- a/src/theory/logic_info.cpp
+++ b/src/theory/logic_info.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file logic_info.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Tianyi Liang, Kshitij Bansal, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class giving information about a logic (group a theory modules
** and configuration information)
diff --git a/src/theory/logic_info.h b/src/theory/logic_info.h
index 6d7297c63..6efdd4615 100644
--- a/src/theory/logic_info.h
+++ b/src/theory/logic_info.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file logic_info.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A class giving information about a logic (group a theory modules
** and configuration information)
diff --git a/src/theory/output_channel.h b/src/theory/output_channel.h
index d5c12457a..639793c7f 100644
--- a/src/theory/output_channel.h
+++ b/src/theory/output_channel.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file output_channel.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds, Dejan Jovanovic, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The theory output channel interface
**
@@ -142,7 +142,6 @@ public:
return lemma(n, RULE_INVALID, removable, preprocess, sendAtoms);
}
-
/**
* Request a split on a new theory atom. This is equivalent to
* calling lemma({OR n (NOT n)}).
diff --git a/src/theory/quantifiers/alpha_equivalence.cpp b/src/theory/quantifiers/alpha_equivalence.cpp
index b72f15a01..80066d690 100644
--- a/src/theory/quantifiers/alpha_equivalence.cpp
+++ b/src/theory/quantifiers/alpha_equivalence.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file alpha_equivalence.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Alpha equivalence checking
**
@@ -29,7 +29,7 @@ struct sortTypeOrder {
}
};
-bool AlphaEquivalenceNode::registerNode( AlphaEquivalenceNode* aen, QuantifiersEngine* qe, Node q, std::vector< Node >& tt, std::vector< int >& arg_index ) {
+Node AlphaEquivalenceNode::registerNode( AlphaEquivalenceNode* aen, QuantifiersEngine* qe, Node q, std::vector< Node >& tt, std::vector< int >& arg_index ) {
while( !tt.empty() ){
if( tt.size()==arg_index.size()+1 ){
Node t = tt.back();
@@ -49,21 +49,25 @@ bool AlphaEquivalenceNode::registerNode( AlphaEquivalenceNode* aen, QuantifiersE
}
}
}
+ Node lem;
Trace("aeq-debug") << std::endl;
if( aen->d_quant.isNull() ){
aen->d_quant = q;
- return true;
}else{
- //lemma ( q <=> d_quant )
- Trace("quant-ae") << "Alpha equivalent : " << std::endl;
- Trace("quant-ae") << " " << q << std::endl;
- Trace("quant-ae") << " " << aen->d_quant << std::endl;
- qe->getOutputChannel().lemma( q.iffNode( aen->d_quant ) );
- return false;
+ if( q.getNumChildren()==2 ){
+ //lemma ( q <=> d_quant )
+ Trace("quant-ae") << "Alpha equivalent : " << std::endl;
+ Trace("quant-ae") << " " << q << std::endl;
+ Trace("quant-ae") << " " << aen->d_quant << std::endl;
+ lem = q.iffNode( aen->d_quant );
+ }else{
+ //do not reduce annotated quantified formulas based on alpha equivalence
+ }
}
+ return lem;
}
-bool AlphaEquivalenceTypeNode::registerNode( AlphaEquivalenceTypeNode* aetn,
+Node AlphaEquivalenceTypeNode::registerNode( AlphaEquivalenceTypeNode* aetn,
QuantifiersEngine* qe, Node q, Node t, std::vector< TypeNode >& typs, std::map< TypeNode, int >& typ_count, int index ){
while( index<(int)typs.size() ){
TypeNode curr = typs[index];
@@ -79,7 +83,7 @@ bool AlphaEquivalenceTypeNode::registerNode( AlphaEquivalenceTypeNode* aetn,
return AlphaEquivalenceNode::registerNode( &(aetn->d_data), qe, q, tt, arg_index );
}
-bool AlphaEquivalence::registerQuantifier( Node q ) {
+Node AlphaEquivalence::reduceQuantifier( Node q ) {
Assert( q.getKind()==FORALL );
Trace("aeq") << "Alpha equivalence : register " << q << std::endl;
//construct canonical quantified formula
@@ -99,7 +103,7 @@ bool AlphaEquivalence::registerQuantifier( Node q ) {
sto.d_tdb = d_qe->getTermDatabase();
std::sort( typs.begin(), typs.end(), sto );
Trace("aeq-debug") << " ";
- bool ret = AlphaEquivalenceTypeNode::registerNode( &d_ae_typ_trie, d_qe, q, t, typs, typ_count );
+ Node ret = AlphaEquivalenceTypeNode::registerNode( &d_ae_typ_trie, d_qe, q, t, typs, typ_count );
Trace("aeq") << " ...result : " << ret << std::endl;
return ret;
}
diff --git a/src/theory/quantifiers/alpha_equivalence.h b/src/theory/quantifiers/alpha_equivalence.h
index 99517fd2a..8e7556eb6 100644
--- a/src/theory/quantifiers/alpha_equivalence.h
+++ b/src/theory/quantifiers/alpha_equivalence.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file alpha_equivalence.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Alpha equivalence checking
**/
@@ -28,14 +28,14 @@ class AlphaEquivalenceNode {
public:
std::map< Node, std::map< int, AlphaEquivalenceNode > > d_children;
Node d_quant;
- static bool registerNode( AlphaEquivalenceNode* aen, QuantifiersEngine* qe, Node q, std::vector< Node >& tt, std::vector< int >& arg_index );
+ static Node registerNode( AlphaEquivalenceNode* aen, QuantifiersEngine* qe, Node q, std::vector< Node >& tt, std::vector< int >& arg_index );
};
class AlphaEquivalenceTypeNode {
public:
std::map< TypeNode, std::map< int, AlphaEquivalenceTypeNode > > d_children;
AlphaEquivalenceNode d_data;
- static bool registerNode( AlphaEquivalenceTypeNode* aetn,
+ static Node registerNode( AlphaEquivalenceTypeNode* aetn,
QuantifiersEngine* qe, Node q, Node t, std::vector< TypeNode >& typs, std::map< TypeNode, int >& typ_count, int index = 0 );
};
@@ -47,8 +47,8 @@ private:
public:
AlphaEquivalence( QuantifiersEngine* qe ) : d_qe( qe ){}
~AlphaEquivalence(){}
-
- bool registerQuantifier( Node q );
+ /** reduce quantifier, return value (if non-null) is lemma justifying why q ia reducible. */
+ Node reduceQuantifier( Node q );
};
}
diff --git a/src/theory/quantifiers/ambqi_builder.cpp b/src/theory/quantifiers/ambqi_builder.cpp
index b18676cbc..5192da7de 100644
--- a/src/theory/quantifiers/ambqi_builder.cpp
+++ b/src/theory/quantifiers/ambqi_builder.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ambqi_builder.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of abstract MBQI builder
**/
@@ -159,7 +159,7 @@ bool AbsDef::addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe,
return true;
}else{
if( depth==q[0].getNumChildren() ){
- if( qe->addInstantiation( q, terms ) ){
+ if( qe->addInstantiation( q, terms, true ) ){
Trace("ambqi-inst-debug") << "-> Added instantiation." << std::endl;
inst++;
return true;
@@ -190,7 +190,7 @@ bool AbsDef::addInstantiations( FirstOrderModelAbs * m, QuantifiersEngine * qe,
success = true;
}
}
- }while( !success && index<32 );
+ }while( !qe->inConflict() && !success && index<32 );
//mark if we are incomplete
osuccess = osuccess && success;
}
diff --git a/src/theory/quantifiers/ambqi_builder.h b/src/theory/quantifiers/ambqi_builder.h
index b2c49c8a3..3669d38b7 100644
--- a/src/theory/quantifiers/ambqi_builder.h
+++ b/src/theory/quantifiers/ambqi_builder.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ambqi_builder.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Abstract MBQI model builder class
**/
diff --git a/src/theory/quantifiers/anti_skolem.cpp b/src/theory/quantifiers/anti_skolem.cpp
new file mode 100644
index 000000000..c8d18aced
--- /dev/null
+++ b/src/theory/quantifiers/anti_skolem.cpp
@@ -0,0 +1,269 @@
+/********************* */
+/*! \file anti_skolem.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Implementation of anti-skolemization
+ ** ( forall x. P[ f( x ) ] ^ forall x. Q[ f( x ) ] ) => forall x. exists y. ( P[ y ] ^ Q[ y ] )
+ **/
+
+#include "theory/quantifiers/anti_skolem.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/quantifiers/first_order_model.h"
+#include "options/quantifiers_options.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+
+
+struct sortTypeOrder {
+ TermDb* d_tdb;
+ bool operator() (TypeNode i, TypeNode j) {
+ return d_tdb->getIdForType( i )<d_tdb->getIdForType( j );
+ }
+};
+
+void QuantAntiSkolem::SkQuantTypeCache::add( std::vector< TypeNode >& typs, Node q, unsigned index ) {
+ if( index==typs.size() ){
+ Assert( std::find( d_quants.begin(), d_quants.end(), q )==d_quants.end() );
+ d_quants.push_back( q );
+ }else{
+ d_children[typs[index]].add( typs, q, index+1 );
+ }
+}
+
+void QuantAntiSkolem::SkQuantTypeCache::sendLemmas( QuantAntiSkolem * ask ) {
+ for( std::map< TypeNode, SkQuantTypeCache >::iterator it = d_children.begin(); it != d_children.end(); ++it ){
+ it->second.sendLemmas( ask );
+ }
+ if( !d_quants.empty() ){
+ ask->sendAntiSkolemizeLemma( d_quants );
+ }
+}
+
+bool QuantAntiSkolem::CDSkQuantCache::add( context::Context* c, std::vector< Node >& quants, unsigned index ) {
+ if( index==quants.size() ){
+ if( !d_valid.get() ){
+ d_valid.set( true );
+ return true;
+ }else{
+ return false;
+ }
+ }else{
+ Node n = quants[index];
+ std::map< Node, CDSkQuantCache* >::iterator it = d_data.find( n );
+ CDSkQuantCache* skc;
+ if( it==d_data.end() ){
+ skc = new CDSkQuantCache( c );
+ d_data[n] = skc;
+ }else{
+ skc = it->second;
+ }
+ return skc->add( c, quants, index+1 );
+ }
+}
+
+QuantAntiSkolem::QuantAntiSkolem( QuantifiersEngine * qe ) : QuantifiersModule( qe ){
+ d_sqc = new CDSkQuantCache( qe->getUserContext() );
+}
+
+/* Call during quantifier engine's check */
+void QuantAntiSkolem::check( Theory::Effort e, unsigned quant_e ) {
+ if( quant_e==QuantifiersEngine::QEFFORT_STANDARD ){
+ d_sqtc.clear();
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
+ if( d_quant_processed.find( q )==d_quant_processed.end() ){
+ d_quant_processed[q] = true;
+ Trace("anti-sk") << "Process quantified formula : " << q << std::endl;
+ bool success = false;
+ if( d_quant_sip[q].init( q[1] ) ){
+ Trace("anti-sk") << "- Partitioned to single invocation parts : " << std::endl;
+ d_quant_sip[q].debugPrint( "anti-sk" );
+ //check if it is single invocation
+ if( d_quant_sip[q].isPurelySingleInvocation() ){
+ //for now, only do purely single invocation
+ success = true;
+ }
+ }else{
+ Trace("anti-sk") << "- Failed to initialize." << std::endl;
+ }
+ if( success ){
+ //sort the argument variables
+ d_ask_types[q].insert( d_ask_types[q].end(), d_quant_sip[q].d_arg_types.begin(), d_quant_sip[q].d_arg_types.end() );
+ std::map< TypeNode, std::vector< unsigned > > indices;
+ for( unsigned j=0; j<d_ask_types[q].size(); j++ ){
+ indices[d_ask_types[q][j]].push_back( j );
+ }
+ sortTypeOrder sto;
+ sto.d_tdb = d_quantEngine->getTermDatabase();
+ std::sort( d_ask_types[q].begin(), d_ask_types[q].end(), sto );
+ //increment j on inner loop
+ for( unsigned j=0; j<d_ask_types[q].size(); ){
+ TypeNode curr = d_ask_types[q][j];
+ for( unsigned k=0; k<indices[curr].size(); k++ ){
+ Assert( d_ask_types[q][j]==curr );
+ d_ask_types_index[q].push_back( indices[curr][k] );
+ j++;
+ }
+ }
+ Assert( d_ask_types_index[q].size()==d_ask_types[q].size() );
+ }else{
+ d_quant_sip.erase( q );
+ }
+ }
+ //now, activate the quantified formula
+ std::map< Node, std::vector< TypeNode > >::iterator it = d_ask_types.find( q );
+ if( it!=d_ask_types.end() ){
+ d_sqtc.add( it->second, q );
+ }
+ }
+ Trace("anti-sk-debug") << "Process lemmas..." << std::endl;
+ //send out lemmas for each anti-skolemizable group of quantified formulas
+ d_sqtc.sendLemmas( this );
+ Trace("anti-sk-debug") << "...Finished process lemmas" << std::endl;
+ }
+}
+
+bool QuantAntiSkolem::sendAntiSkolemizeLemma( std::vector< Node >& quants, bool pconnected ) {
+ Assert( !quants.empty() );
+ std::sort( quants.begin(), quants.end() );
+ if( d_sqc->add( d_quantEngine->getUserContext(), quants ) ){
+ //partition into connected components
+ if( pconnected && quants.size()>1 ){
+ Trace("anti-sk-debug") << "Partition into connected components..." << std::endl;
+ int eqc_count = 0;
+ std::map< Node, int > func_to_eqc;
+ std::map< int, std::vector< Node > > eqc_to_func;
+ std::map< int, std::vector< Node > > eqc_to_quant;
+ for( unsigned i=0; i<quants.size(); i++ ){
+ Node q = quants[i];
+ std::vector< int > eqcs;
+ for( std::map< Node, bool >::iterator it = d_quant_sip[q].d_funcs.begin(); it != d_quant_sip[q].d_funcs.end(); ++it ){
+ Node f = it->first;
+ std::map< Node, int >::iterator itf = func_to_eqc.find( f );
+ if( itf == func_to_eqc.end() ){
+ if( eqcs.empty() ){
+ func_to_eqc[f] = eqc_count;
+ eqc_to_func[eqc_count].push_back( f );
+ eqc_count++;
+ }else{
+ func_to_eqc[f] = eqcs[0];
+ eqc_to_func[eqcs[0]].push_back( f );
+ }
+ }
+ if( std::find( eqcs.begin(), eqcs.end(), func_to_eqc[f] )==eqcs.end() ){
+ eqcs.push_back( func_to_eqc[f] );
+ }
+ }
+ Assert( !eqcs.empty() );
+ //merge equivalence classes
+ int id = eqcs[0];
+ eqc_to_quant[id].push_back( q );
+ for( unsigned j=1; j<eqcs.size(); j++ ){
+ int id2 = eqcs[j];
+ std::map< int, std::vector< Node > >::iterator itef = eqc_to_func.find( id2 );
+ if( itef!=eqc_to_func.end() ){
+ for( unsigned k=0; k<itef->second.size(); k++ ){
+ func_to_eqc[itef->second[k]] = id;
+ eqc_to_func[id].push_back( itef->second[k] );
+ }
+ eqc_to_func.erase( id2 );
+ }
+ itef = eqc_to_quant.find( id2 );
+ if( itef!=eqc_to_quant.end() ){
+ eqc_to_quant[id].insert( eqc_to_quant[id].end(), itef->second.begin(), itef->second.end() );
+ eqc_to_quant.erase( id2 );
+ }
+ }
+ }
+ if( eqc_to_quant.size()>1 ){
+ bool addedLemma = false;
+ for( std::map< int, std::vector< Node > >::iterator it = eqc_to_quant.begin(); it != eqc_to_quant.end(); ++it ){
+ Assert( it->second.size()<quants.size() );
+ bool ret = sendAntiSkolemizeLemma( it->second, false );
+ addedLemma = addedLemma || ret;
+ }
+ return addedLemma;
+ }
+ }
+
+ Trace("anti-sk") << "Anti-skolemize group : " << std::endl;
+ for( unsigned i=0; i<quants.size(); i++ ){
+ Trace("anti-sk") << " " << quants[i] << std::endl;
+ }
+
+ std::vector< Node > outer_vars;
+ std::vector< Node > inner_vars;
+ Node q = quants[0];
+ for( unsigned i=0; i<d_ask_types[q].size(); i++ ){
+ Node v = NodeManager::currentNM()->mkBoundVar( d_ask_types[q][i] );
+ Trace("anti-sk-debug") << "Outer var " << i << " : " << v << std::endl;
+ outer_vars.push_back( v );
+ }
+
+ std::map< Node, Node > func_to_var;
+ std::vector< Node > conj;
+ for( unsigned i=0; i<quants.size(); i++ ){
+ Node q = quants[i];
+ Trace("anti-sk-debug") << "Process " << q << std::endl;
+ std::vector< Node > subs_lhs;
+ std::vector< Node > subs_rhs;
+ //get outer variable substitution
+ Assert( d_ask_types_index[q].size()==d_ask_types[q].size() );
+ for( unsigned j=0; j<d_ask_types_index[q].size(); j++ ){
+ Trace("anti-sk-debug") << " o_subs : " << d_quant_sip[q].d_si_vars[d_ask_types_index[q][j]] << " -> " << outer_vars[j] << std::endl;
+ subs_lhs.push_back( d_quant_sip[q].d_si_vars[d_ask_types_index[q][j]] );
+ subs_rhs.push_back( outer_vars[j] );
+ }
+ //get function substitution
+ for( std::map< Node, bool >::iterator it = d_quant_sip[q].d_funcs.begin(); it != d_quant_sip[q].d_funcs.end(); ++it ){
+ Node f = it->first;
+ Node fv = d_quant_sip[q].d_func_fo_var[it->first];
+ if( func_to_var.find( f )==func_to_var.end() ){
+ Node v = NodeManager::currentNM()->mkBoundVar( fv.getType() );
+ Trace("anti-sk-debug") << "Inner var for " << f << " : " << v << std::endl;
+ inner_vars.push_back( v );
+ func_to_var[f] = v;
+ }
+ subs_lhs.push_back( fv );
+ subs_rhs.push_back( func_to_var[f] );
+ Trace("anti-sk-debug") << " i_subs : " << fv << " -> " << func_to_var[f] << std::endl;
+ }
+ Node c = d_quant_sip[q].getSingleInvocation();
+ if( !subs_lhs.empty() ){
+ c = c.substitute( subs_lhs.begin(), subs_lhs.end(), subs_rhs.begin(), subs_rhs.end() );
+ }
+ conj.push_back( c );
+ }
+ Node body = conj.size()==1 ? conj[0] : NodeManager::currentNM()->mkNode( kind::AND, conj );
+ if( !inner_vars.empty() ){
+ Node bvl = NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, inner_vars );
+ body = NodeManager::currentNM()->mkNode( kind::EXISTS, bvl, body );
+ }
+ if( !outer_vars.empty() ){
+ Node bvl = NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, outer_vars );
+ body = NodeManager::currentNM()->mkNode( kind::FORALL, bvl, body );
+ }
+ Trace("anti-sk") << "Produced : " << body << std::endl;
+ quants.push_back( body.negate() );
+ Node lem = NodeManager::currentNM()->mkNode( kind::AND, quants ).negate();
+ Trace("anti-sk-lemma") << "Anti-skolemize lemma : " << lem << std::endl;
+ quants.pop_back();
+ return d_quantEngine->addLemma( lem );
+ }else{
+ return false;
+ }
+}
+
diff --git a/src/theory/quantifiers/anti_skolem.h b/src/theory/quantifiers/anti_skolem.h
new file mode 100644
index 000000000..721371159
--- /dev/null
+++ b/src/theory/quantifiers/anti_skolem.h
@@ -0,0 +1,75 @@
+/********************* */
+/*! \file anti_skolem.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief dynamic quantifiers splitting
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANT_ANTI_SKOLEM_H
+#define __CVC4__THEORY__QUANT_ANTI_SKOLEM_H
+
+#include "theory/quantifiers_engine.h"
+#include "context/cdo.h"
+#include "theory/quantifiers/ce_guided_single_inv.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class QuantAntiSkolem : public QuantifiersModule {
+ typedef context::CDHashSet<Node, NodeHashFunction> NodeSet;
+private:
+ std::map< Node, bool > d_quant_processed;
+ std::map< Node, SingleInvocationPartition > d_quant_sip;
+ std::map< Node, std::vector< TypeNode > > d_ask_types;
+ std::map< Node, std::vector< unsigned > > d_ask_types_index;
+
+ class SkQuantTypeCache {
+ public:
+ std::map< TypeNode, SkQuantTypeCache > d_children;
+ std::vector< Node > d_quants;
+ void add( std::vector< TypeNode >& typs, Node q, unsigned index = 0 );
+ void clear() {
+ d_children.clear();
+ d_quants.clear();
+ }
+ void sendLemmas( QuantAntiSkolem * ask );
+ };
+ SkQuantTypeCache d_sqtc;
+
+ class CDSkQuantCache {
+ public:
+ CDSkQuantCache( context::Context* c ) : d_valid( c, false ){}
+ std::map< Node, CDSkQuantCache* > d_data;
+ context::CDO< bool > d_valid;
+ bool add( context::Context* c, std::vector< Node >& quants, unsigned index = 0 );
+ };
+ CDSkQuantCache * d_sqc;
+public:
+ bool sendAntiSkolemizeLemma( std::vector< Node >& quants, bool pconnected = true );
+public:
+ QuantAntiSkolem( QuantifiersEngine * qe );
+
+ /* Call during quantifier engine's check */
+ void check( Theory::Effort e, unsigned quant_e );
+ /* Called for new quantifiers */
+ void registerQuantifier( Node q ) {}
+ void assertNode( Node n ) {}
+ /** Identify this module (for debugging, dynamic configuration, etc..) */
+ std::string identify() const { return "QuantAntiSkolem"; }
+};
+
+}
+}
+}
+
+#endif
diff --git a/src/theory/quantifiers/bounded_integers.cpp b/src/theory/quantifiers/bounded_integers.cpp
index ceab8394f..d32ef59a1 100644
--- a/src/theory/quantifiers/bounded_integers.cpp
+++ b/src/theory/quantifiers/bounded_integers.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file bounded_integers.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Bounded integers module
**
diff --git a/src/theory/quantifiers/bounded_integers.h b/src/theory/quantifiers/bounded_integers.h
index dd241b15e..7d15097bd 100644
--- a/src/theory/quantifiers/bounded_integers.h
+++ b/src/theory/quantifiers/bounded_integers.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bounded_integers.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/quantifiers/candidate_generator.cpp b/src/theory/quantifiers/candidate_generator.cpp
index 0cdb22be4..43f5ee2fd 100644
--- a/src/theory/quantifiers/candidate_generator.cpp
+++ b/src/theory/quantifiers/candidate_generator.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file candidate_generator.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of theory uf candidate generator class
**/
@@ -58,10 +58,13 @@ Node CandidateGeneratorQueue::getNextCandidate(){
}
}
-CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node op ) :
- d_op( op ), d_qe( qe ), d_term_iter( -1 ){
+CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node pat ) :
+ d_qe( qe ), d_term_iter( -1 ){
+ d_op = qe->getTermDatabase()->getMatchOperator( pat );
Assert( !d_op.isNull() );
+ d_op_arity = pat.getNumChildren();
}
+
void CandidateGeneratorQE::resetInstantiationRound(){
d_term_iter_limit = d_qe->getTermDatabase()->getNumGroundTerms( d_op );
}
@@ -71,26 +74,38 @@ void CandidateGeneratorQE::reset( Node eqc ){
if( eqc.isNull() ){
d_mode = cand_term_db;
}else{
- //create an equivalence class iterator in eq class eqc
- //d_qe->getEqualityQuery()->getEquivalenceClass( eqc, d_eqc );
-
- eq::EqualityEngine* ee = d_qe->getEqualityQuery()->getEngine();
- if( ee->hasTerm( eqc ) ){
- Node rep = ee->getRepresentative( eqc );
- d_eqc_iter = eq::EqClassIterator( rep, ee );
- d_mode = cand_term_eqc;
+ if( isExcludedEqc( eqc ) ){
+ d_mode = cand_term_none;
}else{
- d_n = eqc;
- d_mode = cand_term_ident;
+ eq::EqualityEngine* ee = d_qe->getEqualityQuery()->getEngine();
+ if( ee->hasTerm( eqc ) ){
+ quantifiers::TermArgTrie * tat = d_qe->getTermDatabase()->getTermArgTrie( eqc, d_op );
+ if( tat ){
+#if 1
+ //create an equivalence class iterator in eq class eqc
+ Node rep = ee->getRepresentative( eqc );
+ d_eqc_iter = eq::EqClassIterator( rep, ee );
+ d_mode = cand_term_eqc;
+#else
+ d_tindex.push_back( tat );
+ d_tindex_iter.push_back( tat->d_data.begin() );
+ d_mode = cand_term_tindex;
+#endif
+ }else{
+ d_mode = cand_term_none;
+ }
+ }else{
+ //the only match is this term itself
+ d_n = eqc;
+ d_mode = cand_term_ident;
+ }
}
- //a should be in its equivalence class
- //Assert( std::find( eqc.begin(), eqc.end(), a )!=eqc.end() );
}
}
bool CandidateGeneratorQE::isLegalOpCandidate( Node n ) {
if( n.hasOperator() ){
if( isLegalCandidate( n ) ){
- return d_qe->getTermDatabase()->getOperator( n )==d_op;
+ return d_qe->getTermDatabase()->getMatchOperator( n )==d_op;
}
}
return false;
@@ -98,25 +113,67 @@ bool CandidateGeneratorQE::isLegalOpCandidate( Node n ) {
Node CandidateGeneratorQE::getNextCandidate(){
if( d_mode==cand_term_db ){
+ Debug("cand-gen-qe") << "...get next candidate in tbd" << std::endl;
//get next candidate term in the uf term database
while( d_term_iter<d_term_iter_limit ){
Node n = d_qe->getTermDatabase()->getGroundTerm( d_op, d_term_iter );
d_term_iter++;
if( isLegalCandidate( n ) ){
if( d_qe->getTermDatabase()->hasTermCurrent( n ) ){
- return n;
+ if( d_exclude_eqc.empty() ){
+ return n;
+ }else{
+ Node r = d_qe->getEqualityQuery()->getRepresentative( n );
+ if( d_exclude_eqc.find( r )==d_exclude_eqc.end() ){
+ Debug("cand-gen-qe") << "...returning " << n << std::endl;
+ return n;
+ }
+ }
}
}
}
}else if( d_mode==cand_term_eqc ){
+ Debug("cand-gen-qe") << "...get next candidate in eqc" << std::endl;
while( !d_eqc_iter.isFinished() ){
Node n = *d_eqc_iter;
++d_eqc_iter;
if( isLegalOpCandidate( n ) ){
+ Debug("cand-gen-qe") << "...returning " << n << std::endl;
return n;
}
}
+ }else if( d_mode==cand_term_tindex ){
+ Debug("cand-gen-qe") << "...get next candidate in tindex " << d_op << " " << d_op_arity << std::endl;
+ //increment the term index iterator
+ if( !d_tindex.empty() ){
+ //populate the vector
+ while( d_tindex_iter.size()<=d_op_arity ){
+ Assert( !d_tindex_iter.empty() );
+ Assert( !d_tindex_iter.back()->second.d_data.empty() );
+ d_tindex.push_back( &(d_tindex_iter.back()->second) );
+ d_tindex_iter.push_back( d_tindex_iter.back()->second.d_data.begin() );
+ }
+ //get the current node
+ Assert( d_tindex_iter.back()->second.hasNodeData() );
+ Node n = d_tindex_iter.back()->second.getNodeData();
+ Debug("cand-gen-qe") << "...returning " << n << std::endl;
+ Assert( !n.isNull() );
+ Assert( isLegalOpCandidate( n ) );
+ //increment
+ bool success = false;
+ do{
+ ++d_tindex_iter.back();
+ if( d_tindex_iter.back()==d_tindex.back()->d_data.end() ){
+ d_tindex.pop_back();
+ d_tindex_iter.pop_back();
+ }else{
+ success = true;
+ }
+ }while( !success && !d_tindex.empty() );
+ return n;
+ }
}else if( d_mode==cand_term_ident ){
+ Debug("cand-gen-qe") << "...get next candidate identity" << std::endl;
if( !d_n.isNull() ){
Node n = d_n;
d_n = Node::null();
@@ -130,21 +187,37 @@ Node CandidateGeneratorQE::getNextCandidate(){
CandidateGeneratorQELitEq::CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat ) :
d_match_pattern( mpat ), d_qe( qe ){
-
+ Assert( mpat.getKind()==EQUAL );
+ for( unsigned i=0; i<2; i++ ){
+ if( !quantifiers::TermDb::hasInstConstAttr(mpat[i]) ){
+ d_match_gterm = mpat[i];
+ }
+ }
}
void CandidateGeneratorQELitEq::resetInstantiationRound(){
}
void CandidateGeneratorQELitEq::reset( Node eqc ){
- d_eq = eq::EqClassesIterator( d_qe->getEqualityQuery()->getEngine() );
+ if( d_match_gterm.isNull() ){
+ d_eq = eq::EqClassesIterator( d_qe->getEqualityQuery()->getEngine() );
+ }else{
+ d_do_mgt = true;
+ }
}
Node CandidateGeneratorQELitEq::getNextCandidate(){
- while( !d_eq.isFinished() ){
- Node n = (*d_eq);
- ++d_eq;
- if( n.getType().isComparableTo( d_match_pattern[0].getType() ) ){
- //an equivalence class with the same type as the pattern, return reflexive equality
- return NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), n, n );
+ if( d_match_gterm.isNull() ){
+ while( !d_eq.isFinished() ){
+ Node n = (*d_eq);
+ ++d_eq;
+ if( n.getType().isComparableTo( d_match_pattern[0].getType() ) ){
+ //an equivalence class with the same type as the pattern, return reflexive equality
+ return NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), n, n );
+ }
+ }
+ }else{
+ if( d_do_mgt ){
+ d_do_mgt = false;
+ return NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), d_match_gterm, d_match_gterm );
}
}
return Node::null();
@@ -225,7 +298,6 @@ Node CandidateGeneratorQEAll::getNextCandidate() {
}
}
if( d_firstTime ){
- Assert( d_qe->getTermDatabase()->d_type_map[d_match_pattern_type].empty() );
//must return something
d_firstTime = false;
return d_qe->getTermDatabase()->getModelBasisTerm( d_match_pattern_type );
diff --git a/src/theory/quantifiers/candidate_generator.h b/src/theory/quantifiers/candidate_generator.h
index fb120dd08..18ef6a086 100644
--- a/src/theory/quantifiers/candidate_generator.h
+++ b/src/theory/quantifiers/candidate_generator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file candidate_generator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory uf candidate generator
**/
@@ -23,6 +23,10 @@
namespace CVC4 {
namespace theory {
+namespace quantifiers {
+ class TermArgTrie;
+}
+
class QuantifiersEngine;
namespace inst {
@@ -79,6 +83,9 @@ private:
//instantiator pointer
QuantifiersEngine* d_qe;
//the equality class iterator
+ unsigned d_op_arity;
+ std::vector< quantifiers::TermArgTrie* > d_tindex;
+ std::vector< std::map< TNode, quantifiers::TermArgTrie >::iterator > d_tindex_iter;
eq::EqClassIterator d_eqc_iter;
//std::vector< Node > d_eqc;
int d_term_iter;
@@ -88,17 +95,22 @@ private:
cand_term_db,
cand_term_ident,
cand_term_eqc,
+ cand_term_tindex,
+ cand_term_none,
};
short d_mode;
bool isLegalOpCandidate( Node n );
Node d_n;
+ std::map< Node, bool > d_exclude_eqc;
public:
- CandidateGeneratorQE( QuantifiersEngine* qe, Node op );
+ CandidateGeneratorQE( QuantifiersEngine* qe, Node pat );
~CandidateGeneratorQE() throw() {}
void resetInstantiationRound();
void reset( Node eqc );
Node getNextCandidate();
+ void excludeEqc( Node r ) { d_exclude_eqc[r] = true; }
+ bool isExcludedEqc( Node r ) { return d_exclude_eqc.find( r )!=d_exclude_eqc.end(); }
};
class CandidateGeneratorQELitEq : public CandidateGenerator
@@ -108,6 +120,8 @@ private:
eq::EqClassesIterator d_eq;
//equality you are trying to match equalities for
Node d_match_pattern;
+ Node d_match_gterm;
+ bool d_do_mgt;
//einstantiator pointer
QuantifiersEngine* d_qe;
public:
diff --git a/src/theory/quantifiers/ce_guided_instantiation.cpp b/src/theory/quantifiers/ce_guided_instantiation.cpp
index 345a5eaef..d9059a3e6 100644
--- a/src/theory/quantifiers/ce_guided_instantiation.cpp
+++ b/src/theory/quantifiers/ce_guided_instantiation.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_instantiation.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief counterexample guided instantiation class
**
@@ -22,19 +22,25 @@
#include "theory/quantifiers/term_database.h"
#include "theory/theory_engine.h"
-using namespace CVC4;
using namespace CVC4::kind;
-using namespace CVC4::theory;
-using namespace CVC4::theory::quantifiers;
using namespace std;
namespace CVC4 {
+namespace theory {
+namespace quantifiers {
-CegConjecture::CegConjecture( QuantifiersEngine * qe, context::Context* c ) : d_qe( qe ), d_curr_lit( c, 0 ){
+
+CegConjecture::CegConjecture( QuantifiersEngine * qe, context::Context* c )
+ : d_qe( qe ), d_curr_lit( c, 0 )
+{
d_refine_count = 0;
d_ceg_si = new CegConjectureSingleInv( qe, this );
}
+CegConjecture::~CegConjecture() {
+ delete d_ceg_si;
+}
+
void CegConjecture::assign( Node q ) {
Assert( d_quant.isNull() );
Assert( q.getKind()==FORALL );
@@ -149,7 +155,7 @@ CegqiFairMode CegConjecture::getCegqiFairMode() {
return isSingleInvocation() ? CEGQI_FAIR_NONE : options::ceGuidedInstFair();
}
-bool CegConjecture::isSingleInvocation() {
+bool CegConjecture::isSingleInvocation() const {
return d_ceg_si->isSingleInvocation();
}
@@ -219,11 +225,13 @@ bool CegInstantiation::needsCheck( Theory::Effort e ) {
}
unsigned CegInstantiation::needsModel( Theory::Effort e ) {
- return d_conj->d_ceg_si->isSingleInvocation() ? QuantifiersEngine::QEFFORT_STANDARD : QuantifiersEngine::QEFFORT_MODEL;
+ return d_conj->getCegConjectureSingleInv()->isSingleInvocation()
+ ? QuantifiersEngine::QEFFORT_STANDARD : QuantifiersEngine::QEFFORT_MODEL;
}
void CegInstantiation::check( Theory::Effort e, unsigned quant_e ) {
- unsigned echeck = d_conj->d_ceg_si->isSingleInvocation() ? QuantifiersEngine::QEFFORT_STANDARD : QuantifiersEngine::QEFFORT_MODEL;
+ unsigned echeck = d_conj->getCegConjectureSingleInv()->isSingleInvocation() ?
+ QuantifiersEngine::QEFFORT_STANDARD : QuantifiersEngine::QEFFORT_MODEL;
if( quant_e==echeck ){
Trace("cegqi-engine") << "---Counterexample Guided Instantiation Engine---" << std::endl;
Trace("cegqi-engine-debug") << std::endl;
@@ -294,12 +302,13 @@ Node CegInstantiation::getNextDecisionRequest() {
if( d_conj->isAssigned() ){
d_conj->initializeGuard( d_quantEngine );
std::vector< Node > req_dec;
- if( !d_conj->d_ceg_si->d_full_guard.isNull() ){
- req_dec.push_back( d_conj->d_ceg_si->d_full_guard );
+ const CegConjectureSingleInv* ceg_si = d_conj->getCegConjectureSingleInv();
+ if( ! ceg_si->d_full_guard.isNull() ){
+ req_dec.push_back( ceg_si->d_full_guard );
}
//must decide ns guard before s guard
- if( !d_conj->d_ceg_si->d_ns_guard.isNull() ){
- req_dec.push_back( d_conj->d_ceg_si->d_ns_guard );
+ if( !ceg_si->d_ns_guard.isNull() ){
+ req_dec.push_back( ceg_si->d_ns_guard );
}
req_dec.push_back( d_conj->getGuard() );
for( unsigned i=0; i<req_dec.size(); i++ ){
@@ -348,9 +357,9 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) {
if( conj->d_ce_sk.empty() ){
Trace("cegqi-engine") << " *** Check candidate phase..." << std::endl;
if( conj->d_syntax_guided ){
- if( conj->d_ceg_si ){
+ if( conj->getCegConjectureSingleInv() != NULL ){
std::vector< Node > lems;
- if( conj->d_ceg_si->check( lems ) ){
+ if( conj->doCegConjectureCheck( lems ) ){
if( !lems.empty() ){
d_last_inst_si = true;
for( unsigned j=0; j<lems.size(); j++ ){
@@ -423,7 +432,7 @@ void CegInstantiation::checkCegConjecture( CegConjecture * conj ) {
Assert( aq==q );
std::vector< Node > model_terms;
if( getModelValues( conj, conj->d_candidates, model_terms ) ){
- d_quantEngine->addInstantiation( q, model_terms, false );
+ d_quantEngine->addInstantiation( q, model_terms );
}
}
}else{
@@ -600,39 +609,53 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) {
Node sol;
int status;
if( d_last_inst_si ){
- Assert( d_conj->d_ceg_si );
- sol = d_conj->d_ceg_si->getSolution( i, tn, status );
+ Assert( d_conj->getCegConjectureSingleInv() != NULL );
+ sol = d_conj->getSingleInvocationSolution( i, tn, status );
sol = sol.getKind()==LAMBDA ? sol[1] : sol;
}else{
if( !d_conj->d_candidate_inst[i].empty() ){
sol = d_conj->d_candidate_inst[i].back();
- //check if this was based on a template, if so, we must do reconstruction
+ // Check if this was based on a template, if so, we must do
+ // Reconstruction
if( d_conj->d_assert_quant!=d_conj->d_quant ){
Node sygus_sol = sol;
- Trace("cegqi-inv") << "Sygus version of solution is : " << sol << ", type : " << sol.getType() << std::endl;
+ Trace("cegqi-inv") << "Sygus version of solution is : " << sol
+ << ", type : " << sol.getType() << std::endl;
std::vector< Node > subs;
Expr svl = dt.getSygusVarList();
for( unsigned j=0; j<svl.getNumChildren(); j++ ){
subs.push_back( Node::fromExpr( svl[j] ) );
}
if( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_PRE ){
- if( d_conj->d_ceg_si->d_trans_pre.find( prog )!=d_conj->d_ceg_si->d_trans_pre.end() ){
- Assert( d_conj->d_ceg_si->d_prog_templ_vars[prog].size()==subs.size() );
- Node pre = d_conj->d_ceg_si->d_trans_pre[prog];
- pre = pre.substitute( d_conj->d_ceg_si->d_prog_templ_vars[prog].begin(), d_conj->d_ceg_si->d_prog_templ_vars[prog].end(),
+ const CegConjectureSingleInv* ceg_si =
+ d_conj->getCegConjectureSingleInv();
+ if(ceg_si->d_trans_pre.find( prog ) != ceg_si->d_trans_pre.end()){
+ std::vector<Node>& templ_vars = d_conj->getProgTempVars(prog);
+ Assert(templ_vars.size() == subs.size());
+ Node pre = ceg_si->getTransPre(prog);
+ pre = pre.substitute( templ_vars.begin(), templ_vars.end(),
subs.begin(), subs.end() );
- sol = getTermDatabase()->getTermDatabaseSygus()->sygusToBuiltin( sol, sol.getType() );
- Trace("cegqi-inv") << "Builtin version of solution is : " << sol << ", type : " << sol.getType() << std::endl;
+ TermDbSygus* sygusDb = getTermDatabase()->getTermDatabaseSygus();
+ sol = sygusDb->sygusToBuiltin( sol, sol.getType() );
+ Trace("cegqi-inv") << "Builtin version of solution is : "
+ << sol << ", type : " << sol.getType()
+ << std::endl;
sol = NodeManager::currentNM()->mkNode( OR, sol, pre );
}
- }else if( options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_POST ){
- if( d_conj->d_ceg_si->d_trans_post.find( prog )!=d_conj->d_ceg_si->d_trans_post.end() ){
- Assert( d_conj->d_ceg_si->d_prog_templ_vars[prog].size()==subs.size() );
- Node post = d_conj->d_ceg_si->d_trans_post[prog];
- post = post.substitute( d_conj->d_ceg_si->d_prog_templ_vars[prog].begin(), d_conj->d_ceg_si->d_prog_templ_vars[prog].end(),
+ }else if(options::sygusInvTemplMode() == SYGUS_INV_TEMPL_MODE_POST){
+ const CegConjectureSingleInv* ceg_si =
+ d_conj->getCegConjectureSingleInv();
+ if(ceg_si->d_trans_post.find(prog) != ceg_si->d_trans_post.end()){
+ std::vector<Node>& templ_vars = d_conj->getProgTempVars(prog);
+ Assert( templ_vars.size()==subs.size() );
+ Node post = ceg_si->getTransPost(prog);
+ post = post.substitute( templ_vars.begin(), templ_vars.end(),
subs.begin(), subs.end() );
- sol = getTermDatabase()->getTermDatabaseSygus()->sygusToBuiltin( sol, sol.getType() );
- Trace("cegqi-inv") << "Builtin version of solution is : " << sol << ", type : " << sol.getType() << std::endl;
+ TermDbSygus* sygusDb = getTermDatabase()->getTermDatabaseSygus();
+ sol = sygusDb->sygusToBuiltin( sol, sol.getType() );
+ Trace("cegqi-inv") << "Builtin version of solution is : "
+ << sol << ", type : " << sol.getType()
+ << std::endl;
sol = NodeManager::currentNM()->mkNode( AND, sol, post );
}
}
@@ -643,7 +666,7 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) {
Trace("cegqi-inv-debug") << "With template : " << sol << std::endl;
sol = Rewriter::rewrite( sol );
Trace("cegqi-inv-debug") << "Simplified : " << sol << std::endl;
- sol = d_conj->d_ceg_si->reconstructToSyntax( sol, tn, status );
+ sol = d_conj->reconstructToSyntaxSingleInvocation(sol, tn, status);
sol = sol.getKind()==LAMBDA ? sol[1] : sol;
}
}else{
@@ -712,5 +735,6 @@ CegInstantiation::Statistics::~Statistics(){
smtStatisticsRegistry()->unregisterStat(&d_cegqi_si_lemmas);
}
-
-}
+}/* namespace CVC4::theory::quantifiers */
+}/* namespace CVC4::theory */
+}/* namespace CVC4 */
diff --git a/src/theory/quantifiers/ce_guided_instantiation.h b/src/theory/quantifiers/ce_guided_instantiation.h
index 8274561ca..57dc31850 100644
--- a/src/theory/quantifiers/ce_guided_instantiation.h
+++ b/src/theory/quantifiers/ce_guided_instantiation.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_instantiation.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief counterexample guided instantiation class
**/
@@ -33,6 +33,8 @@ private:
QuantifiersEngine * d_qe;
public:
CegConjecture( QuantifiersEngine * qe, context::Context* c );
+ ~CegConjecture();
+
/** quantified formula asserted */
Node d_assert_quant;
/** quantified formula (after processing) */
@@ -56,12 +58,36 @@ public:
unsigned d_refine_count;
/** current extential quantifeirs whose couterexamples we must refine */
std::vector< std::vector< Node > > d_ce_sk;
+
+ const CegConjectureSingleInv* getCegConjectureSingleInv() const {
+ return d_ceg_si;
+ }
+
+ bool doCegConjectureCheck(std::vector< Node >& lems) {
+ return d_ceg_si->check(lems);
+ }
+
+ Node getSingleInvocationSolution(unsigned sol_index, TypeNode stn,
+ int& reconstructed, bool rconsSygus=true){
+ return d_ceg_si->getSolution(sol_index, stn, reconstructed, rconsSygus);
+ }
+
+ Node reconstructToSyntaxSingleInvocation(
+ Node s, TypeNode stn, int& reconstructed, bool rconsSygus = true ) {
+ return d_ceg_si->reconstructToSyntax(s, stn, reconstructed, rconsSygus);
+ }
+
+ std::vector<Node>& getProgTempVars(Node prog) {
+ return d_ceg_si->d_prog_templ_vars[prog];
+ }
+
+ private:
/** single invocation utility */
CegConjectureSingleInv * d_ceg_si;
public: //non-syntax guided (deprecated)
/** guard */
bool d_syntax_guided;
- Node d_nsg_guard;
+ Node d_nsg_guard;
public: //for fairness
/** the cardinality literals */
std::map< int, Node > d_lits;
@@ -76,7 +102,7 @@ public: //for fairness
/** fairness */
CegqiFairMode getCegqiFairMode();
/** is single invocation */
- bool isSingleInvocation();
+ bool isSingleInvocation() const;
/** is single invocation */
bool isFullySingleInvocation();
/** needs check */
@@ -151,10 +177,10 @@ public:
~Statistics();
};/* class CegInstantiation::Statistics */
Statistics d_statistics;
-};
+}; /* class CegInstantiation */
-}
-}
-}
+} /* namespace CVC4::theory::quantifiers */
+} /* namespace CVC4::theory */
+} /* namespace CVC4 */
#endif
diff --git a/src/theory/quantifiers/ce_guided_single_inv.cpp b/src/theory/quantifiers/ce_guided_single_inv.cpp
index 7ef23077f..33856d226 100644
--- a/src/theory/quantifiers/ce_guided_single_inv.cpp
+++ b/src/theory/quantifiers/ce_guided_single_inv.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_single_inv.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief utility for processing single invocation synthesis conjectures
**
@@ -33,8 +33,8 @@ using namespace std;
namespace CVC4 {
-bool CegqiOutputSingleInv::addInstantiation( std::vector< Node >& subs ) {
- return d_out->addInstantiation( subs );
+bool CegqiOutputSingleInv::doAddInstantiation( std::vector< Node >& subs ) {
+ return d_out->doAddInstantiation( subs );
}
bool CegqiOutputSingleInv::isEligibleForInstantiation( Node n ) {
@@ -55,12 +55,12 @@ CegConjectureSingleInv::CegConjectureSingleInv( QuantifiersEngine * qe, CegConje
}
d_cosi = new CegqiOutputSingleInv( this );
// third and fourth arguments set to (false,false) until we have solution reconstruction for delta and infinity
- d_cinst = new CegInstantiator( d_qe, d_cosi, false, false );
+ d_cinst = new CegInstantiator( d_qe, d_cosi, false, false );
d_sol = new CegConjectureSingleInvSol( qe );
d_sip = new SingleInvocationPartition;
-
+
if( options::cegqiSingleInvPartial() ){
d_ei = new CegEntailmentInfer( qe, d_sip );
}else{
@@ -104,7 +104,7 @@ void CegConjectureSingleInv::getInitialSingleInvLemma( std::vector< Node >& lems
if( d_cinst ){
delete d_cinst;
}
- d_cinst = new CegInstantiator( d_qe, d_cosi, false, false );
+ d_cinst = new CegInstantiator( d_qe, d_cosi, false, false );
d_cinst->registerCounterexampleLemma( lems, d_single_inv_sk );
}
}
@@ -149,8 +149,7 @@ void CegConjectureSingleInv::initialize( Node q ) {
bool singleInvocation = true;
if( type_valid==0 ){
//process the single invocation-ness of the property
- d_sip->init( types );
- d_sip->process( qq );
+ d_sip->init( types, qq );
Trace("cegqi-si") << "- Partitioned to single invocation parts : " << std::endl;
d_sip->debugPrint( "cegqi-si" );
//map from program to bound variables
@@ -481,7 +480,7 @@ void CegConjectureSingleInv::initializeNextSiConjecture() {
if( d_single_inv.isNull() ){
if( d_ei->getEntailedConjecture( d_single_inv, d_single_inv_exp ) ){
Trace("cegqi-nsi") << "NSI : got : " << d_single_inv << std::endl;
- Trace("cegqi-nsi") << "NSI : exp : " << d_single_inv_exp << std::endl;
+ Trace("cegqi-nsi") << "NSI : exp : " << d_single_inv_exp << std::endl;
}else{
Trace("cegqi-nsi") << "NSI : failed to construct next conjecture." << std::endl;
Notice() << "Incomplete due to --cegqi-si-partial." << std::endl;
@@ -492,7 +491,7 @@ void CegConjectureSingleInv::initializeNextSiConjecture() {
Trace("cegqi-nsi") << "NSI : have : " << d_single_inv << std::endl;
Assert( d_single_inv_exp.isNull() );
}
-
+
d_si_guard = Node::null();
d_ns_guard = Rewriter::rewrite( NodeManager::currentNM()->mkSkolem( "GS", NodeManager::currentNM()->booleanType() ) );
d_ns_guard = d_qe->getValuation().ensureLiteral( d_ns_guard );
@@ -509,7 +508,7 @@ void CegConjectureSingleInv::initializeNextSiConjecture() {
Trace("cegqi-nsi") << "NSI : conjecture is " << d_single_inv << std::endl;
}
-bool CegConjectureSingleInv::addInstantiation( std::vector< Node >& subs ){
+bool CegConjectureSingleInv::doAddInstantiation( std::vector< Node >& subs ){
std::stringstream siss;
if( Trace.isOn("cegqi-si-inst-debug") || Trace.isOn("cegqi-engine") ){
siss << " * single invocation: " << std::endl;
@@ -839,7 +838,42 @@ void CegConjectureSingleInv::preregisterConjecture( Node q ) {
d_orig_conjecture = q;
}
-void SingleInvocationPartition::init( std::vector< TypeNode >& typs ){
+bool SingleInvocationPartition::init( Node n ) {
+ //first, get types of arguments for functions
+ std::vector< TypeNode > typs;
+ std::map< Node, bool > visited;
+ if( inferArgTypes( n, typs, visited ) ){
+ return init( typs, n );
+ }else{
+ Trace("si-prt") << "Could not infer argument types." << std::endl;
+ return false;
+ }
+}
+
+bool SingleInvocationPartition::inferArgTypes( Node n, std::vector< TypeNode >& typs, std::map< Node, bool >& visited ) {
+ if( visited.find( n )==visited.end() ){
+ visited[n] = true;
+ if( n.getKind()!=FORALL ){
+ //if( TermDb::hasBoundVarAttr( n ) ){
+ if( n.getKind()==d_checkKind ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ typs.push_back( n[i].getType() );
+ }
+ return true;
+ }else{
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ if( inferArgTypes( n[i], typs, visited ) ){
+ return true;
+ }
+ }
+ }
+ //}
+ }
+ }
+ return false;
+}
+
+bool SingleInvocationPartition::init( std::vector< TypeNode >& typs, Node n ){
Assert( d_arg_types.empty() );
Assert( d_si_vars.empty() );
d_arg_types.insert( d_arg_types.end(), typs.begin(), typs.end() );
@@ -849,6 +883,9 @@ void SingleInvocationPartition::init( std::vector< TypeNode >& typs ){
Node si_v = NodeManager::currentNM()->mkBoundVar( ss.str(), d_arg_types[j] );
d_si_vars.push_back( si_v );
}
+ Trace("si-prt") << "Process the formula..." << std::endl;
+ process( n );
+ return true;
}
@@ -874,6 +911,7 @@ void SingleInvocationPartition::process( Node n ) {
std::vector< Node > terms;
std::vector< Node > subs;
bool singleInvocation = true;
+ bool ngroundSingleInvocation = false;
if( processConjunct( cr, visited, args, terms, subs ) ){
for( unsigned j=0; j<terms.size(); j++ ){
si_terms.push_back( subs[j] );
@@ -909,6 +947,7 @@ void SingleInvocationPartition::process( Node n ) {
TermDb::getBoundVars( cr, bvs );
if( bvs.size()>d_si_vars.size() ){
Trace("si-prt") << "...not ground single invocation." << std::endl;
+ ngroundSingleInvocation = true;
singleInvocation = false;
}else{
Trace("si-prt") << "...ground single invocation : success." << std::endl;
@@ -949,6 +988,9 @@ void SingleInvocationPartition::process( Node n ) {
d_conjuncts[0].push_back( cr );
}else{
d_conjuncts[1].push_back( cr );
+ if( ngroundSingleInvocation ){
+ d_conjuncts[3].push_back( cr );
+ }
}
}
}else{
@@ -984,43 +1026,45 @@ bool SingleInvocationPartition::processConjunct( Node n, std::map< Node, bool >&
return true;
}else{
bool ret = true;
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- if( !processConjunct( n[i], visited, args, terms, subs ) ){
- ret = false;
+ //if( TermDb::hasBoundVarAttr( n ) ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ if( !processConjunct( n[i], visited, args, terms, subs ) ){
+ ret = false;
+ }
}
- }
- if( ret ){
- if( n.getKind()==APPLY_UF ){
- if( std::find( terms.begin(), terms.end(), n )==terms.end() ){
- Node f = n.getOperator();
- //check if it matches the type requirement
- if( isAntiSkolemizableType( f ) ){
- if( args.empty() ){
- //record arguments
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- args.push_back( n[i] );
- }
- }else{
- //arguments must be the same as those already recorded
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- if( args[i]!=n[i] ){
- Trace("si-prt-debug") << "...bad invocation : " << n << " at arg " << i << "." << std::endl;
- ret = false;
- break;
+ if( ret ){
+ if( n.getKind()==d_checkKind ){
+ if( std::find( terms.begin(), terms.end(), n )==terms.end() ){
+ Node f = n.getOperator();
+ //check if it matches the type requirement
+ if( isAntiSkolemizableType( f ) ){
+ if( args.empty() ){
+ //record arguments
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ args.push_back( n[i] );
+ }
+ }else{
+ //arguments must be the same as those already recorded
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ if( args[i]!=n[i] ){
+ Trace("si-prt-debug") << "...bad invocation : " << n << " at arg " << i << "." << std::endl;
+ ret = false;
+ break;
+ }
}
}
+ if( ret ){
+ terms.push_back( n );
+ subs.push_back( d_func_inv[f] );
+ }
+ }else{
+ Trace("si-prt-debug") << "... " << f << " is a bad operator." << std::endl;
+ ret = false;
}
- if( ret ){
- terms.push_back( n );
- subs.push_back( d_func_inv[f] );
- }
- }else{
- Trace("si-prt-debug") << "... " << f << " is a bad operator." << std::endl;
- ret = false;
}
}
}
- }
+ //}
visited[n] = ret;
return ret;
}
@@ -1037,6 +1081,7 @@ bool SingleInvocationPartition::isAntiSkolemizableType( Node f ) {
ret = true;
std::vector< Node > children;
children.push_back( f );
+ //TODO: permutations of arguments
for( unsigned i=0; i<d_arg_types.size(); i++ ){
children.push_back( d_si_vars[i] );
if( tn[i]!=d_arg_types[i] ){
@@ -1045,7 +1090,7 @@ bool SingleInvocationPartition::isAntiSkolemizableType( Node f ) {
}
}
if( ret ){
- Node t = NodeManager::currentNM()->mkNode( APPLY_UF, children );
+ Node t = NodeManager::currentNM()->mkNode( d_checkKind, children );
d_func_inv[f] = t;
d_inv_to_func[t] = f;
std::stringstream ss;
@@ -1079,7 +1124,7 @@ Node SingleInvocationPartition::getSpecificationInst( Node n, std::map< Node, No
childChanged = childChanged || ( nn!=n[i] );
}
Node ret;
- if( n.getKind()==APPLY_UF ){
+ if( n.getKind()==d_checkKind ){
std::map< Node, Node >::iterator itl = lam.find( n.getOperator() );
if( itl!=lam.end() ){
Assert( itl->second[0].getNumChildren()==children.size() );
@@ -1176,8 +1221,8 @@ void SingleInvocationPartition::debugPrint( const char * c ) {
Trace(c) << "not incorporated." << std::endl;
}
}
- for( unsigned i=0; i<3; i++ ){
- Trace(c) << ( i==0 ? "Single invocation" : ( i==1 ? "Non-single invocation" : "All" ) );
+ for( unsigned i=0; i<4; i++ ){
+ Trace(c) << ( i==0 ? "Single invocation" : ( i==1 ? "Non-single invocation" : ( i==2 ? "All" : "Non-ground single invocation" ) ) );
Trace(c) << " conjuncts: " << std::endl;
for( unsigned j=0; j<d_conjuncts[i].size(); j++ ){
Trace(c) << " " << (j+1) << " : " << d_conjuncts[i][j] << std::endl;
diff --git a/src/theory/quantifiers/ce_guided_single_inv.h b/src/theory/quantifiers/ce_guided_single_inv.h
index c414a51bd..4d2f9a0e5 100644
--- a/src/theory/quantifiers/ce_guided_single_inv.h
+++ b/src/theory/quantifiers/ce_guided_single_inv.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_single_inv.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief utility for processing single invocation synthesis conjectures
**/
@@ -37,7 +37,7 @@ public:
CegqiOutputSingleInv( CegConjectureSingleInv * out ) : d_out( out ){}
~CegqiOutputSingleInv() {}
CegConjectureSingleInv * d_out;
- bool addInstantiation( std::vector< Node >& subs );
+ bool doAddInstantiation( std::vector< Node >& subs );
bool isEligibleForInstantiation( Node n );
bool addLemma( Node lem );
};
@@ -58,13 +58,21 @@ private:
CegqiOutputSingleInv * d_cosi;
CegInstantiator * d_cinst;
//for recognizing templates for invariant synthesis
- Node substituteInvariantTemplates( Node n, std::map< Node, Node >& prog_templ, std::map< Node, std::vector< Node > >& prog_templ_vars );
+ Node substituteInvariantTemplates(
+ Node n, std::map< Node, Node >& prog_templ,
+ std::map< Node, std::vector< Node > >& prog_templ_vars );
// partially single invocation
- Node removeDeepEmbedding( Node n, std::vector< Node >& progs, std::vector< TypeNode >& types, int& type_valid, std::map< Node, Node >& visited );
+ Node removeDeepEmbedding( Node n, std::vector< Node >& progs,
+ std::vector< TypeNode >& types, int& type_valid,
+ std::map< Node, Node >& visited );
Node addDeepEmbedding( Node n, std::map< Node, Node >& visited );
//presolve
- void collectPresolveEqTerms( Node n, std::map< Node, std::vector< Node > >& teq );
- void getPresolveEqConjuncts( std::vector< Node >& vars, std::vector< Node >& terms, std::map< Node, std::vector< Node > >& teq, Node n, std::vector< Node >& conj );
+ void collectPresolveEqTerms( Node n,
+ std::map< Node, std::vector< Node > >& teq );
+ void getPresolveEqConjuncts( std::vector< Node >& vars,
+ std::vector< Node >& terms,
+ std::map< Node, std::vector< Node > >& teq,
+ Node n, std::vector< Node >& conj );
//constructing solution
Node constructSolution( std::vector< unsigned >& indices, unsigned i, unsigned index );
Node postProcessSolution( Node n );
@@ -94,7 +102,7 @@ public:
private:
std::vector< Node > d_curr_lemmas;
//add instantiation
- bool addInstantiation( std::vector< Node >& subs );
+ bool doAddInstantiation( std::vector< Node >& subs );
//is eligible for instantiation
bool isEligibleForInstantiation( Node n );
// add lemma
@@ -113,7 +121,7 @@ public:
Node d_full_inv;
Node d_full_guard;
//explanation for current single invocation conjecture
- Node d_single_inv_exp;
+ Node d_single_inv_exp;
// transition relation version per program
std::map< Node, Node > d_trans_pre;
std::map< Node, Node > d_trans_post;
@@ -132,19 +140,33 @@ public:
//get solution
Node getSolution( unsigned sol_index, TypeNode stn, int& reconstructed, bool rconsSygus = true );
//reconstruct to syntax
- Node reconstructToSyntax( Node s, TypeNode stn, int& reconstructed, bool rconsSygus = true );
+ Node reconstructToSyntax( Node s, TypeNode stn, int& reconstructed,
+ bool rconsSygus = true );
// has ites
bool hasITEs() { return d_has_ites; }
// is single invocation
- bool isSingleInvocation() { return !d_single_inv.isNull(); }
+ bool isSingleInvocation() const { return !d_single_inv.isNull(); }
// is single invocation
- bool isFullySingleInvocation() { return !d_single_inv.isNull() && d_nsingle_inv.isNull(); }
+ bool isFullySingleInvocation() const {
+ return !d_single_inv.isNull() && d_nsingle_inv.isNull();
+ }
//needs check
bool needsCheck();
/** preregister conjecture */
void preregisterConjecture( Node q );
//initialize next candidate si conjecture (if not fully single invocation)
- void initializeNextSiConjecture();
+ void initializeNextSiConjecture();
+
+ Node getTransPre(Node prog) const {
+ std::map<Node, Node>::const_iterator location = d_trans_pre.find(prog);
+ return location->second;
+ }
+
+ Node getTransPost(Node prog) const {
+ std::map<Node, Node>::const_iterator location = d_trans_post.find(prog);
+ return location->second;
+ }
+
};
// partitions any formulas given to it into single invocation/non-single invocation
@@ -153,18 +175,23 @@ public:
class SingleInvocationPartition
{
private:
+ //options
+ Kind d_checkKind;
+ bool inferArgTypes( Node n, std::vector< TypeNode >& typs, std::map< Node, bool >& visited );
+ void process( Node n );
bool collectConjuncts( Node n, bool pol, std::vector< Node >& conj );
bool processConjunct( Node n, std::map< Node, bool >& visited, std::vector< Node >& args,
std::vector< Node >& terms, std::vector< Node >& subs );
Node getSpecificationInst( Node n, std::map< Node, Node >& lam, std::map< Node, Node >& visited );
void extractInvariant2( Node n, Node& func, int& pol, std::vector< Node >& disjuncts, bool hasPol, std::map< Node, bool >& visited );
public:
- void init( std::vector< TypeNode >& typs );
- //inputs
- void process( Node n );
- std::vector< TypeNode > d_arg_types;
+ SingleInvocationPartition( Kind checkKind = kind::APPLY_UF ) : d_checkKind( checkKind ){}
+ ~SingleInvocationPartition(){}
+ bool init( Node n );
+ bool init( std::vector< TypeNode >& typs, Node n );
//outputs (everything is with bound var)
+ std::vector< TypeNode > d_arg_types;
std::map< Node, bool > d_funcs;
std::map< Node, Node > d_func_inv;
std::map< Node, Node > d_inv_to_func;
@@ -173,8 +200,8 @@ public:
std::vector< Node > d_func_vars; //the first-order variables corresponding to all functions
std::vector< Node > d_si_vars; //the arguments that we based the anti-skolemization on
std::vector< Node > d_all_vars; //every free variable of conjuncts[2]
- // si, nsi, all
- std::vector< Node > d_conjuncts[3];
+ // si, nsi, all, non-ground si
+ std::vector< Node > d_conjuncts[4];
bool isAntiSkolemizableType( Node f );
@@ -187,12 +214,14 @@ public:
void extractInvariant( Node n, Node& func, int& pol, std::vector< Node >& disjuncts );
+ bool isPurelySingleInvocation() { return d_conjuncts[1].empty(); }
+ bool isNonGroundSingleInvocation() { return d_conjuncts[3].size()==d_conjuncts[1].size(); }
+
void debugPrint( const char * c );
};
-
-}
-}
-}
+}/* namespace CVC4::theory::quantifiers */
+}/* namespace CVC4::theory */
+}/* namespace CVC4 */
#endif
diff --git a/src/theory/quantifiers/ce_guided_single_inv_ei.cpp b/src/theory/quantifiers/ce_guided_single_inv_ei.cpp
index f45285851..6394fca3d 100644
--- a/src/theory/quantifiers/ce_guided_single_inv_ei.cpp
+++ b/src/theory/quantifiers/ce_guided_single_inv_ei.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_single_inv_ei.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief utility for inferring entailments for cegqi
**
diff --git a/src/theory/quantifiers/ce_guided_single_inv_ei.h b/src/theory/quantifiers/ce_guided_single_inv_ei.h
index 0645c406a..42e0b0820 100644
--- a/src/theory/quantifiers/ce_guided_single_inv_ei.h
+++ b/src/theory/quantifiers/ce_guided_single_inv_ei.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_single_inv_ei.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief utility for inferring entailments for cegqi
**/
diff --git a/src/theory/quantifiers/ce_guided_single_inv_sol.cpp b/src/theory/quantifiers/ce_guided_single_inv_sol.cpp
index 6ba5bed02..240c2ed12 100644
--- a/src/theory/quantifiers/ce_guided_single_inv_sol.cpp
+++ b/src/theory/quantifiers/ce_guided_single_inv_sol.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file ce_guided_single_inv.cpp
+/*! \file ce_guided_single_inv_sol.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief utility for processing single invocation synthesis conjectures
**
diff --git a/src/theory/quantifiers/ce_guided_single_inv_sol.h b/src/theory/quantifiers/ce_guided_single_inv_sol.h
index adcc7bf85..cb6f6bc41 100644
--- a/src/theory/quantifiers/ce_guided_single_inv_sol.h
+++ b/src/theory/quantifiers/ce_guided_single_inv_sol.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ce_guided_single_inv_sol.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief utility for reconstructing solutions for single invocation synthesis conjectures
**/
diff --git a/src/theory/quantifiers/ceg_instantiator.cpp b/src/theory/quantifiers/ceg_instantiator.cpp
index b02c9a740..da488ea98 100644
--- a/src/theory/quantifiers/ceg_instantiator.cpp
+++ b/src/theory/quantifiers/ceg_instantiator.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file ceg_instantiator.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of counterexample-guided quantifier instantiation
**/
@@ -65,9 +65,9 @@ void CegInstantiator::computeProgVars( Node n ){
}
}
-bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
- std::vector< int >& btyp, Node theta, unsigned i, unsigned effort,
- std::map< Node, Node >& cons, std::vector< Node >& curr_var ){
+bool CegInstantiator::doAddInstantiation( SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
+ std::vector< int >& btyp, Node theta, unsigned i, unsigned effort,
+ std::map< Node, Node >& cons, std::vector< Node >& curr_var ){
if( i==d_vars.size() ){
//solved for all variables, now construct instantiation
if( !sf.d_has_coeff.empty() ){
@@ -75,12 +75,12 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
//use symbolic solved forms
SolvedForm csf;
csf.copy( ssf );
- return addInstantiationCoeff( csf, vars, btyp, 0, cons );
+ return doAddInstantiationCoeff( csf, vars, btyp, 0, cons );
}else{
- return addInstantiationCoeff( sf, vars, btyp, 0, cons );
+ return doAddInstantiationCoeff( sf, vars, btyp, 0, cons );
}
}else{
- return addInstantiation( sf.d_subs, vars, cons );
+ return doAddInstantiation( sf.d_subs, vars, cons );
}
}else{
std::map< Node, std::map< Node, bool > > subs_proc;
@@ -94,16 +94,17 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
is_cv = true;
}
TypeNode pvtn = pv.getType();
- Trace("cbqi-inst-debug") << "[Find instantiation for " << pv << "]" << std::endl;
+ TypeNode pvtnb = pvtn.getBaseType();
+ Node pvr = pv;
+ if( d_qe->getMasterEqualityEngine()->hasTerm( pv ) ){
+ pvr = d_qe->getMasterEqualityEngine()->getRepresentative( pv );
+ }
+ Trace("cbqi-inst-debug") << "[Find instantiation for " << pv << "], rep=" << pvr << std::endl;
Node pv_value;
if( options::cbqiModel() ){
pv_value = getModelValue( pv );
Trace("cbqi-bound2") << "...M( " << pv << " ) = " << pv_value << std::endl;
}
- Node pvr = pv;
- if( d_qe->getMasterEqualityEngine()->hasTerm( pv ) ){
- pvr = d_qe->getMasterEqualityEngine()->getRepresentative( pv );
- }
//if in effort=2, we must choose at least one model value
if( (i+1)<d_vars.size() || effort!=2 ){
@@ -138,53 +139,89 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
if( proc ){
//try the substitution
subs_proc[ns][pv_coeff] = true;
- if( addInstantiationInc( ns, pv, pv_coeff, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( ns, pv, pv_coeff, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
}
}
}
+ if( pvtn.isDatatype() ){
+ Trace("cbqi-inst-debug") << "[2] try based on constructors in equivalence class." << std::endl;
+ //[2] look in equivalence class for a constructor
+ for( unsigned k=0; k<it_eqc->second.size(); k++ ){
+ Node n = it_eqc->second[k];
+ if( n.getKind()==APPLY_CONSTRUCTOR ){
+ Trace("cbqi-inst-debug") << "... " << i << "...try based on constructor term " << n << std::endl;
+ cons[pv] = n.getOperator();
+ const Datatype& dt = ((DatatypeType)(pvtn).toType()).getDatatype();
+ unsigned cindex = Datatype::indexOf( n.getOperator().toExpr() );
+ if( is_cv ){
+ curr_var.pop_back();
+ }
+ //now must solve for selectors applied to pv
+ for( unsigned j=0; j<dt[cindex].getNumArgs(); j++ ){
+ curr_var.push_back( NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex][j].getSelector() ), pv ) );
+ }
+ if( doAddInstantiation( sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ return true;
+ }else{
+ //cleanup
+ cons.erase( pv );
+ Assert( curr_var.size()>=dt[cindex].getNumArgs() );
+ for( unsigned j=0; j<dt[cindex].getNumArgs(); j++ ){
+ curr_var.pop_back();
+ }
+ if( is_cv ){
+ curr_var.push_back( pv );
+ }
+ break;
+ }
+ }
+ }
+ }
}else{
Trace("cbqi-inst-debug2") << "...eqc not found." << std::endl;
}
- //[2] : we can solve an equality for pv
- if( pvtn.isInteger() || pvtn.isReal() ){
- ///iterate over equivalence classes to find cases where we can solve for the variable
- TypeNode pvtnb = pvtn.getBaseType();
- Trace("cbqi-inst-debug") << "[2] try based on solving arithmetic equivalence classes." << std::endl;
- for( unsigned k=0; k<d_curr_type_eqc[pvtnb].size(); k++ ){
- Node r = d_curr_type_eqc[pvtnb][k];
- std::map< Node, std::vector< Node > >::iterator it_reqc = d_curr_eqc.find( r );
- std::vector< Node > lhs;
- std::vector< bool > lhs_v;
- std::vector< Node > lhs_coeff;
- Assert( it_reqc!=d_curr_eqc.end() );
- for( unsigned kk=0; kk<it_reqc->second.size(); kk++ ){
- Node n = it_reqc->second[kk];
- Trace("cbqi-inst-debug2") << "...look at term " << n << std::endl;
- //compute the variables in n
- computeProgVars( n );
- //must be an eligible term
- if( d_inelig.find( n )==d_inelig.end() ){
- Node ns;
- Node pv_coeff;
- if( !d_prog_var[n].empty() ){
- ns = applySubstitution( pvtn, n, sf, vars, pv_coeff );
- if( !ns.isNull() ){
- computeProgVars( ns );
- }
- }else{
- ns = n;
- }
+ //[3] : we can solve an equality for pv
+ ///iterate over equivalence classes to find cases where we can solve for the variable
+ Trace("cbqi-inst-debug") << "[3] try based on solving equalities." << std::endl;
+ for( unsigned k=0; k<d_curr_type_eqc[pvtnb].size(); k++ ){
+ Node r = d_curr_type_eqc[pvtnb][k];
+ std::map< Node, std::vector< Node > >::iterator it_reqc = d_curr_eqc.find( r );
+ std::vector< Node > lhs;
+ std::vector< bool > lhs_v;
+ std::vector< Node > lhs_coeff;
+ Assert( it_reqc!=d_curr_eqc.end() );
+ for( unsigned kk=0; kk<it_reqc->second.size(); kk++ ){
+ Node n = it_reqc->second[kk];
+ Trace("cbqi-inst-debug2") << "...look at term " << n << std::endl;
+ //compute the variables in n
+ computeProgVars( n );
+ //must be an eligible term
+ if( d_inelig.find( n )==d_inelig.end() ){
+ Node ns;
+ Node pv_coeff;
+ if( !d_prog_var[n].empty() ){
+ ns = applySubstitution( pvtn, n, sf, vars, pv_coeff );
if( !ns.isNull() ){
- bool hasVar = d_prog_var[ns].find( pv )!=d_prog_var[ns].end();
- Trace("cbqi-inst-debug2") << "... " << ns << " has var " << pv << " : " << hasVar << std::endl;
- for( unsigned j=0; j<lhs.size(); j++ ){
- //if this term or the another has pv in it, try to solve for it
- if( hasVar || lhs_v[j] ){
- Trace("cbqi-inst-debug") << "... " << i << "...try based on equality " << lhs[j] << " = " << ns << std::endl;
+ computeProgVars( ns );
+ }
+ }else{
+ ns = n;
+ }
+ if( !ns.isNull() ){
+ bool hasVar = d_prog_var[ns].find( pv )!=d_prog_var[ns].end();
+ Trace("cbqi-inst-debug2") << "... " << ns << " has var " << pv << " : " << hasVar << std::endl;
+ for( unsigned j=0; j<lhs.size(); j++ ){
+ //if this term or the another has pv in it, try to solve for it
+ if( hasVar || lhs_v[j] ){
+ Trace("cbqi-inst-debug") << "... " << i << "...try based on equality " << lhs[j] << " = " << ns << std::endl;
+ Node val;
+ Node veq_c;
+ bool success = false;
+ if( pvtnb.isReal() ){
Node eq_lhs = lhs[j];
Node eq_rhs = ns;
//make the same coefficient
@@ -204,17 +241,10 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
eq = Rewriter::rewrite( eq );
Node vts_coeff_inf;
Node vts_coeff_delta;
- Node val;
- Node veq_c;
//isolate pv in the equality
- int ires = isolate( pv, eq, veq_c, val, vts_coeff_inf, vts_coeff_delta );
+ int ires = solve_arith( pv, eq, veq_c, val, vts_coeff_inf, vts_coeff_delta );
if( ires!=0 ){
- if( subs_proc[val].find( veq_c )==subs_proc[val].end() ){
- subs_proc[val][veq_c] = true;
- if( addInstantiationInc( val, pv, veq_c, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
- return true;
- }
- }
+ success = true;
}
/*
//cannot contain infinity?
@@ -240,67 +270,43 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
Node val = veq[1];
if( subs_proc[val].find( veq_c )==subs_proc[val].end() ){
subs_proc[val][veq_c] = true;
- if( addInstantiationInc( val, pv, veq_c, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( val, pv, veq_c, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
}
}
*/
+ }else if( pvtnb.isDatatype() ){
+ val = solve_dt( pv, lhs[j], ns, lhs[j], ns );
+ if( !val.isNull() ){
+ success = true;
+ }
+ }
+ if( success ){
+ if( subs_proc[val].find( veq_c )==subs_proc[val].end() ){
+ subs_proc[val][veq_c] = true;
+ if( doAddInstantiationInc( val, pv, veq_c, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ return true;
+ }
+ }
}
}
- lhs.push_back( ns );
- lhs_v.push_back( hasVar );
- lhs_coeff.push_back( pv_coeff );
- }else{
- Trace("cbqi-inst-debug2") << "... term " << n << " is ineligible after substitution." << std::endl;
}
+ lhs.push_back( ns );
+ lhs_v.push_back( hasVar );
+ lhs_coeff.push_back( pv_coeff );
}else{
- Trace("cbqi-inst-debug2") << "... term " << n << " is ineligible." << std::endl;
- }
- }
- }
- }else if( pvtn.isDatatype() ){
- Trace("cbqi-inst-debug") << "[2] try based on constructors in equivalence class." << std::endl;
- //look in equivalence class for a constructor
- if( it_eqc!=d_curr_eqc.end() ){
- for( unsigned k=0; k<it_eqc->second.size(); k++ ){
- Node n = it_eqc->second[k];
- if( n.getKind()==APPLY_CONSTRUCTOR ){
- Trace("cbqi-inst-debug") << "... " << i << "...try based on constructor term " << n << std::endl;
- cons[pv] = n.getOperator();
- const Datatype& dt = ((DatatypeType)(pvtn).toType()).getDatatype();
- unsigned cindex = Datatype::indexOf( n.getOperator().toExpr() );
- if( is_cv ){
- curr_var.pop_back();
- }
- //now must solve for selectors applied to pv
- for( unsigned j=0; j<dt[cindex].getNumArgs(); j++ ){
- curr_var.push_back( NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex][j].getSelector() ), pv ) );
- }
- if( addInstantiation( sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
- return true;
- }else{
- //cleanup
- cons.erase( pv );
- Assert( curr_var.size()>=dt[cindex].getNumArgs() );
- for( unsigned j=0; j<dt[cindex].getNumArgs(); j++ ){
- curr_var.pop_back();
- }
- if( is_cv ){
- curr_var.push_back( pv );
- }
- break;
- }
+ Trace("cbqi-inst-debug2") << "... term " << n << " is ineligible after substitution." << std::endl;
}
+ }else{
+ Trace("cbqi-inst-debug2") << "... term " << n << " is ineligible." << std::endl;
}
- }else{
- Trace("cbqi-inst-debug2") << "... " << i << " does not have an eqc." << std::endl;
}
}
- //[3] directly look at assertions
- Trace("cbqi-inst-debug") << "[3] try based on assertions." << std::endl;
+ //[4] directly look at assertions
+ Trace("cbqi-inst-debug") << "[4] try based on assertions." << std::endl;
d_vts_sym[0] = d_qe->getTermDatabase()->getVtsInfinity( pvtn, false, false );
d_vts_sym[1] = d_qe->getTermDatabase()->getVtsDelta( false, false );
std::vector< Node > mbp_bounds[2];
@@ -360,7 +366,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
Node val;
Node veq_c;
//isolate pv in the inequality
- int ires = isolate( pv, satom, veq_c, val, vts_coeff_inf, vts_coeff_delta );
+ int ires = solve_arith( pv, satom, veq_c, val, vts_coeff_inf, vts_coeff_delta );
if( ires!=0 ){
//disequalities are either strict upper or lower bounds
unsigned rmax = ( atom.getKind()==GEQ && options::cbqiModel() ) ? 1 : 2;
@@ -449,7 +455,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
//try this bound
if( subs_proc[uval].find( veq_c )==subs_proc[uval].end() ){
subs_proc[uval][veq_c] = true;
- if( addInstantiationInc( uval, pv, veq_c, uires>0 ? 1 : -1, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( uval, pv, veq_c, uires>0 ? 1 : -1, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
@@ -486,7 +492,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
val = NodeManager::currentNM()->mkNode( UMINUS, val );
val = Rewriter::rewrite( val );
}
- if( addInstantiationInc( val, pv, Node::null(), 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( val, pv, Node::null(), 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
@@ -582,7 +588,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
if( !val.isNull() ){
if( subs_proc[val].find( mbp_coeff[rr][best] )==subs_proc[val].end() ){
subs_proc[val][mbp_coeff[rr][best]] = true;
- if( addInstantiationInc( val, pv, mbp_coeff[rr][best], rr==0 ? 1 : -1, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( val, pv, mbp_coeff[rr][best], rr==0 ? 1 : -1, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
@@ -599,7 +605,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
if( !val.isNull() ){
if( subs_proc[val].find( c )==subs_proc[val].end() ){
subs_proc[val][c] = true;
- if( addInstantiationInc( val, pv, c, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( val, pv, c, 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
@@ -643,7 +649,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
if( !val.isNull() ){
if( subs_proc[val].find( Node::null() )==subs_proc[val].end() ){
subs_proc[val][Node::null()] = true;
- if( addInstantiationInc( val, pv, Node::null(), 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( val, pv, Node::null(), 0, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
@@ -664,7 +670,7 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
if( !val.isNull() ){
if( subs_proc[val].find( mbp_coeff[rr][j] )==subs_proc[val].end() ){
subs_proc[val][mbp_coeff[rr][j]] = true;
- if( addInstantiationInc( val, pv, mbp_coeff[rr][j], rr==0 ? 1 : -1, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( val, pv, mbp_coeff[rr][j], rr==0 ? 1 : -1, sf, ssf, vars, btyp, theta, i, effort, cons, curr_var ) ){
return true;
}
}
@@ -677,18 +683,18 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
}
}
- //[4] resort to using value in model
+ //[5] resort to using value in model
// do so if we are in effort=1, or if the variable is boolean, or if we are solving for a subfield of a datatype
if( ( effort>0 || pvtn.isBoolean() || !curr_var.empty() ) && d_qe->getTermDatabase()->isClosedEnumerableType( pvtn ) ){
Node mv = getModelValue( pv );
Node pv_coeff_m;
- Trace("cbqi-inst-debug") << "[4] " << i << "...try model value " << mv << std::endl;
+ Trace("cbqi-inst-debug") << "[5] " << i << "...try model value " << mv << std::endl;
int new_effort = pvtn.isBoolean() ? effort : 1;
#ifdef MBP_STRICT_ASSERTIONS
//we only resort to values in the case of booleans
Assert( ( pvtn.isInteger() ? !options::cbqiUseInfInt() : !options::cbqiUseInfReal() ) || pvtn.isBoolean() );
#endif
- if( addInstantiationInc( mv, pv, pv_coeff_m, 0, sf, ssf, vars, btyp, theta, i, new_effort, cons, curr_var ) ){
+ if( doAddInstantiationInc( mv, pv, pv_coeff_m, 0, sf, ssf, vars, btyp, theta, i, new_effort, cons, curr_var ) ){
return true;
}
}
@@ -698,9 +704,9 @@ bool CegInstantiator::addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::ve
}
-bool CegInstantiator::addInstantiationInc( Node n, Node pv, Node pv_coeff, int bt, SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
- std::vector< int >& btyp, Node theta, unsigned i, unsigned effort,
- std::map< Node, Node >& cons, std::vector< Node >& curr_var ) {
+bool CegInstantiator::doAddInstantiationInc( Node n, Node pv, Node pv_coeff, int bt, SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
+ std::vector< int >& btyp, Node theta, unsigned i, unsigned effort,
+ std::map< Node, Node >& cons, std::vector< Node >& curr_var ) {
if( Trace.isOn("cbqi-inst") ){
for( unsigned j=0; j<sf.d_subs.size(); j++ ){
Trace("cbqi-inst") << " ";
@@ -794,7 +800,7 @@ bool CegInstantiator::addInstantiationInc( Node n, Node pv, Node pv_coeff, int b
curr_var.pop_back();
is_cv = true;
}
- success = addInstantiation( sf, ssf, vars, btyp, new_theta, curr_var.empty() ? i+1 : i, effort, cons, curr_var );
+ success = doAddInstantiation( sf, ssf, vars, btyp, new_theta, curr_var.empty() ? i+1 : i, effort, cons, curr_var );
if( !success ){
if( is_cv ){
curr_var.push_back( pv );
@@ -825,12 +831,12 @@ bool CegInstantiator::addInstantiationInc( Node n, Node pv, Node pv_coeff, int b
}
}
-bool CegInstantiator::addInstantiationCoeff( SolvedForm& sf, std::vector< Node >& vars, std::vector< int >& btyp,
+bool CegInstantiator::doAddInstantiationCoeff( SolvedForm& sf, std::vector< Node >& vars, std::vector< int >& btyp,
unsigned j, std::map< Node, Node >& cons ) {
if( j==sf.d_has_coeff.size() ){
- return addInstantiation( sf.d_subs, vars, cons );
+ return doAddInstantiation( sf.d_subs, vars, cons );
}else{
Assert( std::find( vars.begin(), vars.end(), sf.d_has_coeff[j] )!=vars.end() );
unsigned index = std::find( vars.begin(), vars.end(), sf.d_has_coeff[j] )-vars.begin();
@@ -888,7 +894,7 @@ bool CegInstantiator::addInstantiationCoeff( SolvedForm& sf, std::vector< Node >
}
}
}
- if( addInstantiationCoeff( sf, vars, btyp, j+1, cons ) ){
+ if( doAddInstantiationCoeff( sf, vars, btyp, j+1, cons ) ){
return true;
}
}
@@ -899,7 +905,7 @@ bool CegInstantiator::addInstantiationCoeff( SolvedForm& sf, std::vector< Node >
}
}
-bool CegInstantiator::addInstantiation( std::vector< Node >& subs, std::vector< Node >& vars, std::map< Node, Node >& cons ) {
+bool CegInstantiator::doAddInstantiation( std::vector< Node >& subs, std::vector< Node >& vars, std::map< Node, Node >& cons ) {
if( vars.size()>d_vars.size() ){
Trace("cbqi-inst-debug") << "Reconstructing instantiations...." << std::endl;
std::map< Node, Node > subs_map;
@@ -921,7 +927,7 @@ bool CegInstantiator::addInstantiation( std::vector< Node >& subs, std::vector<
subs.push_back( subs_orig[d_var_order_index[i]] );
}
}
- bool ret = d_out->addInstantiation( subs );
+ bool ret = d_out->doAddInstantiation( subs );
#ifdef MBP_STRICT_ASSERTIONS
Assert( ret );
#endif
@@ -1121,7 +1127,7 @@ bool CegInstantiator::check() {
std::map< Node, Node > cons;
std::vector< Node > curr_var;
//try to add an instantiation
- if( addInstantiation( sf, ssf, vars, btyp, theta, 0, r==0 ? 0 : 2, cons, curr_var ) ){
+ if( doAddInstantiation( sf, ssf, vars, btyp, theta, 0, r==0 ? 0 : 2, cons, curr_var ) ){
return true;
}
}
@@ -1493,8 +1499,10 @@ void CegInstantiator::registerCounterexampleLemma( std::vector< Node >& lems, st
}
}
-//this isolates the monomial sum into solved form (pv k t), ensures t is Int if pv is Int, and t does not contain vts symbols
-int CegInstantiator::isolate( Node pv, Node atom, Node& veq_c, Node& val, Node& vts_coeff_inf, Node& vts_coeff_delta ) {
+//this isolates the atom into solved form
+// veq_c * pv <> val + vts_coeff_delta * delta + vts_coeff_inf * inf
+// ensures val is Int if pv is Int, and val does not contain vts symbols
+int CegInstantiator::solve_arith( Node pv, Node atom, Node& veq_c, Node& val, Node& vts_coeff_inf, Node& vts_coeff_delta ) {
int ires = 0;
Trace("cbqi-inst-debug") << "isolate for " << pv << " in " << atom << std::endl;
std::map< Node, Node > msum;
@@ -1602,6 +1610,46 @@ int CegInstantiator::isolate( Node pv, Node atom, Node& veq_c, Node& val, Node&
vts_coeff_inf = vts_coeff[0];
vts_coeff_delta = vts_coeff[1];
}
-
return ires;
}
+
+Node CegInstantiator::solve_dt( Node v, Node a, Node b, Node sa, Node sb ) {
+ Trace("cbqi-inst-debug2") << "Solve dt : " << v << " " << a << " " << b << " " << sa << " " << sb << std::endl;
+ Node ret;
+ if( !a.isNull() && a==v ){
+ ret = sb;
+ }else if( !b.isNull() && b==v ){
+ ret = sa;
+ }else if( !a.isNull() && a.getKind()==APPLY_CONSTRUCTOR ){
+ if( !b.isNull() && b.getKind()==APPLY_CONSTRUCTOR ){
+ if( a.getOperator()==b.getOperator() ){
+ for( unsigned i=0; i<a.getNumChildren(); i++ ){
+ Node s = solve_dt( v, a[i], b[i], sa[i], sb[i] );
+ if( !s.isNull() ){
+ return s;
+ }
+ }
+ }
+ }else{
+ unsigned cindex = Datatype::indexOf( a.getOperator().toExpr() );
+ TypeNode tn = a.getType();
+ const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
+ for( unsigned i=0; i<a.getNumChildren(); i++ ){
+ Node nn = NodeManager::currentNM()->mkNode( APPLY_SELECTOR_TOTAL, Node::fromExpr( dt[cindex][i].getSelector() ), sb );
+ Node s = solve_dt( v, a[i], Node::null(), sa[i], nn );
+ if( !s.isNull() ){
+ return s;
+ }
+ }
+ }
+ }else if( !b.isNull() && b.getKind()==APPLY_CONSTRUCTOR ){
+ return solve_dt( v, b, a, sb, sa );
+ }
+ if( !ret.isNull() ){
+ //ensure does not contain
+ if( TermDb::containsTerm( ret, v ) ){
+ ret = Node::null();
+ }
+ }
+ return ret;
+}
diff --git a/src/theory/quantifiers/ceg_instantiator.h b/src/theory/quantifiers/ceg_instantiator.h
index 9504bd407..3d7bbcb55 100644
--- a/src/theory/quantifiers/ceg_instantiator.h
+++ b/src/theory/quantifiers/ceg_instantiator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ceg_instantiator.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief counterexample-guided quantifier instantiation
**/
@@ -33,7 +33,7 @@ namespace quantifiers {
class CegqiOutput {
public:
virtual ~CegqiOutput() {}
- virtual bool addInstantiation( std::vector< Node >& subs ) = 0;
+ virtual bool doAddInstantiation( std::vector< Node >& subs ) = 0;
virtual bool isEligibleForInstantiation( Node n ) = 0;
virtual bool addLemma( Node lem ) = 0;
};
@@ -108,16 +108,16 @@ private:
};
*/
// effort=0 : do not use model value, 1: use model value, 2: one must use model value
- bool addInstantiation( SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
+ bool doAddInstantiation( SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
std::vector< int >& btyp, Node theta, unsigned i, unsigned effort,
std::map< Node, Node >& cons, std::vector< Node >& curr_var );
- bool addInstantiationInc( Node n, Node pv, Node pv_coeff, int bt, SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
+ bool doAddInstantiationInc( Node n, Node pv, Node pv_coeff, int bt, SolvedForm& sf, SolvedForm& ssf, std::vector< Node >& vars,
std::vector< int >& btyp, Node theta, unsigned i, unsigned effort,
std::map< Node, Node >& cons, std::vector< Node >& curr_var );
- bool addInstantiationCoeff( SolvedForm& sf,
+ bool doAddInstantiationCoeff( SolvedForm& sf,
std::vector< Node >& vars, std::vector< int >& btyp,
unsigned j, std::map< Node, Node >& cons );
- bool addInstantiation( std::vector< Node >& subs, std::vector< Node >& vars, std::map< Node, Node >& cons );
+ bool doAddInstantiation( std::vector< Node >& subs, std::vector< Node >& vars, std::map< Node, Node >& cons );
Node constructInstantiation( Node n, std::map< Node, Node >& subs_map, std::map< Node, Node >& cons );
Node applySubstitution( TypeNode tn, Node n, SolvedForm& sf, std::vector< Node >& vars, Node& pv_coeff, bool try_coeff = true ) {
return applySubstitution( tn, n, sf.d_subs, sf.d_coeff, sf.d_has_coeff, vars, pv_coeff, try_coeff );
@@ -130,7 +130,8 @@ private:
//get model value
Node getModelValue( Node n );
private:
- int isolate( Node v, Node atom, Node & veq_c, Node & val, Node& vts_coeff_inf, Node& vts_coeff_delta );
+ int solve_arith( Node v, Node atom, Node & veq_c, Node & val, Node& vts_coeff_inf, Node& vts_coeff_delta );
+ Node solve_dt( Node v, Node a, Node b, Node sa, Node sb );
public:
CegInstantiator( QuantifiersEngine * qe, CegqiOutput * out, bool use_vts_delta = true, bool use_vts_inf = true );
//check : add instantiations based on valuation of d_vars
diff --git a/src/theory/quantifiers/conjecture_generator.cpp b/src/theory/quantifiers/conjecture_generator.cpp
index 8e083ae1e..2cc49ef5a 100644
--- a/src/theory/quantifiers/conjecture_generator.cpp
+++ b/src/theory/quantifiers/conjecture_generator.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file conjecture_generator.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief conjecture generator class
**
@@ -34,7 +34,7 @@ struct sortConjectureScore {
};
-void OpArgIndex::addTerm( ConjectureGenerator * s, TNode n, unsigned index ){
+void OpArgIndex::addTerm( std::vector< TNode >& terms, TNode n, unsigned index ){
if( index==n.getNumChildren() ){
Assert( n.hasOperator() );
if( std::find( d_ops.begin(), d_ops.end(), n.getOperator() )==d_ops.end() ){
@@ -42,7 +42,7 @@ void OpArgIndex::addTerm( ConjectureGenerator * s, TNode n, unsigned index ){
d_op_terms.push_back( n );
}
}else{
- d_child[s->getTermDatabase()->d_arg_reps[n][index]].addTerm( s, n, index+1 );
+ d_child[terms[index]].addTerm( terms, n, index+1 );
}
}
@@ -369,7 +369,7 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
TNode n = (*ieqc_i);
if( getTermDatabase()->hasTermCurrent( n ) ){
if( isHandledTerm( n ) ){
- d_op_arg_index[r].addTerm( this, n );
+ d_op_arg_index[r].addTerm( getTermDatabase()->d_arg_reps[n], n );
}
}
++ieqc_i;
@@ -489,7 +489,7 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
d_thm_index.clear();
std::vector< Node > provenConj;
quantifiers::FirstOrderModel* m = d_quantEngine->getModel();
- for( int i=0; i<m->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<m->getNumAssertedQuantifiers(); i++ ){
Node q = m->getAssertedQuantifier( i );
Trace("thm-db-debug") << "Is " << q << " a relevant theorem?" << std::endl;
Node conjEq;
@@ -605,7 +605,8 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
std::vector< TypeNode > rt_types;
std::map< TypeNode, std::map< int, std::vector< Node > > > conj_lhs;
unsigned addedLemmas = 0;
- for( unsigned depth=1; depth<=3; depth++ ){
+ unsigned maxDepth = options::conjectureGenMaxDepth();
+ for( unsigned depth=1; depth<=maxDepth; depth++ ){
Trace("sg-proc") << "Generate relevant LHS at depth " << depth << "..." << std::endl;
Trace("sg-rel-term") << "Relevant terms of depth " << depth << " : " << std::endl;
//set up environment
@@ -1167,6 +1168,8 @@ void ConjectureGenerator::processCandidateConjecture( TNode lhs, TNode rhs, unsi
d_waiting_conjectures_score.push_back( score );
d_waiting_conjectures[lhs].push_back( rhs );
d_waiting_conjectures[rhs].push_back( lhs );
+ }else{
+ Trace("sg-conjecture-debug2") << "...do not consider " << lhs << " == " << rhs << ", score = " << score << std::endl;
}
}
@@ -1273,7 +1276,7 @@ bool ConjectureGenerator::notifySubstitution( TNode glhs, std::map< TNode, TNode
}
Trace("sg-cconj-debug") << "Evaluate RHS : : " << rhs << std::endl;
//get the representative of rhs with substitution subs
- TNode grhs = getTermDatabase()->evaluateTerm( rhs, subs, true );
+ TNode grhs = getTermDatabase()->getEntailedTerm( rhs, subs, true );
Trace("sg-cconj-debug") << "...done evaluating term, got : " << grhs << std::endl;
if( !grhs.isNull() ){
if( glhs!=grhs ){
@@ -1569,10 +1572,12 @@ bool TermGenerator::getNextMatch( TermGenEnv * s, TNode eqc, std::map< TypeNode,
if( d_match_status_child_num==0 ){
//initial binding
TNode f = s->getTgFunc( d_typ, d_status_num );
- std::map< TNode, TermArgTrie >::iterator it = s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.find( eqc );
- if( it!=s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.end() ){
- d_match_children.push_back( it->second.d_data.begin() );
- d_match_children_end.push_back( it->second.d_data.end() );
+ //std::map< TNode, TermArgTrie >::iterator it = s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.find( eqc );
+ Assert( !eqc.isNull() );
+ TermArgTrie * tat = s->getTermDatabase()->getTermArgTrie( eqc, f );
+ if( tat ){
+ d_match_children.push_back( tat->d_data.begin() );
+ d_match_children_end.push_back( tat->d_data.end() );
}else{
d_match_status++;
d_match_status_child_num--;
diff --git a/src/theory/quantifiers/conjecture_generator.h b/src/theory/quantifiers/conjecture_generator.h
index 3aa932296..c89d0f2ee 100644
--- a/src/theory/quantifiers/conjecture_generator.h
+++ b/src/theory/quantifiers/conjecture_generator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file conjecture_generator.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief conjecture generator class
**/
@@ -39,7 +39,7 @@ public:
std::map< TNode, OpArgIndex > d_child;
std::vector< TNode > d_ops;
std::vector< TNode > d_op_terms;
- void addTerm( ConjectureGenerator * s, TNode n, unsigned index = 0 );
+ void addTerm( std::vector< TNode >& terms, TNode n, unsigned index = 0 );
Node getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args );
void getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms );
};
diff --git a/src/theory/quantifiers/equality_infer.cpp b/src/theory/quantifiers/equality_infer.cpp
new file mode 100644
index 000000000..c3064116f
--- /dev/null
+++ b/src/theory/quantifiers/equality_infer.cpp
@@ -0,0 +1,427 @@
+/********************* */
+/*! \file equality_infer.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Method for inferring equalities between arithmetic equivalence classes,
+ ** inspired by "A generalization of Shostak's method for combining decision procedures" Barrett et al. Figure 1.
+ **
+ **/
+
+#include "theory/quantifiers/equality_infer.h"
+#include "theory/quantifiers/quant_util.h"
+#include "context/context_mm.h"
+
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+using namespace std;
+
+namespace CVC4 {
+
+EqualityInference::EqcInfo::EqcInfo(context::Context* c) : d_rep( c ), d_valid( c, false ), d_solved( c, false ), d_master(c)
+//, d_rep_exp(c), d_uselist(c)
+{
+
+}
+
+EqualityInference::EqualityInference( context::Context* c, bool trackExp ) :
+d_c( c ), d_trackExplain( trackExp ), d_elim_vars( c ),
+d_rep_to_eqc( c ), d_rep_exp( c ), d_uselist( c ), d_pending_merges( c ), d_pending_merge_exp( c ){
+ d_one = NodeManager::currentNM()->mkConst( Rational( 1 ) );
+ d_true = NodeManager::currentNM()->mkConst( true );
+}
+
+EqualityInference::~EqualityInference(){
+ for( std::map< Node, EqcInfo * >::iterator it = d_eqci.begin(); it != d_eqci.end(); ++it ){
+ delete it->second;
+ }
+}
+
+void EqualityInference::addToExplanation( std::vector< Node >& exp, Node e ) {
+ if( std::find( exp.begin(), exp.end(), e )==exp.end() ){
+ Trace("eq-infer-debug2") << "......add to explanation " << e << std::endl;
+ exp.push_back( e );
+ }
+}
+
+void EqualityInference::addToExplanationEqc( std::vector< Node >& exp, Node eqc ) {
+ NodeListMap::iterator re_i = d_rep_exp.find( eqc );
+ if( re_i!=d_rep_exp.end() ){
+ for( unsigned i=0; i<(*re_i).second->size(); i++ ){
+ addToExplanation( exp, (*(*re_i).second)[i] );
+ }
+ }
+ //for( unsigned i=0; i<d_eqci[n]->d_rep_exp.size(); i++ ){
+ // addToExplanation( exp, d_eqci[n]->d_rep_exp[i] );
+ //}
+}
+
+void EqualityInference::addToExplanationEqc( Node eqc, std::vector< Node >& exp_to_add ) {
+ NodeListMap::iterator re_i = d_rep_exp.find( eqc );
+ NodeList* re;
+ if( re_i != d_rep_exp.end() ){
+ re = (*re_i).second;
+ }else{
+ re = new(d_c->getCMM()) NodeList( true, d_c, false, context::ContextMemoryAllocator<TNode>(d_c->getCMM()) );
+ d_rep_exp.insertDataFromContextMemory( eqc, re );
+ }
+ for( unsigned i=0; i<exp_to_add.size(); i++ ){
+ re->push_back( exp_to_add[i] );
+ }
+ //for( unsigned i=0; i<exp_to_add.size(); i++ ){
+ // eqci->d_rep_exp.push_back( exp_to_add[i] );
+ //}
+}
+
+Node EqualityInference::getMaster( Node t, EqcInfo * eqc, bool& updated, Node new_m ) {
+ if( !eqc->d_master.get().isNull() ){
+ if( eqc->d_master.get()==t ){
+ if( !new_m.isNull() && t!=new_m ){
+ eqc->d_master = new_m;
+ updated = true;
+ return new_m;
+ }else{
+ return t;
+ }
+ }else{
+ Assert( d_eqci.find( eqc->d_master.get() )!=d_eqci.end() );
+ EqcInfo * eqc_m = d_eqci[eqc->d_master.get()];
+ Node m = getMaster( eqc->d_master.get(), eqc_m, updated, new_m );
+ eqc->d_master = m;
+ return m;
+ }
+ }else{
+ return Node::null();
+ }
+}
+
+//update the internal "master" representative of the equivalence class, return true if the merge was non-redundant
+bool EqualityInference::updateMaster( Node t1, Node t2, EqcInfo * eqc1, EqcInfo * eqc2 ) {
+ bool updated = false;
+ Node m1 = getMaster( t1, eqc1, updated );
+ if( m1.isNull() ){
+ eqc1->d_master = t2;
+ if( eqc2->d_master.get().isNull() ){
+ eqc2->d_master = t2;
+ }
+ return true;
+ }else{
+ updated = false;
+ Node m2 = getMaster( t2, eqc2, updated, m1);
+ if( m2.isNull() ){
+ eqc2->d_master = m1;
+ return true;
+ }else{
+ return updated;
+ }
+ }
+}
+
+void EqualityInference::eqNotifyNewClass(TNode t) {
+ if( t.getType().isReal() ){
+ Trace("eq-infer") << "Notify equivalence class : " << t << std::endl;
+ EqcInfo * eqci;
+ std::map< Node, EqcInfo * >::iterator itec = d_eqci.find( t );
+ if( itec==d_eqci.end() ){
+ eqci = new EqcInfo( d_c );
+ d_eqci[t] = eqci;
+ }else{
+ eqci = itec->second;
+ }
+ Assert( !eqci->d_valid.get() );
+ if( !eqci->d_solved.get() ){
+ //somewhat strange: t may not be in rewritten form
+ Node r = Rewriter::rewrite( t );
+ std::map< Node, Node > msum;
+ if( QuantArith::getMonomialSum( r, msum ) ){
+ Trace("eq-infer-debug2") << "...process monomial sum, size = " << msum.size() << std::endl;
+ eqci->d_valid = true;
+ bool changed = false;
+ std::vector< Node > exp;
+ std::vector< Node > children;
+ for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ) {
+ Trace("eq-infer-debug2") << "...process child " << it->first << ", " << it->second << std::endl;
+ if( !it->first.isNull() ){
+ Node n = it->first;
+ BoolMap::const_iterator itv = d_elim_vars.find( n );
+ if( itv!=d_elim_vars.end() ){
+ changed = true;
+ Assert( d_eqci.find( n )!=d_eqci.end() );
+ Assert( n!=t );
+ Assert( d_eqci[n]->d_solved.get() );
+ Trace("eq-infer-debug2") << "......its solved form is " << d_eqci[n]->d_rep.get() << std::endl;
+ if( d_trackExplain ){
+ //track the explanation: justified by explanation for each substitution
+ addToExplanationEqc( exp, n );
+ }
+ n = d_eqci[n]->d_rep;
+ Assert( !n.isNull() );
+ }
+ if( it->second.isNull() ){
+ children.push_back( n );
+ }else{
+ children.push_back( NodeManager::currentNM()->mkNode( MULT, it->second, n ) );
+ }
+ }else{
+ Assert( !it->second.isNull() );
+ children.push_back( it->second );
+ }
+ }
+ Trace("eq-infer-debug2") << "...children size = " << children.size() << std::endl;
+ bool mvalid = true;
+ if( changed ){
+ r = children.size()==1 ? children[0] : NodeManager::currentNM()->mkNode( PLUS, children );
+ Trace("eq-infer-debug2") << "...pre-rewrite : " << r << std::endl;
+ r = Rewriter::rewrite( r );
+ msum.clear();
+ if( !QuantArith::getMonomialSum( r, msum ) ){
+ mvalid = false;
+ }
+ }
+ Trace("eq-infer") << "...value is " << r << std::endl;
+ setEqcRep( t, r, exp, eqci );
+ if( mvalid ){
+ for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ){
+ if( !it->first.isNull() ){
+ addToUseList( it->first, t );
+ }
+ }
+ }
+ }else{
+ eqci->d_valid = false;
+ }
+ }
+ }
+}
+
+void EqualityInference::addToUseList( Node used, Node eqc ) {
+#if 1
+ NodeListMap::iterator ul_i = d_uselist.find( used );
+ NodeList* ul;
+ if( ul_i != d_uselist.end() ){
+ ul = (*ul_i).second;
+ }else{
+ ul = new(d_c->getCMM()) NodeList( true, d_c, false, context::ContextMemoryAllocator<TNode>(d_c->getCMM()) );
+ d_uselist.insertDataFromContextMemory( used, ul );
+ }
+ Trace("eq-infer-debug") << " add to use list : " << used << " -> " << eqc << std::endl;
+ (*ul).push_back( eqc );
+#else
+ std::map< Node, EqcInfo * >::iterator itu = d_eqci.find( used );
+ EqcInfo * eqci_used;
+ if( itu==d_eqci.end() ){
+ eqci_used = new EqcInfo( d_c );
+ d_eqci[used] = eqci_used;
+ }else{
+ eqci_used = itu->second;
+ }
+ Trace("eq-infer-debug") << " add to use list : " << used << " -> " << eqc << std::endl;
+ eqci_used->d_uselist.push_back( eqc );
+#endif
+}
+
+void EqualityInference::setEqcRep( Node t, Node r, std::vector< Node >& exp_to_add, EqcInfo * eqci ) {
+ eqci->d_rep = r;
+ if( d_trackExplain ){
+ addToExplanationEqc( t, exp_to_add );
+ }
+ //if this is an active equivalence class
+ if( eqci->d_valid.get() ){
+ Trace("eq-infer-debug") << "Set eqc rep " << t << " -> " << r << std::endl;
+ NodeMap::const_iterator itr = d_rep_to_eqc.find( r );
+ if( itr==d_rep_to_eqc.end() ){
+ d_rep_to_eqc[r] = t;
+ }else{
+ //merge two equivalence classes
+ Node t2 = (*itr).second;
+ //check if it is valid
+ std::map< Node, EqcInfo * >::iterator itc = d_eqci.find( t2 );
+ if( itc!=d_eqci.end() && itc->second->d_valid.get() ){
+ //if we haven't already determined they should be merged
+ if( updateMaster( t, t2, eqci, itc->second ) ){
+ Trace("eq-infer") << "Infer two equivalence classes are equal : " << t << " " << t2 << std::endl;
+ Trace("eq-infer") << " since they both normalize to : " << r << std::endl;
+ d_pending_merges.push_back( t.eqNode( t2 ) );
+ if( d_trackExplain ){
+ std::vector< Node > exp;
+ for( unsigned j=0; j<2; j++ ){
+ addToExplanationEqc( exp, j==0 ? t : t2 );
+ }
+ Node exp_n = exp.empty() ? d_true : ( exp.size()==1 ? exp[0] : NodeManager::currentNM()->mkNode( AND, exp ) );
+ Trace("eq-infer") << " explanation : " << exp_n << std::endl;
+ d_pending_merge_exp.push_back( exp_n );
+ }
+ }
+ }
+ }
+ }
+}
+
+void EqualityInference::eqNotifyMerge(TNode t1, TNode t2) {
+ Assert( !t1.isNull() );
+ Assert( !t2.isNull() );
+ std::map< Node, EqcInfo * >::iterator itv1 = d_eqci.find( t1 );
+ if( itv1!=d_eqci.end() ){
+ std::map< Node, EqcInfo * >::iterator itv2 = d_eqci.find( t2 );
+ if( itv2!=d_eqci.end() ){
+ Trace("eq-infer") << "Merge equivalence classes : " << t2 << " into " << t1 << std::endl;
+ Node tr1 = itv1->second->d_rep;
+ Node tr2 = itv2->second->d_rep;
+ itv2->second->d_valid = false;
+ Trace("eq-infer") << "Representatives : " << tr2 << " into " << tr1 << std::endl;
+ if( tr1!=tr2 ){
+ Node eq = tr1.eqNode( tr2 );
+ std::map< Node, Node > msum;
+ if( QuantArith::getMonomialSumLit( eq, msum ) ){
+ Node v_solve;
+ //solve for variables with no coefficient
+ if( Trace.isOn("eq-infer-debug2") ){
+ Trace("eq-infer-debug2") << "Monomial sum : " << std::endl;
+ for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ) {
+ Trace("eq-infer-debug2") << " " << it->first << " * " << it->second << std::endl;
+ }
+ }
+ for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ) {
+ Node n = it->first;
+ if( !n.isNull() ){
+ bool canSolve = false;
+ if( it->second.isNull() ){
+ canSolve = true;
+ }else{
+ //Assert( it->second.isConst() );
+ Rational r = it->second.getConst<Rational>();
+ canSolve = r.isOne() || r.isNegativeOne();
+ }
+ if( canSolve ){
+ v_solve = n;
+ break;
+ }
+ }
+ }
+ Trace("eq-infer-debug") << "solve for variable : " << v_solve << std::endl;
+ if( !v_solve.isNull() ){
+ //solve for v_solve
+ Node veq;
+ if( QuantArith::isolate( v_solve, msum, veq, kind::EQUAL, true )==1 ){
+ Node v_value = veq[1];
+ Trace("eq-infer") << "...solved " << v_solve << " == " << v_value << std::endl;
+ Assert( d_elim_vars.find( v_solve )==d_elim_vars.end() );
+ d_elim_vars[v_solve] = true;
+ //store value in eqc info
+ EqcInfo * eqci_solved;
+ std::map< Node, EqcInfo * >::iterator itec = d_eqci.find( v_solve );
+ if( itec==d_eqci.end() ){
+ eqci_solved = new EqcInfo( d_c );
+ d_eqci[v_solve] = eqci_solved;
+ }else{
+ eqci_solved = itec->second;
+ }
+ eqci_solved->d_solved = true;
+ eqci_solved->d_rep = v_value;
+ //track the explanation
+ std::vector< Node > exp;
+ if( d_trackExplain ){
+ //explanation is t1 = t2 + their explanations
+ exp.push_back( t1.eqNode( t2 ) );
+ for( unsigned i=0; i<2; i++ ){
+ addToExplanationEqc( exp, i==0 ? t1 : t2 );
+ }
+ if( Trace.isOn("eq-infer-debug") ){
+ Trace("eq-infer-debug") << " explanation for solving " << v_solve << " is ";
+ for( unsigned i=0; i<exp.size(); i++ ){
+ Trace("eq-infer-debug") << exp[i] << " ";
+ }
+ Trace("eq-infer-debug") << std::endl;
+ }
+ addToExplanationEqc( v_solve, exp );
+ }
+
+ std::vector< Node > new_use;
+ for( std::map< Node, Node >::iterator itmm = msum.begin(); itmm != msum.end(); ++itmm ){
+ Node n = itmm->first;
+ if( !n.isNull() && n!=v_solve ){
+ new_use.push_back( n );
+ addToUseList( n, v_solve );
+ }
+ }
+
+ //go through all equivalence classes that may refer to v_solve
+ std::map< Node, bool > processed;
+ processed[v_solve] = true;
+ NodeListMap::iterator ul_i = d_uselist.find( v_solve );
+ if( ul_i != d_uselist.end() ){
+ NodeList* ul = (*ul_i).second;
+ Trace("eq-infer-debug") << " use list size = " << ul->size() << std::endl;
+ for( unsigned j=0; j<ul->size(); j++ ){
+ Node r = (*ul)[j];
+ //Trace("eq-infer-debug") << " use list size = " << eqci_solved->d_uselist.size() << std::endl;
+ //for( unsigned j=0; j<eqci_solved->d_uselist.size(); j++ ){
+ // Node r = eqci_solved->d_uselist[j];
+ if( processed.find( r )==processed.end() ){
+ processed[r] = true;
+ std::map< Node, EqcInfo * >::iterator itt = d_eqci.find( r );
+ if( itt!=d_eqci.end() && ( itt->second->d_valid || itt->second->d_solved ) ){
+ std::map< Node, Node > msum2;
+ if( QuantArith::getMonomialSum( itt->second->d_rep.get(), msum2 ) ){
+ std::map< Node, Node >::iterator itm = msum2.find( v_solve );
+ if( itm!=msum2.end() ){
+ //substitute in solved form
+ std::map< Node, Node >::iterator itm2 = msum2.find( v_value );
+ if( itm2 == msum2.end() ){
+ msum2[v_value] = itm->second;
+ }else{
+ msum2[v_value] = NodeManager::currentNM()->mkNode( PLUS, itm2->second.isNull() ? d_one : itm2->second,
+ itm->second.isNull() ? d_one : itm->second );
+ }
+ msum2.erase( itm );
+ Node rr = QuantArith::mkNode( msum2 );
+ rr = Rewriter::rewrite( rr );
+ Trace("eq-infer") << "......update " << itt->first << " => " << rr << std::endl;
+ setEqcRep( itt->first, rr, exp, itt->second );
+ //update use list
+ for( unsigned i=0; i<new_use.size(); i++ ){
+ addToUseList( new_use[i], r );
+ }
+ }
+ }else{
+ itt->second->d_valid = false;
+ }
+ }
+ }
+ }
+ }
+ Trace("eq-infer") << "...finished solved." << std::endl;
+ }
+ }
+ }
+ }
+ }else{
+ //no information to merge
+ }
+ }else{
+ //carry information (this might happen for non-linear t1 and linear t2?)
+ std::map< Node, EqcInfo * >::iterator itv2 = d_eqci.find( t2 );
+ if( itv2!=d_eqci.end() ){
+ d_eqci[t1] = d_eqci[t2];
+ d_eqci[t2] = NULL;
+ }
+ }
+}
+
+Node EqualityInference::getPendingMergeExplanation( unsigned i ) {
+ if( d_trackExplain ){
+ return d_pending_merge_exp[i];
+ }else{
+ return d_pending_merges[i];
+ }
+}
+
+}
diff --git a/src/theory/quantifiers/equality_infer.h b/src/theory/quantifiers/equality_infer.h
new file mode 100644
index 000000000..93c7bd080
--- /dev/null
+++ b/src/theory/quantifiers/equality_infer.h
@@ -0,0 +1,103 @@
+/********************* */
+/*! \file equality_infer.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief additional inference for equalities
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANTIFIERS__EQUALITY_INFER_H
+#define __CVC4__THEORY__QUANTIFIERS__EQUALITY_INFER_H
+
+#include <ext/hash_set>
+#include <iostream>
+#include <map>
+#include <vector>
+
+#include "context/context.h"
+#include "context/context_mm.h"
+#include "context/cdhashmap.h"
+#include "context/cdchunk_list.h"
+#include "context/cdhashset.h"
+#include "theory/theory.h"
+
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class EqualityInference
+{
+ typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap;
+ typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap;
+ typedef context::CDChunkList<Node> NodeList;
+ typedef context::CDHashMap< Node, NodeList *, NodeHashFunction > NodeListMap;
+private:
+ context::Context * d_c;
+ Node d_one;
+ Node d_true;
+ class EqcInfo {
+ public:
+ EqcInfo(context::Context* c);
+ ~EqcInfo(){}
+ context::CDO< Node > d_rep;
+ //whether the eqc of this info is a representative and d_rep can been computed successfully
+ context::CDO< bool > d_valid;
+ //whether the eqc of this info is a solved variable
+ context::CDO< bool > d_solved;
+ //master equivalence class (a union find)
+ context::CDO< Node > d_master;
+ //a vector of equalities t1=t2 for which eqNotifyMerge(t1,t2) was called that explains d_rep
+ //NodeList d_rep_exp;
+ //the list of other eqc where this variable may be appear
+ //NodeList d_uselist;
+ };
+
+ /** track explanations */
+ bool d_trackExplain;
+ /** information necessary for equivalence classes */
+ BoolMap d_elim_vars;
+ std::map< Node, EqcInfo * > d_eqci;
+ NodeMap d_rep_to_eqc;
+ NodeListMap d_rep_exp;
+ /** set eqc rep */
+ void setEqcRep( Node t, Node r, std::vector< Node >& exp_to_add, EqcInfo * eqci );
+ /** use list */
+ NodeListMap d_uselist;
+ void addToUseList( Node used, Node eqc );
+ /** pending merges */
+ NodeList d_pending_merges;
+ NodeList d_pending_merge_exp;
+ /** add to explanation */
+ void addToExplanation( std::vector< Node >& exp, Node e );
+ void addToExplanationEqc( std::vector< Node >& exp, Node eqc );
+ void addToExplanationEqc( Node eqc, std::vector< Node >& exp_to_add );
+ /** for setting master/slave */
+ Node getMaster( Node t, EqcInfo * eqc, bool& updated, Node new_m = Node::null() );
+ bool updateMaster( Node t1, Node t2, EqcInfo * eqc1, EqcInfo * eqc2 );
+public:
+ //second argument is whether explanations should be tracked
+ EqualityInference(context::Context* c, bool trackExp = false);
+ virtual ~EqualityInference();
+ /** input : notification when equality engine is updated */
+ void eqNotifyNewClass(TNode t);
+ void eqNotifyMerge(TNode t1, TNode t2);
+ /** output : inferred equalities */
+ unsigned getNumPendingMerges() { return d_pending_merges.size(); }
+ Node getPendingMerge( unsigned i ) { return d_pending_merges[i]; }
+ Node getPendingMergeExplanation( unsigned i );
+};
+
+}
+}
+}
+
+#endif
diff --git a/src/theory/quantifiers/first_order_model.cpp b/src/theory/quantifiers/first_order_model.cpp
index 272f16be8..a833f48d2 100644
--- a/src/theory/quantifiers/first_order_model.cpp
+++ b/src/theory/quantifiers/first_order_model.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file first_order_model.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of model engine model class
**/
@@ -30,24 +30,43 @@ using namespace CVC4::theory;
using namespace CVC4::theory::quantifiers;
using namespace CVC4::theory::quantifiers::fmcheck;
+struct sortQuantifierRelevance {
+ FirstOrderModel * d_fm;
+ bool operator() (Node i, Node j) {
+ int wi = d_fm->getRelevanceValue( i );
+ int wj = d_fm->getRelevanceValue( j );
+ if( wi==wj ){
+ return i<j;
+ }else{
+ return wi<wj;
+ }
+ }
+};
+
FirstOrderModel::FirstOrderModel(QuantifiersEngine * qe, context::Context* c, std::string name ) :
TheoryModel( c, name, true ),
d_qe( qe ), d_forall_asserts( c ), d_isModelSet( c, false ){
+ d_rlv_count = 0;
+}
+
+void FirstOrderModel::assertQuantifier( Node n ){
+ if( n.getKind()==FORALL ){
+ d_forall_asserts.push_back( n );
+ }else if( n.getKind()==NOT ){
+ Assert( n[0].getKind()==FORALL );
+ }
+}
+unsigned FirstOrderModel::getNumAssertedQuantifiers() {
+ return d_forall_asserts.size();
}
-void FirstOrderModel::assertQuantifier( Node n, bool reduced ){
- if( !reduced ){
- if( n.getKind()==FORALL ){
- d_forall_asserts.push_back( n );
- }else if( n.getKind()==NOT ){
- Assert( n[0].getKind()==FORALL );
- }
+Node FirstOrderModel::getAssertedQuantifier( unsigned i, bool ordered ) {
+ if( !ordered || d_forall_rlv_assert.empty() ){
+ return d_forall_asserts[i];
}else{
- Assert( n.getKind()==FORALL );
- Assert( d_forall_to_reduce.find( n )==d_forall_to_reduce.end() );
- d_forall_to_reduce[n] = true;
- Trace("quant") << "Mark to reduce : " << n << std::endl;
+ Assert( d_forall_rlv_assert.size()==d_forall_asserts.size() );
+ return d_forall_rlv_assert[i];
}
}
@@ -81,11 +100,11 @@ void FirstOrderModel::initialize() {
processInitialize( true );
//this is called after representatives have been chosen and the equality engine has been built
//for each quantifier, collect all operators we care about
- for( int i=0; i<getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<getNumAssertedQuantifiers(); i++ ){
Node f = getAssertedQuantifier( i );
if( d_quant_var_id.find( f )==d_quant_var_id.end() ){
- for(unsigned i=0; i<f[0].getNumChildren(); i++){
- d_quant_var_id[f][f[0][i]] = i;
+ for(unsigned j=0; j<f[0].getNumChildren(); j++){
+ d_quant_var_id[f][f[0][j]] = j;
}
}
processInitializeQuantifier( f );
@@ -122,20 +141,72 @@ Node FirstOrderModel::getSomeDomainElement(TypeNode tn){
/** needs check */
bool FirstOrderModel::checkNeeded() {
- return d_forall_asserts.size()>0 || !d_forall_to_reduce.empty();
-}
-
-/** mark reduced */
-void FirstOrderModel::markQuantifierReduced( Node q ) {
- Assert( d_forall_to_reduce.find( q )!=d_forall_to_reduce.end() );
- d_forall_to_reduce.erase( q );
- Trace("quant") << "Mark reduced : " << q << std::endl;
+ return d_forall_asserts.size()>0;
}
void FirstOrderModel::reset_round() {
d_quant_active.clear();
+
+ //order the quantified formulas
+ if( !d_forall_rlv_vec.empty() ){
+ Trace("fm-relevant") << "Build sorted relevant list..." << std::endl;
+ d_forall_rlv_assert.clear();
+ Trace("fm-relevant-debug") << "Mark asserted quantified formulas..." << std::endl;
+ std::map< Node, bool > qassert;
+ for( unsigned i=0; i<d_forall_asserts.size(); i++ ){
+ qassert[d_forall_asserts[i]] = true;
+ }
+ Trace("fm-relevant-debug") << "Sort the relevant quantified formulas..." << std::endl;
+ sortQuantifierRelevance sqr;
+ sqr.d_fm = this;
+ std::sort( d_forall_rlv_vec.begin(), d_forall_rlv_vec.end(), sqr );
+ Trace("fm-relevant-debug") << "Add relevant asserted formulas..." << std::endl;
+ for( int i=(int)(d_forall_rlv_vec.size()-1); i>=0; i-- ){
+ Node q = d_forall_rlv_vec[i];
+ if( qassert.find( q )!=qassert.end() ){
+ Trace("fm-relevant") << " " << d_forall_rlv[q] << " : " << q << std::endl;
+ d_forall_rlv_assert.push_back( q );
+ }
+ }
+ Trace("fm-relevant-debug") << "Add remaining asserted formulas..." << std::endl;
+ for( unsigned i=0; i<d_forall_asserts.size(); i++ ){
+ Node q = d_forall_asserts[i];
+ if( std::find( d_forall_rlv_assert.begin(), d_forall_rlv_assert.end(), q )==d_forall_rlv_assert.end() ){
+ d_forall_rlv_assert.push_back( q );
+ }else{
+ Trace("fm-relevant-debug") << "...already included " << q << std::endl;
+ }
+ }
+ Trace("fm-relevant-debug") << "Sizes : " << d_forall_rlv_assert.size() << " " << d_forall_asserts.size() << std::endl;
+ Assert( d_forall_rlv_assert.size()==d_forall_asserts.size() );
+ }
+}
+
+void FirstOrderModel::markRelevant( Node q ) {
+ if( q!=d_last_forall_rlv ){
+ Trace("fm-relevant") << "Mark relevant : " << q << std::endl;
+ if( std::find( d_forall_rlv_vec.begin(), d_forall_rlv_vec.end(), q )==d_forall_rlv_vec.end() ){
+ d_forall_rlv_vec.push_back( q );
+ }
+ d_forall_rlv[ q ] = d_rlv_count;
+ d_rlv_count++;
+ d_last_forall_rlv = q;
+ }
}
+int FirstOrderModel::getRelevanceValue( Node q ) {
+ std::map< Node, unsigned >::iterator it = d_forall_rlv.find( q );
+ if( it==d_forall_rlv.end() ){
+ return -1;
+ }else{
+ return it->second;
+ }
+}
+
+//bool FirstOrderModel::isQuantifierAsserted( TNode q ) {
+// return d_forall_asserts.find( q )!=d_forall_asserts.end();
+//}
+
void FirstOrderModel::setQuantifierActive( TNode q, bool active ) {
d_quant_active[q] = active;
}
diff --git a/src/theory/quantifiers/first_order_model.h b/src/theory/quantifiers/first_order_model.h
index d42eb61e3..cbe83cfa5 100644
--- a/src/theory/quantifiers/first_order_model.h
+++ b/src/theory/quantifiers/first_order_model.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file first_order_model.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Model extended classes
**/
@@ -49,8 +49,12 @@ protected:
QuantifiersEngine * d_qe;
/** list of quantifiers asserted in the current context */
context::CDList<Node> d_forall_asserts;
- /** list of quantifiers that have been marked to reduce */
- std::map< Node, bool > d_forall_to_reduce;
+ /** quantified formulas marked as relevant */
+ unsigned d_rlv_count;
+ std::map< Node, unsigned > d_forall_rlv;
+ std::vector< Node > d_forall_rlv_vec;
+ Node d_last_forall_rlv;
+ std::vector< Node > d_forall_rlv_assert;
/** is model set */
context::CDO< bool > d_isModelSet;
/** get variable id */
@@ -59,13 +63,11 @@ protected:
virtual Node getCurrentUfModelValue( Node n, std::vector< Node > & args, bool partial ) = 0;
public: //for Theory Quantifiers:
/** assert quantifier */
- void assertQuantifier( Node n, bool reduced = false );
+ void assertQuantifier( Node n );
/** get number of asserted quantifiers */
- int getNumAssertedQuantifiers() { return (int)d_forall_asserts.size(); }
+ unsigned getNumAssertedQuantifiers();
/** get asserted quantifier */
- Node getAssertedQuantifier( int i ) { return d_forall_asserts[i]; }
- /** get number to reduce quantifiers */
- unsigned getNumToReduceQuantifiers() { return d_forall_to_reduce.size(); }
+ Node getAssertedQuantifier( unsigned i, bool ordered = false );
/** initialize model for term */
void initializeModelForTerm( Node n, std::map< Node, bool >& visited );
virtual void processInitializeModelForTerm( Node n ) = 0;
@@ -94,14 +96,16 @@ public:
Node getSomeDomainElement(TypeNode tn);
/** do we need to do any work? */
bool checkNeeded();
- /** mark reduced */
- void markQuantifierReduced( Node q );
private:
//list of inactive quantified formulas
std::map< TNode, bool > d_quant_active;
public:
/** reset round */
void reset_round();
+ /** mark quantified formula relevant */
+ void markRelevant( Node q );
+ /** get relevance value */
+ int getRelevanceValue( Node q );
/** set quantified formula active/inactive
* a quantified formula may be set inactive if for instance:
* - it is entailed by other quantified formulas
diff --git a/src/theory/quantifiers/full_model_check.cpp b/src/theory/quantifiers/full_model_check.cpp
index ff0da13e1..33c853328 100644
--- a/src/theory/quantifiers/full_model_check.cpp
+++ b/src/theory/quantifiers/full_model_check.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file full_model_check.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of full model check class
**/
@@ -350,11 +350,11 @@ void FullModelChecker::preProcessBuildModel(TheoryModel* m, bool fullModel) {
}
//do not have to introduce terms for sorts of domains of quantified formulas if we are allowed to assume empty sorts
if( !options::fmfEmptySorts() ){
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
Node q = fm->getAssertedQuantifier( i );
//make sure all types are set
- for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
- preInitializeType( fm, q[0][i].getType() );
+ for( unsigned j=0; j<q[0].getNumChildren(); j++ ){
+ preInitializeType( fm, q[0][j].getType() );
}
}
}
@@ -411,6 +411,11 @@ void FullModelChecker::processBuildModel(TheoryModel* m, bool fullModel){
Node r = fm->getUsedRepresentative(n);
Trace("fmc-model-debug") << n << " -> " << r << std::endl;
//AlwaysAssert( fm->areEqual( fm->d_uf_terms[op][i], r ) );
+ }else{
+ if( Trace.isOn("fmc-model-debug") ){
+ Node r = fm->getUsedRepresentative(n);
+ Trace("fmc-model-debug") << "[redundant] " << n << " -> " << r << std::endl;
+ }
}
}
Trace("fmc-model-debug") << std::endl;
@@ -456,7 +461,7 @@ void FullModelChecker::processBuildModel(TheoryModel* m, bool fullModel){
}
}
if( !isStar && !ri.isConst() ){
- Trace("fmc-warn") << "Warning : model has non-constant argument in model " << ri << " (from " << c[i] << ")" << std::endl;
+ Trace("fmc-warn") << "Warning : model for " << op << " has non-constant argument in model " << ri << " (from " << c[i] << ")" << std::endl;
Assert( false );
}
entry_children.push_back(ri);
@@ -464,7 +469,7 @@ void FullModelChecker::processBuildModel(TheoryModel* m, bool fullModel){
Node n = NodeManager::currentNM()->mkNode( APPLY_UF, children );
Node nv = fm->getUsedRepresentative( v );
if( !nv.isConst() ){
- Trace("fmc-warn") << "Warning : model has non-constant value in model " << nv << std::endl;
+ Trace("fmc-warn") << "Warning : model for " << op << " has non-constant value in model " << nv << std::endl;
Assert( false );
}
Node en = (useSimpleModels() && hasNonStar) ? n : NodeManager::currentNM()->mkNode( APPLY_UF, entry_children );
@@ -586,6 +591,7 @@ void FullModelChecker::debugPrint(const char * tr, Node n, bool dispStar) {
bool FullModelChecker::doExhaustiveInstantiation( FirstOrderModel * fm, Node f, int effort ) {
Trace("fmc") << "Full model check " << f << ", effort = " << effort << "..." << std::endl;
+ Assert( !d_qe->inConflict() );
if( optUseModel() ){
FirstOrderModelFmc * fmfmc = fm->asFirstOrderModelFmc();
if (effort==0) {
@@ -614,7 +620,7 @@ bool FullModelChecker::doExhaustiveInstantiation( FirstOrderModel * fm, Node f,
//consider all entries going to non-true
for (unsigned i=0; i<d_quant_models[f].d_cond.size(); i++) {
- if( d_quant_models[f].d_value[i]!=d_true) {
+ if( d_quant_models[f].d_value[i]!=d_true ) {
Trace("fmc-inst") << "Instantiate based on " << d_quant_models[f].d_cond[i] << "..." << std::endl;
bool hasStar = false;
std::vector< Node > inst;
@@ -676,15 +682,21 @@ bool FullModelChecker::doExhaustiveInstantiation( FirstOrderModel * fm, Node f,
}else{
//just add the instance
d_triedLemmas++;
- if( d_qe->addInstantiation( f, inst ) ){
+ if( d_qe->addInstantiation( f, inst, true ) ){
Trace("fmc-debug-inst") << "** Added instantiation." << std::endl;
d_addedLemmas++;
- if( options::fmfOneInstPerRound() ){
+ if( d_qe->inConflict() || options::fmfOneInstPerRound() ){
break;
}
}else{
Trace("fmc-debug-inst") << "** Instantiation was duplicate." << std::endl;
- //this can happen if evaluation is unknown
+ //this can happen if evaluation is unknown, or if we are generalizing a star that already has a value
+ //if( !hasStar && d_quant_models[f].d_value[i]==d_false ){
+ // Trace("fmc-warn") << "**** FMC warning: inconsistent duplicate instantiation." << std::endl;
+ //}
+ //this assertion can happen if two instantiations from this round are identical
+ // (0,1)->false (1,0)->false for forall xy. f( x, y ) = f( y, x )
+ //Assert( hasStar || d_quant_models[f].d_value[i]!=d_false );
//might try it next effort level
d_star_insts[f].push_back(i);
}
@@ -733,12 +745,14 @@ bool FullModelChecker::exhaustiveInstantiate(FirstOrderModelFmc * fm, Node f, No
for( unsigned i=0; i<c.getNumChildren(); i++ ){
if( c[i].getType().isInteger() ){
if( fm->isInterval(c[i]) ){
+ Trace("fmc-exh-debug") << "...set " << i << " based on interval." << std::endl;
for( unsigned b=0; b<2; b++ ){
if( !fm->isStar(c[i][b]) ){
riter.d_bounds[b][i] = c[i][b];
}
}
}else if( !fm->isStar(c[i]) ){
+ Trace("fmc-exh-debug") << "...set " << i << " based on point." << std::endl;
riter.d_bounds[0][i] = c[i];
riter.d_bounds[1][i] = QuantArith::offset( c[i], 1 );
}
@@ -780,11 +794,11 @@ bool FullModelChecker::exhaustiveInstantiate(FirstOrderModelFmc * fm, Node f, No
for( int i=0; i<riter.getNumTerms(); i++ ){
Node rr = riter.getTerm( i );
Node r = rr;
- if( r.getType().isSort() ){
- r = fm->getUsedRepresentative( r );
- }else{
- r = fm->getCurrentModelValue( r );
- }
+ //if( r.getType().isSort() ){
+ r = fm->getUsedRepresentative( r );
+ //}else{
+ // r = fm->getCurrentModelValue( r );
+ //}
debugPrint("fmc-exh-debug", r);
Trace("fmc-exh-debug") << " (term : " << rr << ")";
ev_inst.push_back( r );
@@ -796,10 +810,10 @@ bool FullModelChecker::exhaustiveInstantiate(FirstOrderModelFmc * fm, Node f, No
if (ev!=d_true) {
Trace("fmc-exh-debug") << ", add!";
//add as instantiation
- if( d_qe->addInstantiation( f, inst ) ){
+ if( d_qe->addInstantiation( f, inst, true ) ){
Trace("fmc-exh-debug") << " ...success.";
addedLemmas++;
- if( options::fmfOneInstPerRound() ){
+ if( d_qe->inConflict() || options::fmfOneInstPerRound() ){
break;
}
}else{
@@ -846,38 +860,12 @@ void FullModelChecker::doCheck(FirstOrderModelFmc * fm, Node f, Def & d, Node n
d.addEntry(fm, mkCondDefault(fm, f), Node::null());
}
else if( n.getType().isArray() ){
- //make the definition
- bool success = false;
- /*
- Node r = fm->getRepresentative(n);
- Trace("fmc-debug") << "Representative for array is " << r << std::endl;
- while( r.getKind() == kind::STORE ){
- Node i = fm->getUsedRepresentative( r[1] );
- Node e = fm->getUsedRepresentative( r[2] );
- d.addEntry(fm, mkArrayCond(i), e );
- r = fm->getRepresentative( r[0] );
- }
- Node defC = mkArrayCond(fm->getStar(n.getType().getArrayIndexType()));
- bool success = false;
- Node odefaultValue;
- if( r.getKind() == kind::STORE_ALL ){
- ArrayStoreAll storeAll = r.getConst<ArrayStoreAll>();
- odefaultValue = Node::fromExpr(storeAll.getExpr());
- Node defaultValue = fm->getUsedRepresentative( odefaultValue, true );
- if( !defaultValue.isNull() ){
- d.addEntry(fm, defC, defaultValue);
- success = true;
- }
- }
- */
- if( !success ){
- //Trace("fmc-warn") << "WARNING : ARRAYS : Can't process base array " << r << std::endl;
- //Trace("fmc-warn") << " Default value was : " << odefaultValue << std::endl;
- //Trace("fmc-debug") << "Can't process base array " << r << std::endl;
- //can't process this array
- d.reset();
- d.addEntry(fm, mkCondDefault(fm, f), Node::null());
- }
+ //Trace("fmc-warn") << "WARNING : ARRAYS : Can't process base array " << r << std::endl;
+ //Trace("fmc-warn") << " Default value was : " << odefaultValue << std::endl;
+ //Trace("fmc-debug") << "Can't process base array " << r << std::endl;
+ //can't process this array
+ d.reset();
+ d.addEntry(fm, mkCondDefault(fm, f), Node::null());
}
else if( n.getNumChildren()==0 ){
Node r = n;
diff --git a/src/theory/quantifiers/full_model_check.h b/src/theory/quantifiers/full_model_check.h
index c7bfcd189..411b7a5eb 100644
--- a/src/theory/quantifiers/full_model_check.h
+++ b/src/theory/quantifiers/full_model_check.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file full_model_check.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Full model check class
**/
diff --git a/src/theory/quantifiers/fun_def_engine.cpp b/src/theory/quantifiers/fun_def_engine.cpp
index 56214f540..cf1d14663 100644
--- a/src/theory/quantifiers/fun_def_engine.cpp
+++ b/src/theory/quantifiers/fun_def_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file fun_def_process.cpp
+/*! \file fun_def_engine.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** This class implements specialized techniques for (recursively) defined functions
**/
diff --git a/src/theory/quantifiers/fun_def_engine.h b/src/theory/quantifiers/fun_def_engine.h
index be73d51a9..3b95281c0 100644
--- a/src/theory/quantifiers/fun_def_engine.h
+++ b/src/theory/quantifiers/fun_def_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file fun_def_engine.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Specialized techniques for (recursively) defined functions
**/
diff --git a/src/theory/quantifiers/fun_def_process.cpp b/src/theory/quantifiers/fun_def_process.cpp
index 7d5e33fdb..9109aab8a 100644
--- a/src/theory/quantifiers/fun_def_process.cpp
+++ b/src/theory/quantifiers/fun_def_process.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file fun_def_process.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sort inference module
**
diff --git a/src/theory/quantifiers/fun_def_process.h b/src/theory/quantifiers/fun_def_process.h
index 8cff6c952..1f6ee6562 100644
--- a/src/theory/quantifiers/fun_def_process.h
+++ b/src/theory/quantifiers/fun_def_process.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file fun_def_process.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Pre-process steps for well-defined functions
**/
diff --git a/src/theory/quantifiers/inst_match.cpp b/src/theory/quantifiers/inst_match.cpp
index 5eca87903..8818175db 100644
--- a/src/theory/quantifiers/inst_match.cpp
+++ b/src/theory/quantifiers/inst_match.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_match.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Kshitij Bansal, Francois Bobot, Clark Barrett
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of inst match class
**/
@@ -142,7 +142,7 @@ bool InstMatch::set( QuantifiersEngine* qe, int i, TNode n ) {
}
bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m, bool modEq,
- bool modInst, ImtIndexOrder* imtio, bool onlyExist, int index ) {
+ ImtIndexOrder* imtio, bool onlyExist, int index ) {
if( index==(int)f[0].getNumChildren() || ( imtio && index==(int)imtio->d_order.size() ) ){
return false;
}else{
@@ -150,25 +150,11 @@ bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector< No
Node n = m[i_index];
std::map< Node, InstMatchTrie >::iterator it = d_data.find( n );
if( it!=d_data.end() ){
- bool ret = it->second.addInstMatch( qe, f, m, modEq, modInst, imtio, onlyExist, index+1 );
+ bool ret = it->second.addInstMatch( qe, f, m, modEq, imtio, onlyExist, index+1 );
if( !onlyExist || !ret ){
return ret;
}
}
- /*
- //check if m is an instance of another instantiation if modInst is true
- if( modInst ){
- if( !n.isNull() ){
- Node nl;
- std::map< Node, InstMatchTrie >::iterator itm = d_data.find( nl );
- if( itm!=d_data.end() ){
- if( !itm->second.addInstMatch( qe, f, m, modEq, modInst, imtio, true, index+1 ) ){
- return false;
- }
- }
- }
- }
- */
if( modEq ){
//check modulo equality if any other instantiation match exists
if( !n.isNull() && qe->getEqualityQuery()->getEngine()->hasTerm( n ) ){
@@ -179,7 +165,7 @@ bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector< No
if( en!=n ){
std::map< Node, InstMatchTrie >::iterator itc = d_data.find( en );
if( itc!=d_data.end() ){
- if( itc->second.addInstMatch( qe, f, m, modEq, modInst, imtio, true, index+1 ) ){
+ if( itc->second.addInstMatch( qe, f, m, modEq, imtio, true, index+1 ) ){
return false;
}
}
@@ -189,12 +175,30 @@ bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector< No
}
}
if( !onlyExist ){
- d_data[n].addInstMatch( qe, f, m, modEq, modInst, imtio, false, index+1 );
+ d_data[n].addInstMatch( qe, f, m, modEq, imtio, false, index+1 );
}
return true;
}
}
+bool InstMatchTrie::removeInstMatch( QuantifiersEngine* qe, Node q, std::vector< Node >& m, ImtIndexOrder* imtio, int index ) {
+ Assert( index<(int)q[0].getNumChildren() );
+ Assert( !imtio || index<(int)imtio->d_order.size() );
+ int i_index = imtio ? imtio->d_order[index] : index;
+ Node n = m[i_index];
+ std::map< Node, InstMatchTrie >::iterator it = d_data.find( n );
+ if( it!=d_data.end() ){
+ if( (index+1)==(int)q[0].getNumChildren() || ( imtio && (index+1)==(int)imtio->d_order.size() ) ){
+ d_data.erase( n );
+ return true;
+ }else{
+ return it->second.removeInstMatch( qe, q, m, imtio, index+1 );
+ }
+ }else{
+ return false;
+ }
+}
+
void InstMatchTrie::print( std::ostream& out, Node q, std::vector< TNode >& terms ) const {
if( terms.size()==q[0].getNumChildren() ){
out << " ( ";
@@ -212,9 +216,31 @@ void InstMatchTrie::print( std::ostream& out, Node q, std::vector< TNode >& term
}
}
+void InstMatchTrie::getInstantiations( std::vector< Node >& insts, Node q, std::vector< Node >& terms, QuantifiersEngine * qe ) const {
+ if( terms.size()==q[0].getNumChildren() ){
+ //insts.push_back( q[1].substitute( vars.begin(), vars.end(), terms.begin(), terms.end() ) );
+ insts.push_back( qe->getInstantiation( q, terms, true ) );
+ }else{
+ for( std::map< Node, InstMatchTrie >::const_iterator it = d_data.begin(); it != d_data.end(); ++it ){
+ terms.push_back( it->first );
+ it->second.getInstantiations( insts, q, terms, qe );
+ terms.pop_back();
+ }
+ }
+}
+
+CDInstMatchTrie::~CDInstMatchTrie() {
+ for(std::map< Node, CDInstMatchTrie* >::iterator i = d_data.begin(),
+ iend = d_data.end(); i != iend; ++i) {
+ CDInstMatchTrie* current = (*i).second;
+ delete current;
+ }
+ d_data.clear();
+}
+
bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m,
- context::Context* c, bool modEq, bool modInst, int index, bool onlyExist ){
+ context::Context* c, bool modEq, int index, bool onlyExist ){
bool reset = false;
if( !d_valid.get() ){
if( onlyExist ){
@@ -230,25 +256,11 @@ bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector<
Node n = m[ index ];
std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
if( it!=d_data.end() ){
- bool ret = it->second->addInstMatch( qe, f, m, c, modEq, modInst, index+1, onlyExist );
+ bool ret = it->second->addInstMatch( qe, f, m, c, modEq, index+1, onlyExist );
if( !onlyExist || !ret ){
return reset || ret;
}
}
- //check if m is an instance of another instantiation if modInst is true
- /*
- if( modInst ){
- if( !n.isNull() ){
- Node nl;
- std::map< Node, CDInstMatchTrie* >::iterator itm = d_data.find( nl );
- if( itm!=d_data.end() ){
- if( !itm->second->addInstMatch( qe, f, m, c, modEq, modInst, index+1, true ) ){
- return false;
- }
- }
- }
- }
- */
if( modEq ){
//check modulo equality if any other instantiation match exists
if( !n.isNull() && qe->getEqualityQuery()->getEngine()->hasTerm( n ) ){
@@ -259,7 +271,7 @@ bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector<
if( en!=n ){
std::map< Node, CDInstMatchTrie* >::iterator itc = d_data.find( en );
if( itc!=d_data.end() ){
- if( itc->second->addInstMatch( qe, f, m, c, modEq, modInst, index+1, true ) ){
+ if( itc->second->addInstMatch( qe, f, m, c, modEq, index+1, true ) ){
return false;
}
}
@@ -272,13 +284,33 @@ bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, std::vector<
if( !onlyExist ){
// std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
CDInstMatchTrie* imt = new CDInstMatchTrie( c );
+ Assert(d_data.find(n) == d_data.end());
d_data[n] = imt;
- imt->addInstMatch( qe, f, m, c, modEq, modInst, index+1, false );
+ imt->addInstMatch( qe, f, m, c, modEq, index+1, false );
}
return true;
}
}
+bool CDInstMatchTrie::removeInstMatch( QuantifiersEngine* qe, Node q, std::vector< Node >& m, int index ) {
+ if( index==(int)q[0].getNumChildren() ){
+ if( d_valid.get() ){
+ d_valid.set( false );
+ return true;
+ }else{
+ return false;
+ }
+ }else{
+ Node n = m[index];
+ std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
+ if( it!=d_data.end() ){
+ return it->second->removeInstMatch( qe, q, m, index+1 );
+ }else{
+ return false;
+ }
+ }
+}
+
void CDInstMatchTrie::print( std::ostream& out, Node q, std::vector< TNode >& terms ) const{
if( d_valid.get() ){
if( terms.size()==q[0].getNumChildren() ){
@@ -298,6 +330,21 @@ void CDInstMatchTrie::print( std::ostream& out, Node q, std::vector< TNode >& te
}
}
+void CDInstMatchTrie::getInstantiations( std::vector< Node >& insts, Node q, std::vector< Node >& terms, QuantifiersEngine * qe ) const{
+ if( d_valid.get() ){
+ if( terms.size()==q[0].getNumChildren() ){
+ //insts.push_back( q[1].substitute( vars.begin(), vars.end(), terms.begin(), terms.end() ) );
+ insts.push_back( qe->getInstantiation( q, terms, true ) );
+ }else{
+ for( std::map< Node, CDInstMatchTrie* >::const_iterator it = d_data.begin(); it != d_data.end(); ++it ){
+ terms.push_back( it->first );
+ it->second->getInstantiations( insts, q, terms, qe );
+ terms.pop_back();
+ }
+ }
+ }
+}
+
}/* CVC4::theory::inst namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/quantifiers/inst_match.h b/src/theory/quantifiers/inst_match.h
index f1c1c952a..ad287c1a3 100644
--- a/src/theory/quantifiers/inst_match.h
+++ b/src/theory/quantifiers/inst_match.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_match.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief inst match class
**/
@@ -96,11 +96,12 @@ public:
public:
std::vector< int > d_order;
};/* class InstMatchTrie ImtIndexOrder */
-public:
+
/** the data */
std::map< Node, InstMatchTrie > d_data;
private:
void print( std::ostream& out, Node q, std::vector< TNode >& terms ) const;
+ void getInstantiations( std::vector< Node >& insts, Node q, std::vector< Node >& terms, QuantifiersEngine * qe ) const;
public:
InstMatchTrie(){}
~InstMatchTrie(){}
@@ -110,69 +111,80 @@ public:
modInst is if we return true if m is an instance of a match that exists
*/
bool existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false,
- bool modInst = false, ImtIndexOrder* imtio = NULL, int index = 0 ) {
- return !addInstMatch( qe, f, m, modEq, modInst, imtio, true, index );
+ ImtIndexOrder* imtio = NULL, int index = 0 ) {
+ return !addInstMatch( qe, f, m, modEq, imtio, true, index );
}
bool existsInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m, bool modEq = false,
- bool modInst = false, ImtIndexOrder* imtio = NULL, int index = 0 ) {
- return !addInstMatch( qe, f, m, modEq, modInst, imtio, true, index );
+ ImtIndexOrder* imtio = NULL, int index = 0 ) {
+ return !addInstMatch( qe, f, m, modEq, imtio, true, index );
}
/** add match m for quantifier f, take into account equalities if modEq = true,
if imtio is non-null, this is the order to add to trie
return true if successful
*/
bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false,
- bool modInst = false, ImtIndexOrder* imtio = NULL, bool onlyExist = false, int index = 0 ){
- return addInstMatch( qe, f, m.d_vals, modEq, modInst, imtio, onlyExist, index );
+ ImtIndexOrder* imtio = NULL, bool onlyExist = false, int index = 0 ){
+ return addInstMatch( qe, f, m.d_vals, modEq, imtio, onlyExist, index );
}
bool addInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m, bool modEq = false,
- bool modInst = false, ImtIndexOrder* imtio = NULL, bool onlyExist = false, int index = 0 );
+ ImtIndexOrder* imtio = NULL, bool onlyExist = false, int index = 0 );
+ bool removeInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m, ImtIndexOrder* imtio = NULL, int index = 0 );
void print( std::ostream& out, Node q ) const{
std::vector< TNode > terms;
print( out, q, terms );
}
+ void getInstantiations( std::vector< Node >& insts, Node q, QuantifiersEngine * qe ) {
+ std::vector< Node > terms;
+ getInstantiations( insts, q, terms, qe );
+ }
void clear() { d_data.clear(); }
};/* class InstMatchTrie */
/** trie for InstMatch objects */
class CDInstMatchTrie {
-public:
+private:
/** the data */
std::map< Node, CDInstMatchTrie* > d_data;
/** is valid */
context::CDO< bool > d_valid;
-private:
+
void print( std::ostream& out, Node q, std::vector< TNode >& terms ) const;
+ void getInstantiations( std::vector< Node >& insts, Node q, std::vector< Node >& terms, QuantifiersEngine * qe ) const;
public:
CDInstMatchTrie( context::Context* c ) : d_valid( c, false ){}
- ~CDInstMatchTrie(){}
-public:
+ ~CDInstMatchTrie();
+
/** return true if m exists in this trie
modEq is if we check modulo equality
modInst is if we return true if m is an instance of a match that exists
*/
- bool existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, bool modEq = false,
- bool modInst = false, int index = 0 ) {
- return !addInstMatch( qe, f, m, c, modEq, modInst, index, true );
+ bool existsInstMatch( QuantifiersEngine* qe, Node q, InstMatch& m, context::Context* c, bool modEq = false,
+ int index = 0 ) {
+ return !addInstMatch( qe, q, m, c, modEq, index, true );
}
- bool existsInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m, context::Context* c, bool modEq = false,
- bool modInst = false, int index = 0 ) {
- return !addInstMatch( qe, f, m, c, modEq, modInst, index, true );
+ bool existsInstMatch( QuantifiersEngine* qe, Node q, std::vector< Node >& m, context::Context* c, bool modEq = false,
+ int index = 0 ) {
+ return !addInstMatch( qe, q, m, c, modEq, index, true );
}
/** add match m for quantifier f, take into account equalities if modEq = true,
if imtio is non-null, this is the order to add to trie
return true if successful
*/
- bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, bool modEq = false,
- bool modInst = false, int index = 0, bool onlyExist = false ) {
- return addInstMatch( qe, f, m.d_vals, c, modEq, modInst, index, onlyExist );
+ bool addInstMatch( QuantifiersEngine* qe, Node q, InstMatch& m, context::Context* c, bool modEq = false,
+ int index = 0, bool onlyExist = false ) {
+ return addInstMatch( qe, q, m.d_vals, c, modEq, index, onlyExist );
}
- bool addInstMatch( QuantifiersEngine* qe, Node f, std::vector< Node >& m, context::Context* c, bool modEq = false,
- bool modInst = false, int index = 0, bool onlyExist = false );
+ bool addInstMatch( QuantifiersEngine* qe, Node q, std::vector< Node >& m, context::Context* c, bool modEq = false,
+ int index = 0, bool onlyExist = false );
+ bool removeInstMatch( QuantifiersEngine* qe, Node q, std::vector< Node >& m, int index = 0 );
void print( std::ostream& out, Node q ) const{
std::vector< TNode > terms;
print( out, q, terms );
}
+ void getInstantiations( std::vector< Node >& insts, Node q, QuantifiersEngine * qe ) {
+ std::vector< Node > terms;
+ getInstantiations( insts, q, terms, qe );
+ }
};/* class CDInstMatchTrie */
@@ -190,10 +202,10 @@ public:
public:
/** add match m, return true if successful */
bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false, bool modInst = false ){
- return d_imt.addInstMatch( qe, f, m, modEq, modInst, d_imtio );
+ return d_imt.addInstMatch( qe, f, m, modEq, d_imtio );
}
bool existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false, bool modInst = false ){
- return d_imt.existsInstMatch( qe, f, m, modEq, modInst, d_imtio );
+ return d_imt.existsInstMatch( qe, f, m, modEq, d_imtio );
}
};/* class InstMatchTrieOrdered */
diff --git a/src/theory/quantifiers/inst_match_generator.cpp b/src/theory/quantifiers/inst_match_generator.cpp
index 89c2d4868..bf05de3bb 100644
--- a/src/theory/quantifiers/inst_match_generator.cpp
+++ b/src/theory/quantifiers/inst_match_generator.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_match_generator.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
@@ -40,7 +40,6 @@ InstMatchGenerator::InstMatchGenerator( Node pat ){
d_match_pattern_type = pat.getType();
d_next = NULL;
d_matchPolicy = MATCH_GEN_DEFAULT;
- d_eq_class_rel = false;
}
InstMatchGenerator::InstMatchGenerator() {
@@ -59,7 +58,7 @@ void InstMatchGenerator::setActiveAdd(bool val){
void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector< InstMatchGenerator * > & gens ){
if( !d_pattern.isNull() ){
- Debug("inst-match-gen") << "Pattern term is " << d_pattern << std::endl;
+ Trace("inst-match-gen") << "Initialize, pattern term is " << d_pattern << std::endl;
if( d_match_pattern.getKind()==NOT ){
//we want to add the children of the NOT
d_match_pattern = d_pattern[0];
@@ -67,29 +66,23 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector<
if( d_match_pattern.getKind()==IFF || d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==GEQ ){
//make sure the matching portion of the equality is on the LHS of d_pattern
// and record what d_match_pattern is
- if( !quantifiers::TermDb::hasInstConstAttr(d_match_pattern[0]) || d_match_pattern[0].getKind()==INST_CONSTANT ){
- if( d_match_pattern[1].getKind()!=INST_CONSTANT ){
- Assert( quantifiers::TermDb::hasInstConstAttr(d_match_pattern[1]) );
- Node mp = d_match_pattern[1];
- //swap sides
- Node pat = d_pattern;
- if(d_match_pattern.getKind()==GEQ){
- d_pattern = NodeManager::currentNM()->mkNode( kind::GT, d_match_pattern[1], d_match_pattern[0] );
- d_pattern = d_pattern.negate();
- }else{
- d_pattern = NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), d_match_pattern[1], d_match_pattern[0] );
- }
- d_pattern = pat.getKind()==NOT ? d_pattern.negate() : d_pattern;
- d_match_pattern = mp;
- }
- }else if( !quantifiers::TermDb::hasInstConstAttr(d_match_pattern[1]) || d_match_pattern[1].getKind()==INST_CONSTANT ){
- if( d_match_pattern[0].getKind()!=INST_CONSTANT ){
- Assert( quantifiers::TermDb::hasInstConstAttr(d_match_pattern[0]) );
- if( d_pattern.getKind()!=NOT ){ //TEMPORARY until we do better implementation of disequality matching
- d_match_pattern = d_match_pattern[0];
- }else if( d_match_pattern[1].getKind()==INST_CONSTANT ){
- d_match_pattern = d_match_pattern[0];
+ for( unsigned i=0; i<2; i++ ){
+ if( !quantifiers::TermDb::hasInstConstAttr(d_match_pattern[i]) || d_match_pattern[i].getKind()==INST_CONSTANT ){
+ Node mp = d_match_pattern[1-i];
+ Node mpo = d_match_pattern[i];
+ if( mp.getKind()!=INST_CONSTANT ){
+ if( i==0 ){
+ if( d_match_pattern.getKind()==GEQ ){
+ d_pattern = NodeManager::currentNM()->mkNode( kind::GT, mp, mpo );
+ d_pattern = d_pattern.negate();
+ }else{
+ d_pattern = NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), mp, mpo );
+ }
+ }
+ d_eq_class_rel = mpo;
+ d_match_pattern = mp;
}
+ break;
}
}
}else if( d_match_pattern.getKind()==APPLY_SELECTOR_TOTAL && d_match_pattern[0].getKind()==INST_CONSTANT && options::purifyDtTriggers() ){
@@ -97,11 +90,10 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector<
}
d_match_pattern_type = d_match_pattern.getType();
Trace("inst-match-gen") << "Pattern is " << d_pattern << ", match pattern is " << d_match_pattern << std::endl;
- d_match_pattern_op = qe->getTermDatabase()->getOperator( d_match_pattern );
+ d_match_pattern_op = qe->getTermDatabase()->getMatchOperator( d_match_pattern );
//now, collect children of d_match_pattern
- //int childMatchPolicy = MATCH_GEN_DEFAULT;
- for( int i=0; i<(int)d_match_pattern.getNumChildren(); i++ ){
+ for( unsigned i=0; i<d_match_pattern.getNumChildren(); i++ ){
Node qa = quantifiers::TermDb::getInstConstAttr(d_match_pattern[i]);
if( !qa.isNull() ){
InstMatchGenerator * cimg = Trigger::getInstMatchGenerator( q, d_match_pattern[i] );
@@ -127,9 +119,17 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector<
}
//create candidate generator
- if( d_match_pattern.getKind()==INST_CONSTANT ){
+ if( Trigger::isAtomicTrigger( d_match_pattern ) ){
+ //we will be scanning lists trying to find d_match_pattern.getOperator()
+ d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern );
+ //if matching on disequality, inform the candidate generator not to match on eqc
+ if( d_pattern.getKind()==NOT && ( d_pattern[0].getKind()==IFF || d_pattern[0].getKind()==EQUAL ) ){
+ ((inst::CandidateGeneratorQE*)d_cg)->excludeEqc( d_eq_class_rel );
+ d_eq_class_rel = Node::null();
+ }
+ }else if( d_match_pattern.getKind()==INST_CONSTANT ){
if( d_pattern.getKind()==APPLY_SELECTOR_TOTAL ){
- Expr selectorExpr = qe->getTermDatabase()->getOperator( d_pattern ).toExpr();
+ Expr selectorExpr = qe->getTermDatabase()->getMatchOperator( d_pattern ).toExpr();
size_t selectorIndex = Datatype::cindexOf(selectorExpr);
const Datatype& dt = Datatype::datatypeOf(selectorExpr);
const DatatypeConstructor& c = dt[selectorIndex];
@@ -139,7 +139,8 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector<
}else{
d_cg = new CandidateGeneratorQEAll( qe, d_match_pattern );
}
- }else if( d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==IFF ){
+ }else if( ( d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==IFF ) &&
+ d_match_pattern[0].getKind()==INST_CONSTANT && d_match_pattern[1].getKind()==INST_CONSTANT ){
//we will be producing candidates via literal matching heuristics
if( d_pattern.getKind()!=NOT ){
//candidates will be all equalities
@@ -148,26 +149,6 @@ void InstMatchGenerator::initialize( Node q, QuantifiersEngine* qe, std::vector<
//candidates will be all disequalities
d_cg = new inst::CandidateGeneratorQELitDeq( qe, d_match_pattern );
}
- }else if( d_pattern.getKind()==EQUAL || d_pattern.getKind()==IFF ||
- d_pattern.getKind()==GEQ || d_pattern.getKind()==GT || d_pattern.getKind()==NOT ){
- Assert( d_matchPolicy==MATCH_GEN_DEFAULT );
- if( d_pattern.getKind()==NOT ){
- if (d_pattern[0][1].getKind()!=INST_CONSTANT) {
- Unimplemented("Disequal generator unimplemented");
- }else{
- d_eq_class = d_pattern[0][1];
- }
- }else{
- //store the equivalence class that we will call d_cg->reset( ... ) on
- d_eq_class = d_pattern[1];
- }
- d_eq_class_rel = true;
- Assert( Trigger::isAtomicTrigger( d_match_pattern ) );
- //we are matching only in a particular equivalence class
- d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern_op );
- }else if( Trigger::isAtomicTrigger( d_match_pattern ) ){
- //we will be scanning lists trying to find d_match_pattern.getOperator()
- d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern_op );
}else{
d_cg = new CandidateGeneratorQueue;
Trace("inst-match-gen-warn") << "(?) Unknown matching pattern is " << d_match_pattern << std::endl;
@@ -197,7 +178,7 @@ bool InstMatchGenerator::getMatch( Node f, Node t, InstMatch& m, QuantifiersEngi
Assert( !Trigger::isAtomicTrigger( d_match_pattern ) || t.getOperator()==d_match_pattern.getOperator() );
//first, check if ground arguments are not equal, or a match is in conflict
Trace("matching-debug2") << "Setting immediate matches..." << std::endl;
- for( int i=0; i<(int)d_match_pattern.getNumChildren(); i++ ){
+ for( unsigned i=0; i<d_match_pattern.getNumChildren(); i++ ){
if( d_children_types[i]==0 ){
Trace("matching-debug2") << "Setting " << d_var_num[i] << " to " << t[i] << "..." << std::endl;
bool addToPrev = m.get( d_var_num[i] ).isNull();
@@ -231,8 +212,8 @@ bool InstMatchGenerator::getMatch( Node f, Node t, InstMatch& m, QuantifiersEngi
}
}
//for relational matching
- }else if( d_eq_class_rel && d_eq_class.getKind()==INST_CONSTANT ){
- int v = d_eq_class.getAttribute(InstVarNumAttribute());
+ }else if( !d_eq_class_rel.isNull() && d_eq_class_rel.getKind()==INST_CONSTANT ){
+ int v = d_eq_class_rel.getAttribute(InstVarNumAttribute());
//also must fit match to equivalence class
bool pol = d_pattern.getKind()!=NOT;
Node pat = d_pattern.getKind()==NOT ? d_pattern[0] : d_pattern;
@@ -289,7 +270,7 @@ bool InstMatchGenerator::continueNextMatch( Node f, InstMatch& m, QuantifiersEng
return d_next->getNextMatch( f, m, qe );
}else{
if( d_active_add ){
- return qe->addInstantiation( f, m, false );
+ return qe->addInstantiation( f, m );
}else{
return true;
}
@@ -313,20 +294,22 @@ void InstMatchGenerator::resetInstantiationRound( QuantifiersEngine* qe ){
void InstMatchGenerator::reset( Node eqc, QuantifiersEngine* qe ){
eqc = qe->getEqualityQuery()->getRepresentative( eqc );
Trace("matching-debug2") << this << " reset " << eqc << "." << std::endl;
- if( !eqc.isNull() ){
+ if( !d_eq_class_rel.isNull() && d_eq_class_rel.getKind()!=INST_CONSTANT ){
+ d_eq_class = d_eq_class_rel;
+ }else if( !eqc.isNull() ){
d_eq_class = eqc;
}
//we have a specific equivalence class in mind
//we are producing matches for f(E) ~ t, where E is a non-ground vector of terms, and t is a ground term
//just look in equivalence class of the RHS
- d_cg->reset( d_eq_class_rel ? Node::null() : d_eq_class );
+ d_cg->reset( d_eq_class );
d_needsReset = false;
}
bool InstMatchGenerator::getNextMatch( Node f, InstMatch& m, QuantifiersEngine* qe ){
if( d_needsReset ){
Trace("matching") << "Reset not done yet, must do the reset..." << std::endl;
- reset( d_eq_class_rel ? Node::null() : d_eq_class, qe );
+ reset( d_eq_class, qe );
}
m.d_matched = Node::null();
Trace("matching") << this << " " << d_match_pattern << " get next match " << m << " in eq class " << d_eq_class << std::endl;
@@ -346,7 +329,7 @@ bool InstMatchGenerator::getNextMatch( Node f, InstMatch& m, QuantifiersEngine*
if( !success ){
Trace("matching") << this << " failed, reset " << d_eq_class << std::endl;
//we failed, must reset
- reset( d_eq_class_rel ? Node::null() : d_eq_class, qe );
+ reset( d_eq_class, qe );
}
return success;
}
@@ -360,11 +343,17 @@ int InstMatchGenerator::addInstantiations( Node f, InstMatch& baseMatch, Quantif
while( getNextMatch( f, m, qe ) ){
if( !d_active_add ){
m.add( baseMatch );
- if( qe->addInstantiation( f, m, false ) ){
+ if( qe->addInstantiation( f, m ) ){
addedLemmas++;
+ if( qe->inConflict() ){
+ break;
+ }
}
}else{
addedLemmas++;
+ if( qe->inConflict() ){
+ break;
+ }
}
m.clear();
}
@@ -377,12 +366,12 @@ int InstMatchGenerator::addTerm( Node f, Node t, QuantifiersEngine* qe ){
if( !d_match_pattern.isNull() ){
InstMatch m( f );
if( getMatch( f, t, m, qe ) ){
- if( qe->addInstantiation( f, m, false ) ){
+ if( qe->addInstantiation( f, m ) ){
return 1;
}
}
}else{
- for( int i=0; i<(int)d_children.size(); i++ ){
+ for( unsigned i=0; i<d_children.size(); i++ ){
d_children[i]->addTerm( f, t, qe );
}
}
@@ -544,14 +533,14 @@ d_f( q ){
/** reset instantiation round (call this whenever equivalence classes have changed) */
void InstMatchGeneratorMulti::resetInstantiationRound( QuantifiersEngine* qe ){
- for( int i=0; i<(int)d_children.size(); i++ ){
+ for( unsigned i=0; i<d_children.size(); i++ ){
d_children[i]->resetInstantiationRound( qe );
}
}
/** reset, eqc is the equivalence class to search in (any if eqc=null) */
void InstMatchGeneratorMulti::reset( Node eqc, QuantifiersEngine* qe ){
- for( int i=0; i<(int)d_children.size(); i++ ){
+ for( unsigned i=0; i<d_children.size(); i++ ){
d_children[i]->reset( eqc, qe );
}
}
@@ -559,7 +548,7 @@ void InstMatchGeneratorMulti::reset( Node eqc, QuantifiersEngine* qe ){
int InstMatchGeneratorMulti::addInstantiations( Node q, InstMatch& baseMatch, QuantifiersEngine* qe ){
int addedLemmas = 0;
Debug("smart-multi-trigger") << "Process smart multi trigger" << std::endl;
- for( int i=0; i<(int)d_children.size(); i++ ){
+ for( unsigned i=0; i<d_children.size(); i++ ){
Debug("smart-multi-trigger") << "Calculate matches " << i << std::endl;
std::vector< InstMatch > newMatches;
InstMatch m( q );
@@ -569,8 +558,11 @@ int InstMatchGeneratorMulti::addInstantiations( Node q, InstMatch& baseMatch, Qu
m.clear();
}
Debug("smart-multi-trigger") << "Made " << newMatches.size() << " new matches for index " << i << std::endl;
- for( int j=0; j<(int)newMatches.size(); j++ ){
+ for( unsigned j=0; j<newMatches.size(); j++ ){
processNewMatch( qe, newMatches[j], i, addedLemmas );
+ if( qe->inConflict() ){
+ return addedLemmas;
+ }
}
}
return addedLemmas;
@@ -593,6 +585,7 @@ void InstMatchGeneratorMulti::processNewMatch( QuantifiersEngine* qe, InstMatch&
void InstMatchGeneratorMulti::processNewInstantiations( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas, InstMatchTrie* tr,
std::vector< IndexedTrie >& unique_var_tries,
int trieIndex, int childIndex, int endChildIndex, bool modEq ){
+ Assert( !qe->inConflict() );
if( childIndex==endChildIndex ){
//now, process unique variables
processNewInstantiations2( qe, m, addedLemmas, unique_var_tries, 0 );
@@ -614,6 +607,9 @@ void InstMatchGeneratorMulti::processNewInstantiations( QuantifiersEngine* qe, I
mn.setValue( curr_index, it->first);
processNewInstantiations( qe, mn, addedLemmas, &(it->second), unique_var_tries,
trieIndex+1, childIndex, endChildIndex, modEq );
+ if( qe->inConflict() ){
+ break;
+ }
}
//}
}else{
@@ -635,6 +631,9 @@ void InstMatchGeneratorMulti::processNewInstantiations( QuantifiersEngine* qe, I
if( itc!=tr->d_data.end() ){
processNewInstantiations( qe, m, addedLemmas, &(itc->second), unique_var_tries,
trieIndex+1, childIndex, endChildIndex, modEq );
+ if( qe->inConflict() ){
+ break;
+ }
}
}
++eqc;
@@ -666,13 +665,16 @@ void InstMatchGeneratorMulti::processNewInstantiations2( QuantifiersEngine* qe,
InstMatch mn( &m );
mn.setValue( curr_index, it->first);
processNewInstantiations2( qe, mn, addedLemmas, unique_var_tries, uvtIndex, &(it->second), trieIndex+1 );
+ if( qe->inConflict() ){
+ break;
+ }
}
}else{
processNewInstantiations2( qe, m, addedLemmas, unique_var_tries, uvtIndex+1 );
}
}else{
//m is an instantiation
- if( qe->addInstantiation( d_f, m, false ) ){
+ if( qe->addInstantiation( d_f, m ) ){
addedLemmas++;
Debug("smart-multi-trigger") << "-> Produced instantiation " << m << std::endl;
}
@@ -683,7 +685,7 @@ int InstMatchGeneratorMulti::addTerm( Node q, Node t, QuantifiersEngine* qe ){
Assert( options::eagerInstQuant() );
int addedLemmas = 0;
for( int i=0; i<(int)d_children.size(); i++ ){
- Node t_op = qe->getTermDatabase()->getOperator( t );
+ Node t_op = qe->getTermDatabase()->getMatchOperator( t );
if( ((InstMatchGenerator*)d_children[i])->d_match_pattern_op==t_op ){
InstMatch m( q );
//if it produces a match, then process it with the rest
@@ -696,6 +698,18 @@ int InstMatchGeneratorMulti::addTerm( Node q, Node t, QuantifiersEngine* qe ){
}
InstMatchGeneratorSimple::InstMatchGeneratorSimple( Node q, Node pat ) : d_f( q ), d_match_pattern( pat ) {
+ if( d_match_pattern.getKind()==NOT ){
+ d_match_pattern = d_match_pattern[0];
+ d_pol = false;
+ }else{
+ d_pol = true;
+ }
+ if( d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==IFF ){
+ d_eqc = d_match_pattern[1];
+ d_match_pattern = d_match_pattern[0];
+ Assert( !quantifiers::TermDb::hasInstConstAttr( d_eqc ) );
+ }
+ Assert( Trigger::isSimpleTrigger( d_match_pattern ) );
for( unsigned i=0; i<d_match_pattern.getNumChildren(); i++ ){
if( d_match_pattern[i].getKind()==INST_CONSTANT ){
if( !options::cbqi() || quantifiers::TermDb::getInstConstAttr(d_match_pattern[i])==q ){
@@ -709,15 +723,39 @@ InstMatchGeneratorSimple::InstMatchGeneratorSimple( Node q, Node pat ) : d_f( q
}
void InstMatchGeneratorSimple::resetInstantiationRound( QuantifiersEngine* qe ) {
- d_op = qe->getTermDatabase()->getOperator( d_match_pattern );
+ d_op = qe->getTermDatabase()->getMatchOperator( d_match_pattern );
}
int InstMatchGeneratorSimple::addInstantiations( Node q, InstMatch& baseMatch, QuantifiersEngine* qe ){
- InstMatch m( q );
- m.add( baseMatch );
int addedLemmas = 0;
-
- addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_func_map_trie[ d_op ]) );
+ quantifiers::TermArgTrie* tat;
+ if( d_eqc.isNull() ){
+ tat = qe->getTermDatabase()->getTermArgTrie( d_op );
+ }else{
+ if( d_pol ){
+ tat = qe->getTermDatabase()->getTermArgTrie( d_eqc, d_op );
+ }else{
+ Node r = qe->getEqualityQuery()->getRepresentative( d_eqc );
+ //iterate over all classes except r
+ tat = qe->getTermDatabase()->getTermArgTrie( Node::null(), d_op );
+ for( std::map< TNode, quantifiers::TermArgTrie >::iterator it = tat->d_data.begin(); it != tat->d_data.end(); ++it ){
+ if( it->first!=r ){
+ InstMatch m( q );
+ m.add( baseMatch );
+ addInstantiations( m, qe, addedLemmas, 0, &(it->second) );
+ if( qe->inConflict() ){
+ break;
+ }
+ }
+ }
+ tat = NULL;
+ }
+ }
+ if( tat ){
+ InstMatch m( q );
+ m.add( baseMatch );
+ addInstantiations( m, qe, addedLemmas, 0, tat );
+ }
return addedLemmas;
}
@@ -725,14 +763,14 @@ void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngin
Debug("simple-trigger-debug") << "Add inst " << argIndex << " " << d_match_pattern << std::endl;
if( argIndex==(int)d_match_pattern.getNumChildren() ){
Assert( !tat->d_data.empty() );
- Node t = tat->d_data.begin()->first;
+ TNode t = tat->getNodeData();
Debug("simple-trigger") << "Actual term is " << t << std::endl;
//convert to actual used terms
for( std::map< int, int >::iterator it = d_var_num.begin(); it != d_var_num.end(); ++it ){
Debug("simple-trigger") << "...set " << it->second << " " << t[it->first] << std::endl;
m.setValue( it->second, t[it->first] );
}
- if( qe->addInstantiation( d_f, m, false ) ){
+ if( qe->addInstantiation( d_f, m ) ){
addedLemmas++;
Debug("simple-trigger") << "-> Produced instantiation " << m << std::endl;
}
@@ -749,10 +787,14 @@ void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngin
m.setValue( v, t);
addInstantiations( m, qe, addedLemmas, argIndex+1, &(it->second) );
m.setValue( v, prev);
+ if( qe->inConflict() ){
+ break;
+ }
}
}
return;
}
+ //inst constant from another quantified formula, treat as ground term TODO: remove this?
}
Node r = qe->getEqualityQuery()->getRepresentative( d_match_pattern[argIndex] );
std::map< TNode, quantifiers::TermArgTrie >::iterator it = tat->d_data.find( r );
@@ -763,16 +805,17 @@ void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngin
}
int InstMatchGeneratorSimple::addTerm( Node q, Node t, QuantifiersEngine* qe ){
+ //for eager instantiation only
Assert( options::eagerInstQuant() );
InstMatch m( q );
- for( int i=0; i<(int)t.getNumChildren(); i++ ){
+ for( unsigned i=0; i<t.getNumChildren(); i++ ){
if( d_match_pattern[i].getKind()==INST_CONSTANT ){
m.setValue(d_var_num[i], t[i]);
}else if( !qe->getEqualityQuery()->areEqual( d_match_pattern[i], t[i] ) ){
return 0;
}
}
- return qe->addInstantiation( q, m, false ) ? 1 : 0;
+ return qe->addInstantiation( q, m ) ? 1 : 0;
}
}/* CVC4::theory::inst namespace */
diff --git a/src/theory/quantifiers/inst_match_generator.h b/src/theory/quantifiers/inst_match_generator.h
index 75adeb2d8..a1d907001 100644
--- a/src/theory/quantifiers/inst_match_generator.h
+++ b/src/theory/quantifiers/inst_match_generator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_match_generator.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief inst match generator class
**/
@@ -64,7 +64,7 @@ protected:
InstMatchGenerator* d_next;
/** eq class */
Node d_eq_class;
- bool d_eq_class_rel;
+ Node d_eq_class_rel;
/** variable numbers */
std::map< int, int > d_var_num;
/** initialize pattern */
@@ -211,6 +211,9 @@ private:
Node d_f;
/** match term */
Node d_match_pattern;
+ /** equivalence class */
+ bool d_pol;
+ Node d_eqc;
/** match pattern arg types */
std::vector< TypeNode > d_match_pattern_arg_types;
/** operator */
diff --git a/src/theory/quantifiers/inst_propagator.cpp b/src/theory/quantifiers/inst_propagator.cpp
new file mode 100644
index 000000000..d4be58636
--- /dev/null
+++ b/src/theory/quantifiers/inst_propagator.cpp
@@ -0,0 +1,761 @@
+/********************* */
+/*! \file inst_propagator.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** Propagate mechanism for instantiations
+ **/
+
+#include <vector>
+
+#include "theory/quantifiers/inst_propagator.h"
+#include "theory/rewriter.h"
+#include "theory/quantifiers/term_database.h"
+
+using namespace CVC4;
+using namespace std;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+using namespace CVC4::kind;
+
+
+EqualityQueryInstProp::EqualityQueryInstProp( QuantifiersEngine* qe ) : d_qe( qe ){
+ d_true = NodeManager::currentNM()->mkConst( true );
+ d_false = NodeManager::currentNM()->mkConst( false );
+}
+
+bool EqualityQueryInstProp::reset( Theory::Effort e ) {
+ d_uf.clear();
+ d_uf_exp.clear();
+ d_diseq_list.clear();
+ return true;
+}
+
+/** contains term */
+bool EqualityQueryInstProp::hasTerm( Node a ) {
+ if( getEngine()->hasTerm( a ) ){
+ return true;
+ }else{
+ std::vector< Node > exp;
+ Node ar = getUfRepresentative( a, exp );
+ return !ar.isNull() && getEngine()->hasTerm( ar );
+ }
+}
+
+/** get the representative of the equivalence class of a */
+Node EqualityQueryInstProp::getRepresentative( Node a ) {
+ if( getEngine()->hasTerm( a ) ){
+ a = getEngine()->getRepresentative( a );
+ }
+ std::vector< Node > exp;
+ Node ar = getUfRepresentative( a, exp );
+ return ar.isNull() ? a : ar;
+}
+
+/** returns true if a and b are equal in the current context */
+bool EqualityQueryInstProp::areEqual( Node a, Node b ) {
+ if( a==b ){
+ return true;
+ }else{
+ eq::EqualityEngine* ee = getEngine();
+ if( ee->hasTerm( a ) && ee->hasTerm( b ) ){
+ if( ee->areEqual( a, b ) ){
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/** returns true is a and b are disequal in the current context */
+bool EqualityQueryInstProp::areDisequal( Node a, Node b ) {
+ if( a==b ){
+ return false;
+ }else{
+ eq::EqualityEngine* ee = getEngine();
+ if( ee->hasTerm( a ) && ee->hasTerm( b ) ){
+ if( ee->areDisequal( a, b, false ) ){
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/** get the equality engine associated with this query */
+eq::EqualityEngine* EqualityQueryInstProp::getEngine() {
+ return d_qe->getMasterEqualityEngine();
+}
+
+/** get the equivalence class of a */
+void EqualityQueryInstProp::getEquivalenceClass( Node a, std::vector< Node >& eqc ) {
+ //TODO?
+}
+
+TNode EqualityQueryInstProp::getCongruentTerm( Node f, std::vector< TNode >& args ) {
+ TNode t = d_qe->getTermDatabase()->getCongruentTerm( f, args );
+ if( !t.isNull() ){
+ return t;
+ }else{
+ //TODO?
+ return TNode::null();
+ }
+}
+
+Node EqualityQueryInstProp::getRepresentativeExp( Node a, std::vector< Node >& exp ) {
+ bool engine_has_a = getEngine()->hasTerm( a );
+ if( engine_has_a ){
+ a = getEngine()->getRepresentative( a );
+ }
+ //get union find representative, if this occurs in the equality engine, return it
+ unsigned prev_size = exp.size();
+ Node ar = getUfRepresentative( a, exp );
+ if( !ar.isNull() ){
+ if( engine_has_a || getEngine()->hasTerm( ar ) ){
+ Assert( getEngine()->hasTerm( ar ) );
+ Assert( getEngine()->getRepresentative( ar )==ar );
+ return ar;
+ }
+ }else{
+ if( engine_has_a ){
+ return a;
+ }
+ }
+ //retract explanation
+ while( exp.size()>prev_size ){
+ exp.pop_back();
+ }
+ return Node::null();
+}
+
+bool EqualityQueryInstProp::areEqualExp( Node a, Node b, std::vector< Node >& exp ) {
+ if( areEqual( a, b ) ){
+ return true;
+ }else{
+ std::vector< Node > exp_a;
+ Node ar = getUfRepresentative( a, exp_a );
+ if( !ar.isNull() ){
+ std::vector< Node > exp_b;
+ if( ar==getUfRepresentative( b, exp_b ) ){
+ merge_exp( exp, exp_a );
+ merge_exp( exp, exp_b );
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+bool EqualityQueryInstProp::areDisequalExp( Node a, Node b, std::vector< Node >& exp ) {
+ if( areDisequal( a, b ) ){
+ return true;
+ }else{
+ //Assert( getRepresentative( a )==a );
+ //Assert( getRepresentative( b )==b );
+ std::map< Node, std::vector< Node > >::iterator itd = d_diseq_list[a].find( b );
+ if( itd!=d_diseq_list[a].end() ){
+ exp.insert( exp.end(), itd->second.begin(), itd->second.end() );
+ return true;
+ }else{
+ return false;
+ }
+ }
+}
+
+Node EqualityQueryInstProp::getUfRepresentative( Node a, std::vector< Node >& exp ) {
+ Assert( exp.empty() );
+ std::map< Node, Node >::iterator it = d_uf.find( a );
+ if( it!=d_uf.end() ){
+ if( it->second==a ){
+ Assert( d_uf_exp[ a ].empty() );
+ return it->second;
+ }else{
+ Node m = getUfRepresentative( it->second, exp );
+ Assert( !m.isNull() );
+ if( m!=it->second ){
+ //update union find
+ d_uf[ a ] = m;
+ //update explanation : merge the explanation of the parent
+ merge_exp( d_uf_exp[ a ], exp );
+ Trace("qip-eq") << "EqualityQueryInstProp::getUfRepresentative : merge " << a << " -> " << m << ", exp size=" << d_uf_exp[ a ].size() << std::endl;
+ }
+ //add current explanation to exp: note that exp is a subset of d_uf_exp[ a ], reset
+ exp.clear();
+ exp.insert( exp.end(), d_uf_exp[ a ].begin(), d_uf_exp[ a ].end() );
+ return m;
+ }
+ }else{
+ return Node::null();
+ }
+}
+
+// set a == b with reason, return status, modify a and b to representatives pre-merge
+int EqualityQueryInstProp::setEqual( Node& a, Node& b, bool pol, std::vector< Node >& reason ) {
+ if( a==b ){
+ return pol ? STATUS_NONE : STATUS_CONFLICT;
+ }
+ int status = pol ? STATUS_MERGED_UNKNOWN : STATUS_NONE;
+ Trace("qip-eq") << "EqualityQueryInstProp::setEqual " << a << ", " << b << ", pol = " << pol << ", reason size = " << reason.size() << std::endl;
+ //get the representative for a
+ std::vector< Node > exp_a;
+ Node ar = getUfRepresentative( a, exp_a );
+ if( ar.isNull() ){
+ Assert( exp_a.empty() );
+ ar = a;
+ }
+ if( ar==b ){
+ Trace("qip-eq") << "EqualityQueryInstProp::setEqual : already equal" << std::endl;
+ if( pol ){
+ return STATUS_NONE;
+ }else{
+ merge_exp( reason, exp_a );
+ return STATUS_CONFLICT;
+ }
+ }
+ bool swap = false;
+ //get the representative for b
+ std::vector< Node > exp_b;
+ Node br = getUfRepresentative( b, exp_b );
+ if( br.isNull() ){
+ Assert( exp_b.empty() );
+ br = b;
+ if( !getEngine()->hasTerm( br ) ){
+ if( ar!=a || getEngine()->hasTerm( ar ) ){
+ swap = true;
+ }
+ }else{
+ if( getEngine()->hasTerm( ar ) ){
+ status = STATUS_MERGED_KNOWN;
+ }
+ }
+ }else{
+ if( ar==br ){
+ Trace("qip-eq") << "EqualityQueryInstProp::setEqual : already equal" << std::endl;
+ if( pol ){
+ return STATUS_NONE;
+ }else{
+ merge_exp( reason, exp_a );
+ merge_exp( reason, exp_b );
+ return STATUS_CONFLICT;
+ }
+ }else if( getEngine()->hasTerm( ar ) ){
+ if( getEngine()->hasTerm( br ) ){
+ status = STATUS_MERGED_KNOWN;
+ }else{
+ swap = true;
+ }
+ }
+ }
+
+ if( swap ){
+ //swap
+ Node temp_r = ar;
+ ar = br;
+ br = temp_r;
+ }
+
+ Assert( !getEngine()->hasTerm( ar ) || getEngine()->hasTerm( br ) );
+ Assert( ar!=br );
+
+ std::vector< Node > exp_d;
+ if( areDisequalExp( ar, br, exp_d ) ){
+ if( pol ){
+ merge_exp( reason, exp_b );
+ merge_exp( reason, exp_b );
+ merge_exp( reason, exp_d );
+ return STATUS_CONFLICT;
+ }else{
+ return STATUS_NONE;
+ }
+ }else{
+ if( pol ){
+ //update the union find
+ Assert( d_uf_exp[ar].empty() );
+ Assert( d_uf_exp[br].empty() );
+
+ d_uf[ar] = br;
+ merge_exp( d_uf_exp[ar], exp_a );
+ merge_exp( d_uf_exp[ar], exp_b );
+ merge_exp( d_uf_exp[ar], reason );
+
+ d_uf[br] = br;
+ d_uf_exp[br].clear();
+
+ Trace("qip-eq") << "EqualityQueryInstProp::setEqual : merge " << ar << " -> " << br << ", exp size = " << d_uf_exp[ar].size() << ", status = " << status << std::endl;
+ a = ar;
+ b = br;
+
+ //carry disequality list
+ std::map< Node, std::map< Node, std::vector< Node > > >::iterator itd = d_diseq_list.find( ar );
+ if( itd!=d_diseq_list.end() ){
+ for( std::map< Node, std::vector< Node > >::iterator itdd = itd->second.begin(); itdd != itd->second.end(); ++itdd ){
+ Node d = itdd->first;
+ if( d_diseq_list[br].find( d )==d_diseq_list[br].end() ){
+ merge_exp( d_diseq_list[br][d], itdd->second );
+ merge_exp( d_diseq_list[br][d], d_uf_exp[ar] );
+ }
+ }
+ }
+
+ return status;
+ }else{
+ Trace("qip-eq") << "EqualityQueryInstProp::setEqual : disequal " << ar << " <> " << br << std::endl;
+ Assert( d_diseq_list[ar].find( br )==d_diseq_list[ar].end() );
+ Assert( d_diseq_list[br].find( ar )==d_diseq_list[br].end() );
+
+ merge_exp( d_diseq_list[ar][br], reason );
+ merge_exp( d_diseq_list[br][ar], reason );
+ return STATUS_NONE;
+ }
+ }
+}
+
+void EqualityQueryInstProp::addArgument( std::vector< Node >& args, std::vector< Node >& props, Node n, bool is_prop, bool pol ) {
+ if( is_prop ){
+ if( isLiteral( n ) ){
+ props.push_back( pol ? n : n.negate() );
+ return;
+ }
+ }
+ args.push_back( n );
+}
+
+bool EqualityQueryInstProp::isLiteral( Node n ) {
+ Kind ak = n.getKind()==NOT ? n[0].getKind() : n.getKind();
+ Assert( ak!=NOT );
+ return ak!=AND && ak!=OR && ak!=IFF && ak!=ITE;
+}
+
+//this is identical to TermDb::evaluateTerm2, but tracks more information
+Node EqualityQueryInstProp::evaluateTermExp( Node n, std::vector< Node >& exp, std::map< Node, Node >& visited, bool hasPol, bool pol,
+ std::map< Node, bool >& watch_list_out, std::vector< Node >& props ) {
+ std::map< Node, Node >::iterator itv = visited.find( n );
+ if( itv != visited.end() ){
+ return itv->second;
+ }else{
+ visited[n] = n;
+ Trace("qip-eval") << "evaluate term : " << n << std::endl;
+ std::vector< Node > exp_n;
+ Node ret = getRepresentativeExp( n, exp_n );
+ if( ret.isNull() ){
+ //term is not known to be equal to a representative in equality engine, evaluate it
+ Kind k = n.getKind();
+ if( k==FORALL ){
+ ret = Node::null();
+ }else{
+ std::map< Node, bool > watch_list_out_curr;
+ TNode f = d_qe->getTermDatabase()->getMatchOperator( n );
+ std::vector< Node > args;
+ bool ret_set = false;
+ bool childChanged = false;
+ int abort_i = -1;
+ //get the child entailed polarity
+ Assert( n.getKind()!=IMPLIES );
+ bool newHasPol, newPol;
+ QuantPhaseReq::getEntailPolarity( n, 0, hasPol, pol, newHasPol, newPol );
+ //for each child
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ Node c = evaluateTermExp( n[i], exp, visited, newHasPol, newPol, watch_list_out_curr, props );
+ if( c.isNull() ){
+ ret = Node::null();
+ ret_set = true;
+ break;
+ }else if( c==d_true || c==d_false ){
+ //short-circuiting
+ if( k==kind::AND || k==kind::OR ){
+ if( (k==kind::AND)==(c==d_false) ){
+ ret = c;
+ ret_set = true;
+ break;
+ }else{
+ //redundant
+ c = Node::null();
+ childChanged = true;
+ }
+ }else if( k==kind::ITE && i==0 ){
+ Assert( watch_list_out_curr.empty() );
+ ret = evaluateTermExp( n[ c==d_true ? 1 : 2], exp, visited, hasPol, pol, watch_list_out_curr, props );
+ ret_set = true;
+ break;
+ }else if( k==kind::NOT ){
+ ret = c==d_true ? d_false : d_true;
+ ret_set = true;
+ break;
+ }
+ }
+ if( !c.isNull() ){
+ childChanged = childChanged || n[i]!=c;
+ if( !f.isNull() && !watch_list_out_curr.empty() ){
+ // we are done if this is an UF application and an argument is unevaluated
+ args.push_back( c );
+ abort_i = i;
+ break;
+ }else if( ( k==kind::AND || k==kind::OR ) ){
+ if( c.getKind()==k ){
+ //flatten
+ for( unsigned j=0; j<c.getNumChildren(); j++ ){
+ addArgument( args, props, c[j], newHasPol, newPol );
+ }
+ }else{
+ addArgument( args, props, c, newHasPol, newPol );
+ }
+ //if we are in a branching position
+ if( hasPol && !newHasPol && args.size()>=2 ){
+ //we are done if at least two args are unevaluated
+ abort_i = i;
+ break;
+ }
+ }else if( k==kind::ITE ){
+ //we are done if we are ITE and condition is unevaluated
+ Assert( i==0 );
+ args.push_back( c );
+ abort_i = i;
+ break;
+ }else{
+ args.push_back( c );
+ }
+ }
+ }
+ //add remaining children if we aborted
+ if( abort_i!=-1 ){
+ for( int i=(abort_i+1); i<(int)n.getNumChildren(); i++ ){
+ args.push_back( n[i] );
+ }
+ }
+ //copy over the watch list
+ for( std::map< Node, bool >::iterator itc = watch_list_out_curr.begin(); itc != watch_list_out_curr.end(); ++itc ){
+ watch_list_out[itc->first] = itc->second;
+ }
+
+ //if we have not short-circuited evaluation
+ if( !ret_set ){
+ //if it is an indexed term, return the congruent term
+ if( !f.isNull() && watch_list_out.empty() ){
+ std::vector< TNode > t_args;
+ for( unsigned i=0; i<args.size(); i++ ) {
+ t_args.push_back( args[i] );
+ }
+ Assert( args.size()==n.getNumChildren() );
+ //args contains terms known by the equality engine
+ TNode nn = getCongruentTerm( f, t_args );
+ Trace("qip-eval") << " got congruent term " << nn << " from DB for " << n << std::endl;
+ if( !nn.isNull() ){
+ //successfully constructed representative in EE
+ Assert( exp_n.empty() );
+ ret = getRepresentativeExp( nn, exp_n );
+ Trace("qip-eval") << "return rep, exp size = " << exp_n.size() << std::endl;
+ merge_exp( exp, exp_n );
+ ret_set = true;
+ Assert( !ret.isNull() );
+ }
+ }
+ if( !ret_set ){
+ if( childChanged ){
+ Trace("qip-eval") << "return rewrite" << std::endl;
+ if( ( k==kind::AND || k==kind::OR ) ){
+ if( args.empty() ){
+ ret = k==kind::AND ? d_true : d_false;
+ ret_set = true;
+ }else if( args.size()==1 ){
+ ret = args[0];
+ ret_set = true;
+ }
+ }else{
+ Assert( args.size()==n.getNumChildren() );
+ }
+ if( !ret_set ){
+ if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
+ args.insert( args.begin(), n.getOperator() );
+ }
+ ret = NodeManager::currentNM()->mkNode( k, args );
+ ret = Rewriter::rewrite( ret );
+ //re-evaluate
+ Node ret_eval = getRepresentativeExp( ret, exp_n );
+ if( !ret_eval.isNull() ){
+ ret = ret_eval;
+ watch_list_out.clear();
+ }else{
+ watch_list_out[ret] = true;
+ }
+ }
+ }else{
+ ret = n;
+ watch_list_out[ret] = true;
+ }
+ }
+ }
+ }
+ }else{
+ Trace("qip-eval") << "...exists in ee, return rep, exp size = " << exp_n.size() << std::endl;
+ merge_exp( exp, exp_n );
+ }
+ Trace("qip-eval") << "evaluated term : " << n << ", got : " << ret << ", exp size = " << exp.size() << std::endl;
+ visited[n] = ret;
+ return ret;
+ }
+}
+
+void EqualityQueryInstProp::merge_exp( std::vector< Node >& v, std::vector< Node >& v_to_merge, int up_to_size ) {
+ //TODO : optimize
+ if( v.empty() ){
+ Assert( up_to_size==-1 || up_to_size==(int)v_to_merge.size() );
+ v.insert( v.end(), v_to_merge.begin(), v_to_merge.end() );
+ }else{
+ //std::vector< Node >::iterator v_end = v.end();
+ up_to_size = up_to_size==-1 ? (int)v_to_merge.size() : up_to_size;
+ for( int j=0; j<up_to_size; j++ ){
+ if( std::find( v.begin(), v.end(), v_to_merge[j] )==v.end() ){
+ v.push_back( v_to_merge[j] );
+ }
+ }
+ }
+}
+
+
+void InstPropagator::InstInfo::init( Node q, Node lem, std::vector< Node >& terms, Node body ) {
+ d_active = true;
+ //information about the instance
+ d_q = q;
+ d_lem = lem;
+ Assert( d_terms.empty() );
+ d_terms.insert( d_terms.end(), terms.begin(), terms.end() );
+ //the current lemma
+ d_curr = body;
+ d_curr_exp.push_back( body );
+}
+
+InstPropagator::InstPropagator( QuantifiersEngine* qe ) :
+d_qe( qe ), d_notify(*this), d_qy( qe ){
+}
+
+bool InstPropagator::reset( Theory::Effort e ) {
+ d_icount = 1;
+ d_ii.clear();
+ for( unsigned i=0; i<2; i++ ){
+ d_conc_to_id[i].clear();
+ d_conc_to_id[i][d_qy.d_true] = 0;
+ }
+ d_conflict = false;
+ d_watch_list.clear();
+ d_update_list.clear();
+ d_relevant_inst.clear();
+ return d_qy.reset( e );
+}
+
+bool InstPropagator::notifyInstantiation( unsigned quant_e, Node q, Node lem, std::vector< Node >& terms, Node body ) {
+ if( !d_conflict ){
+ if( Trace.isOn("qip-prop") ){
+ Trace("qip-prop") << "InstPropagator:: Notify instantiation " << q << " : " << std::endl;
+ for( unsigned i=0; i<terms.size(); i++ ){
+ Trace("qip-prop") << " " << terms[i] << std::endl;
+ }
+ }
+ unsigned id = d_icount;
+ d_icount++;
+ Trace("qip-prop") << "...assign id=" << id << std::endl;
+ d_ii[id].init( q, lem, terms, body );
+ //initialize the information
+ if( cacheConclusion( id, body ) ){
+ Assert( d_update_list.empty() );
+ d_update_list.push_back( id );
+ bool firstTime = true;
+ //update infos in the update list until empty
+ do {
+ unsigned uid = d_update_list.back();
+ d_update_list.pop_back();
+ if( d_ii[uid].d_active ){
+ update( uid, d_ii[uid], firstTime );
+ }
+ firstTime = false;
+ }while( !d_conflict && !d_update_list.empty() );
+ }else{
+ d_ii[id].d_active = false;
+ Trace("qip-prop") << "...duplicate." << std::endl;
+ }
+ Trace("qip-prop") << "...finished notify instantiation." << std::endl;
+ return !d_conflict;
+ }else{
+ Assert( false );
+ return true;
+ }
+}
+
+bool InstPropagator::update( unsigned id, InstInfo& ii, bool firstTime ) {
+ Assert( !d_conflict );
+ Assert( ii.d_active );
+ Trace("qip-prop-debug") << "Update info [" << id << "]..." << std::endl;
+ //update the evaluation of the current lemma
+ std::map< Node, Node > visited;
+ std::map< Node, bool > watch_list;
+ std::vector< Node > props;
+ Node eval = d_qy.evaluateTermExp( ii.d_curr, ii.d_curr_exp, visited, true, true, watch_list, props );
+ if( eval.isNull() ){
+ ii.d_active = false;
+ }else if( firstTime || eval!=ii.d_curr ){
+ if( EqualityQueryInstProp::isLiteral( eval ) ){
+ props.push_back( eval );
+ eval = d_qy.d_true;
+ watch_list.clear();
+ }
+ if( Trace.isOn("qip-prop") ){
+ Trace("qip-prop") << "Update info [" << id << "]..." << std::endl;
+ Trace("qip-prop") << "...updated lemma " << ii.d_curr << " -> " << eval << ", exp = ";
+ debugPrintExplanation( ii.d_curr_exp, "qip-prop" );
+ Trace("qip-prop") << std::endl;
+ Trace("qip-prop") << "...watch list: " << std::endl;
+ for( std::map< Node, bool >::iterator itw = watch_list.begin(); itw!=watch_list.end(); ++itw ){
+ Trace("qip-prop") << " " << itw->first << std::endl;
+ }
+ Trace("qip-prop") << "...new propagations: " << std::endl;
+ for( unsigned i=0; i<props.size(); i++ ){
+ Trace("qip-prop") << " " << props[i] << std::endl;
+ }
+ Trace("qip-prop") << std::endl;
+ }
+ //determine the status of eval
+ if( eval==d_qy.d_false ){
+ Assert( props.empty() );
+ //we have inferred a conflict
+ conflict( ii.d_curr_exp );
+ return false;
+ }else{
+ for( unsigned i=0; i<props.size(); i++ ){
+ Trace("qip-prop-debug2") << "Process propagation " << props[i] << std::endl;
+ //if we haven't propagated this literal yet
+ if( cacheConclusion( id, props[i], 1 ) ){
+ Node lit = props[i].getKind()==NOT ? props[i][0] : props[i];
+ bool pol = props[i].getKind()!=NOT;
+ if( lit.getKind()==EQUAL ){
+ propagate( lit[0], lit[1], pol, ii.d_curr_exp );
+ }else{
+ propagate( lit, pol ? d_qy.d_true : d_qy.d_false, true, ii.d_curr_exp );
+ }
+ if( d_conflict ){
+ return false;
+ }
+ }
+ Trace("qip-prop-debug2") << "Done process propagation " << props[i] << std::endl;
+ }
+ //if we have not inferred this conclusion yet
+ if( cacheConclusion( id, eval ) ){
+ ii.d_curr = eval;
+ //update the watch list
+ Trace("qip-prop-debug") << "...updating watch list for [" << id << "], curr is " << ii.d_curr << std::endl;
+ //Here, we need to be notified of enough terms such that if we are not notified, then update( ii ) will return no propagations.
+ // Similar to two-watched literals, but since we are in UF, we need to watch all terms on a complete path of two terms.
+ for( std::map< Node, bool >::iterator itw = watch_list.begin(); itw != watch_list.end(); ++itw ){
+ d_watch_list[ itw->first ][ id ] = true;
+ }
+ }else{
+ Trace("qip-prop-debug") << "...conclusion " << eval << " is duplicate." << std::endl;
+ ii.d_active = false;
+ }
+ }
+ }else{
+ Trace("qip-prop-debug") << "...did not update." << std::endl;
+ }
+ Assert( !d_conflict );
+ return true;
+}
+
+void InstPropagator::propagate( Node a, Node b, bool pol, std::vector< Node >& exp ) {
+ if( Trace.isOn("qip-propagate") ){
+ Trace("qip-propagate") << "* Propagate " << a << ( pol ? " == " : " != " ) << b << ", exp = ";
+ debugPrintExplanation( exp, "qip-propagate" );
+ Trace("qip-propagate") << "..." << std::endl;
+ }
+ //set equal
+ int status = d_qy.setEqual( a, b, pol, exp );
+ if( status==EqualityQueryInstProp::STATUS_NONE ){
+ Trace("qip-prop-debug") << "...already equal/no conflict." << std::endl;
+ return;
+ }else if( status==EqualityQueryInstProp::STATUS_CONFLICT ){
+ Trace("qip-prop-debug") << "...conflict." << std::endl;
+ conflict( exp );
+ return;
+ }
+ if( pol ){
+ if( status==EqualityQueryInstProp::STATUS_MERGED_KNOWN ){
+ Assert( d_qy.getEngine()->hasTerm( a ) );
+ Assert( d_qy.getEngine()->hasTerm( b ) );
+ Trace("qip-prop-debug") << "...equality between known terms." << std::endl;
+ addRelevantInstances( exp, "qip-propagate" );
+ }
+ Trace("qip-prop-debug") << "...merged representatives " << a << " and " << b << std::endl;
+ for( unsigned i=0; i<2; i++ ){
+ //update terms from watched lists
+ Node c = i==0 ? a : b;
+ std::map< Node, std::map< unsigned, bool > >::iterator it = d_watch_list.find( c );
+ if( it!=d_watch_list.end() ){
+ Trace("qip-prop-debug") << "...update ids from watch list of " << c << ", size=" << it->second.size() << "..." << std::endl;
+ for( std::map< unsigned, bool >::iterator itw = it->second.begin(); itw != it->second.end(); ++itw ){
+ unsigned idw = itw->first;
+ if( std::find( d_update_list.begin(), d_update_list.end(), idw )==d_update_list.end() ){
+ Trace("qip-prop-debug") << "...will update " << idw << std::endl;
+ d_update_list.push_back( idw );
+ }
+ }
+ d_watch_list.erase( c );
+ }
+ }
+ }
+}
+
+void InstPropagator::conflict( std::vector< Node >& exp ) {
+ Trace("qip-propagate") << "Conflict, exp size =" << exp.size() << std::endl;
+ d_conflict = true;
+ d_relevant_inst.clear();
+ addRelevantInstances( exp, "qip-propagate" );
+
+ //now, inform quantifiers engine which instances should be retracted
+ Trace("qip-prop-debug") << "...remove instantiation ids : ";
+ for( std::map< unsigned, InstInfo >::iterator it = d_ii.begin(); it != d_ii.end(); ++it ){
+ if( d_relevant_inst.find( it->first )==d_relevant_inst.end() ){
+ if( !d_qe->removeInstantiation( it->second.d_q, it->second.d_lem, it->second.d_terms ) ){
+ Trace("qip-warn") << "WARNING : did not remove instantiation id " << it->first << std::endl;
+ Assert( false );
+ }else{
+ Trace("qip-prop-debug") << it->first << " ";
+ }
+ }else{
+ //mark the quantified formula as relevant
+ d_qe->markRelevant( it->second.d_q );
+ }
+ }
+ Trace("qip-prop-debug") << std::endl;
+ //will interupt the quantifiers engine
+ Trace("quant-engine-conflict") << "-----> InstPropagator::conflict with " << exp.size() << " instances." << std::endl;
+}
+
+bool InstPropagator::cacheConclusion( unsigned id, Node body, int prop_index ) {
+ Assert( prop_index==0 || prop_index==1 );
+ //check if the conclusion is non-redundant
+ if( d_conc_to_id[prop_index].find( body )==d_conc_to_id[prop_index].end() ){
+ d_conc_to_id[prop_index][body] = id;
+ return true;
+ }else{
+ return false;
+ }
+}
+
+void InstPropagator::addRelevantInstances( std::vector< Node >& exp, const char * c ) {
+ for( unsigned i=0; i<exp.size(); i++ ){
+ Assert( d_conc_to_id[0].find( exp[i] )!=d_conc_to_id[0].end() );
+ Trace(c) << " relevant instance id : " << d_conc_to_id[0][ exp[i] ] << std::endl;
+ d_relevant_inst[ d_conc_to_id[0][ exp[i] ] ] = true;
+ }
+}
+
+void InstPropagator::debugPrintExplanation( std::vector< Node >& exp, const char * c ) {
+ for( unsigned i=0; i<exp.size(); i++ ){
+ Assert( d_conc_to_id[0].find( exp[i] )!=d_conc_to_id[0].end() );
+ Trace(c) << d_conc_to_id[0][ exp[i] ] << " ";
+ }
+}
+
diff --git a/src/theory/quantifiers/inst_propagator.h b/src/theory/quantifiers/inst_propagator.h
new file mode 100644
index 000000000..0c02c7f95
--- /dev/null
+++ b/src/theory/quantifiers/inst_propagator.h
@@ -0,0 +1,163 @@
+/********************* */
+/*! \file inst_propagator.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Propagate mechanism for instantiations
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__QUANTIFIERS_INST_PROPAGATOR_H
+#define __CVC4__QUANTIFIERS_INST_PROPAGATOR_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include "expr/node.h"
+#include "expr/type_node.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/quantifiers/term_database.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class EqualityQueryInstProp : public EqualityQuery {
+private:
+ /** pointer to quantifiers engine */
+ QuantifiersEngine* d_qe;
+public:
+ EqualityQueryInstProp( QuantifiersEngine* qe );
+ ~EqualityQueryInstProp(){};
+ /** reset */
+ bool reset( Theory::Effort e );
+ /** identify */
+ std::string identify() const { return "EqualityQueryInstProp"; }
+ /** extends engine */
+ bool extendsEngine() { return true; }
+ /** contains term */
+ bool hasTerm( Node a );
+ /** get the representative of the equivalence class of a */
+ Node getRepresentative( Node a );
+ /** returns true if a and b are equal in the current context */
+ bool areEqual( Node a, Node b );
+ /** returns true is a and b are disequal in the current context */
+ bool areDisequal( Node a, Node b );
+ /** get the equality engine associated with this query */
+ eq::EqualityEngine* getEngine();
+ /** get the equivalence class of a */
+ void getEquivalenceClass( Node a, std::vector< Node >& eqc );
+ /** get congruent term */
+ TNode getCongruentTerm( Node f, std::vector< TNode >& args );
+public:
+ /** get the representative of the equivalence class of a, with explanation */
+ Node getRepresentativeExp( Node a, std::vector< Node >& exp );
+ /** returns true if a and b are equal in the current context */
+ bool areEqualExp( Node a, Node b, std::vector< Node >& exp );
+ /** returns true is a and b are disequal in the current context */
+ bool areDisequalExp( Node a, Node b, std::vector< Node >& exp );
+private:
+ /** term index */
+ std::map< Node, TermArgTrie > d_func_map_trie;
+ /** union find for terms beyond what is stored in equality engine */
+ std::map< Node, Node > d_uf;
+ std::map< Node, std::vector< Node > > d_uf_exp;
+ Node getUfRepresentative( Node a, std::vector< Node >& exp );
+ /** disequality list, stores explanations */
+ std::map< Node, std::map< Node, std::vector< Node > > > d_diseq_list;
+ /** add arg */
+ void addArgument( std::vector< Node >& args, std::vector< Node >& props, Node n, bool is_prop, bool pol );
+public:
+ enum {
+ STATUS_CONFLICT,
+ STATUS_MERGED_KNOWN,
+ STATUS_MERGED_UNKNOWN,
+ STATUS_NONE,
+ };
+ /** set equal */
+ int setEqual( Node& a, Node& b, bool pol, std::vector< Node >& reason );
+ Node d_true;
+ Node d_false;
+public:
+ //for explanations
+ static void merge_exp( std::vector< Node >& v, std::vector< Node >& v_to_merge, int up_to_size = -1 );
+
+ Node evaluateTermExp( Node n, std::vector< Node >& exp, std::map< Node, Node >& visited, bool hasPol, bool pol,
+ std::map< Node, bool >& watch_list_out, std::vector< Node >& props );
+ static bool isLiteral( Node n );
+};
+
+class InstPropagator : public QuantifiersUtil {
+private:
+ /** pointer to quantifiers engine */
+ QuantifiersEngine* d_qe;
+ /** notify class */
+ class InstantiationNotifyInstPropagator : public InstantiationNotify {
+ InstPropagator& d_ip;
+ public:
+ InstantiationNotifyInstPropagator(InstPropagator& ip): d_ip(ip) {}
+ virtual bool notifyInstantiation( unsigned quant_e, Node q, Node lem, std::vector< Node >& terms, Node body ) {
+ return d_ip.notifyInstantiation( quant_e, q, lem, terms, body );
+ }
+ };
+ InstantiationNotifyInstPropagator d_notify;
+ /** notify instantiation method */
+ bool notifyInstantiation( unsigned quant_e, Node q, Node lem, std::vector< Node >& terms, Node body );
+ /** equality query */
+ EqualityQueryInstProp d_qy;
+ class InstInfo {
+ public:
+ bool d_active;
+ Node d_q;
+ Node d_lem;
+ std::vector< Node > d_terms;
+ // the current entailed body
+ Node d_curr;
+ //explanation for current entailed body
+ std::vector< Node > d_curr_exp;
+ void init( Node q, Node lem, std::vector< Node >& terms, Node body );
+ };
+ /** instantiation count/info */
+ unsigned d_icount;
+ std::map< unsigned, InstInfo > d_ii;
+ std::map< Node, unsigned > d_conc_to_id[2];
+ /** are we in conflict */
+ bool d_conflict;
+ /** watch list */
+ std::map< Node, std::map< unsigned, bool > > d_watch_list;
+ /** update list */
+ std::vector< unsigned > d_update_list;
+ /** relevant instances */
+ std::map< unsigned, bool > d_relevant_inst;
+private:
+ bool update( unsigned id, InstInfo& i, bool firstTime = false );
+ void propagate( Node a, Node b, bool pol, std::vector< Node >& exp );
+ void conflict( std::vector< Node >& exp );
+ bool cacheConclusion( unsigned id, Node body, int prop_index = 0 );
+ void addRelevantInstances( std::vector< Node >& exp, const char * c );
+
+ void debugPrintExplanation( std::vector< Node >& exp, const char * c );
+public:
+ InstPropagator( QuantifiersEngine* qe );
+ ~InstPropagator(){}
+ /** reset */
+ bool reset( Theory::Effort e );
+ /** identify */
+ std::string identify() const { return "InstPropagator"; }
+ /** get the notify mechanism */
+ InstantiationNotify* getInstantiationNotify() { return &d_notify; }
+};
+
+}
+}
+}
+
+#endif
diff --git a/src/theory/quantifiers/inst_strategy_cbqi.cpp b/src/theory/quantifiers/inst_strategy_cbqi.cpp
index d5ef2e290..149330c61 100644
--- a/src/theory/quantifiers/inst_strategy_cbqi.cpp
+++ b/src/theory/quantifiers/inst_strategy_cbqi.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_strategy_cbqi.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of counterexample-guided quantifier instantiation strategies
**/
@@ -34,8 +34,9 @@ using namespace CVC4::theory::arith;
#define ARITH_INSTANTIATOR_USE_MINUS_DELTA
InstStrategyCbqi::InstStrategyCbqi( QuantifiersEngine * qe )
- : QuantifiersModule( qe )
- , d_added_cbqi_lemma( qe->getUserContext() ){
+ : QuantifiersModule( qe ), d_added_cbqi_lemma( qe->getUserContext() )
+//, d_added_inst( qe->getUserContext() )
+{
}
InstStrategyCbqi::~InstStrategyCbqi() throw(){}
@@ -45,7 +46,7 @@ bool InstStrategyCbqi::needsCheck( Theory::Effort e ) {
}
unsigned InstStrategyCbqi::needsModel( Theory::Effort e ) {
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
if( doCbqi( q ) && d_quantEngine->getModel()->isQuantifierActive( q ) ){
return QuantifiersEngine::QEFFORT_STANDARD;
@@ -58,7 +59,7 @@ void InstStrategyCbqi::reset_round( Theory::Effort effort ) {
d_cbqi_set_quant_inactive = false;
d_incomplete_check = false;
//check if any cbqi lemma has not been added yet
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
//it is not active if it corresponds to a rewrite rule: we will process in rewrite engine
if( doCbqi( q ) ){
@@ -106,6 +107,7 @@ void InstStrategyCbqi::reset_round( Theory::Effort effort ) {
void InstStrategyCbqi::check( Theory::Effort e, unsigned quant_e ) {
if( quant_e==QuantifiersEngine::QEFFORT_STANDARD ){
+ Assert( !d_quantEngine->inConflict() );
double clSet = 0;
if( Trace.isOn("cbqi-engine") ){
clSet = double(clock())/double(CLOCKS_PER_SEC);
@@ -113,13 +115,16 @@ void InstStrategyCbqi::check( Theory::Effort e, unsigned quant_e ) {
}
unsigned lastWaiting = d_quantEngine->getNumLemmasWaiting();
for( int ee=0; ee<=1; ee++ ){
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
if( doCbqi( q ) && d_quantEngine->getModel()->isQuantifierActive( q ) ){
process( q, e, ee );
+ if( d_quantEngine->inConflict() ){
+ break;
+ }
}
}
- if( d_quantEngine->getNumLemmasWaiting()>lastWaiting ){
+ if( d_quantEngine->inConflict() || d_quantEngine->getNumLemmasWaiting()>lastWaiting ){
break;
}
}
@@ -162,13 +167,15 @@ void InstStrategyCbqi::registerCounterexampleLemma( Node q, Node lem ){
bool InstStrategyCbqi::hasNonCbqiOperator( Node n, std::map< Node, bool >& visited ){
if( visited.find( n )==visited.end() ){
visited[n] = true;
- if( n.getKind()!=INST_CONSTANT && TermDb::hasInstConstAttr( n ) ){
+ if( n.getKind()!=BOUND_VARIABLE && TermDb::hasBoundVarAttr( n ) ){
if( !inst::Trigger::isCbqiKind( n.getKind() ) ){
Trace("cbqi-debug2") << "Non-cbqi kind : " << n.getKind() << " in " << n << std::endl;
return true;
}else if( n.getKind()==MULT && ( n.getNumChildren()!=2 || !n[0].isConst() ) ){
Trace("cbqi-debug2") << "Non-linear arithmetic : " << n << std::endl;
return true;
+ }else if( n.getKind()==FORALL ){
+ return hasNonCbqiOperator( n[1], visited );
}else{
for( unsigned i=0; i<n.getNumChildren(); i++ ){
if( hasNonCbqiOperator( n[i], visited ) ){
@@ -201,20 +208,25 @@ bool InstStrategyCbqi::doCbqi( Node q ){
std::map< Node, bool >::iterator it = d_do_cbqi.find( q );
if( it==d_do_cbqi.end() ){
bool ret = false;
- //if has an instantiation pattern, don't do it
- if( q.getNumChildren()==3 && options::eMatching() && options::userPatternsQuant()!=USER_PAT_MODE_IGNORE ){
- ret = false;
+ if( d_quantEngine->getTermDatabase()->isQAttrQuantElim( q ) ){
+ ret = true;
}else{
- if( options::cbqiAll() ){
- ret = true;
+ //if has an instantiation pattern, don't do it
+ if( q.getNumChildren()==3 && options::eMatching() && options::userPatternsQuant()!=USER_PAT_MODE_IGNORE ){
+ ret = false;
}else{
- //if quantifier has a non-arithmetic variable, then do not use cbqi
- //if quantifier has an APPLY_UF term, then do not use cbqi
- Node cb = d_quantEngine->getTermDatabase()->getInstConstantBody( q );
- std::map< Node, bool > visited;
- ret = !hasNonCbqiVariable( q ) && !hasNonCbqiOperator( cb, visited );
+ if( options::cbqiAll() ){
+ ret = true;
+ }else{
+ //if quantifier has a non-arithmetic variable, then do not use cbqi
+ //if quantifier has an APPLY_UF term, then do not use cbqi
+ //Node cb = d_quantEngine->getTermDatabase()->getInstConstantBody( q );
+ std::map< Node, bool > visited;
+ ret = !hasNonCbqiVariable( q ) && !hasNonCbqiOperator( q[1], visited );
+ }
}
}
+ Trace("cbqi") << "doCbqi " << q << " returned " << ret << std::endl;
d_do_cbqi[q] = ret;
return ret;
}else{
@@ -224,7 +236,7 @@ bool InstStrategyCbqi::doCbqi( Node q ){
Node InstStrategyCbqi::getNextDecisionRequest(){
// all counterexample literals that are not asserted
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
if( hasAddedCbqiLemma( q ) ){
Node cel = d_quantEngine->getTermDatabase()->getCounterexampleLiteral( q );
@@ -304,8 +316,10 @@ void InstStrategySimplex::processResetInstantiationRound( Theory::Effort effort
}
}
//print debug
- Debug("quant-arith-debug") << std::endl;
- debugPrint( "quant-arith-debug" );
+ if( Debug.isOn("quant-arith-debug") ){
+ Debug("quant-arith-debug") << std::endl;
+ debugPrint( "quant-arith-debug" );
+ }
d_counter++;
}
@@ -343,10 +357,10 @@ void InstStrategySimplex::process( Node f, Theory::Effort effort, int e ){
bool m_point_valid = true;
int lem = 0;
//scan over all instantiation rows
- for( int i=0; i<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( f ); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( f ); i++ ){
Node ic = d_quantEngine->getTermDatabase()->getInstantiationConstant( f, i );
Debug("quant-arith-simplex") << "InstStrategySimplex check " << ic << ", rows = " << d_instRows[ic].size() << std::endl;
- for( int j=0; j<(int)d_instRows[ic].size(); j++ ){
+ for( unsigned j=0; j<d_instRows[ic].size(); j++ ){
ArithVar x = d_instRows[ic][j];
if( !d_ceTableaux[ic][x].empty() ){
if( Debug.isOn("quant-arith-simplex") ){
@@ -462,25 +476,25 @@ void InstStrategySimplex::debugPrint( const char* c ){
}
Debug(c) << std::endl;
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
Node f = d_quantEngine->getModel()->getAssertedQuantifier( i );
Debug(c) << f << std::endl;
Debug(c) << " Inst constants: ";
- for( int i=0; i<(int)d_quantEngine->getTermDatabase()->getNumInstantiationConstants( f ); i++ ){
- if( i>0 ){
+ for( unsigned j=0; j<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( f ); i++ ){
+ if( j>0 ){
Debug( c ) << ", ";
}
Debug( c ) << d_quantEngine->getTermDatabase()->getInstantiationConstant( f, i );
}
Debug(c) << std::endl;
- for( int j=0; j<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( f ); j++ ){
+ for( unsigned j=0; j<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( f ); j++ ){
Node ic = d_quantEngine->getTermDatabase()->getInstantiationConstant( f, j );
Debug(c) << " Instantiation rows for " << ic << " : ";
- for( int i=0; i<(int)d_instRows[ic].size(); i++ ){
- if( i>0 ){
+ for( unsigned k=0; k<d_instRows[ic].size(); k++ ){
+ if( k>0 ){
Debug(c) << ", ";
}
- Debug(c) << d_instRows[ic][i];
+ Debug(c) << d_instRows[ic][k];
}
Debug(c) << std::endl;
}
@@ -559,8 +573,8 @@ Node InstStrategySimplex::getTableauxValue( ArithVar v, bool minus_delta ){
//new implementation
-bool CegqiOutputInstStrategy::addInstantiation( std::vector< Node >& subs ) {
- return d_out->addInstantiation( subs );
+bool CegqiOutputInstStrategy::doAddInstantiation( std::vector< Node >& subs ) {
+ return d_out->doAddInstantiation( subs );
}
bool CegqiOutputInstStrategy::isEligibleForInstantiation( Node n ) {
@@ -580,24 +594,33 @@ InstStrategyCegqi::InstStrategyCegqi( QuantifiersEngine * qe )
InstStrategyCegqi::~InstStrategyCegqi() throw () {
delete d_out;
+
+ for(std::map< Node, CegInstantiator * >::iterator i = d_cinst.begin(),
+ iend = d_cinst.end(); i != iend; ++i) {
+ CegInstantiator * instantiator = (*i).second;
+ delete instantiator;
+ }
+ d_cinst.clear();
}
void InstStrategyCegqi::processResetInstantiationRound( Theory::Effort effort ) {
- d_check_vts_lemma_lc = true;
+ d_check_vts_lemma_lc = false;
}
-void InstStrategyCegqi::process( Node f, Theory::Effort effort, int e ) {
+void InstStrategyCegqi::process( Node q, Theory::Effort effort, int e ) {
if( e==0 ){
- CegInstantiator * cinst = getInstantiator( f );
- Trace("inst-alg") << "-> Run cegqi for " << f << std::endl;
- d_curr_quant = f;
+ CegInstantiator * cinst = getInstantiator( q );
+ Trace("inst-alg") << "-> Run cegqi for " << q << std::endl;
+ d_curr_quant = q;
if( !cinst->check() ){
d_incomplete_check = true;
+ d_check_vts_lemma_lc = true;
}
d_curr_quant = Node::null();
}else if( e==1 ){
//minimize the free delta heuristically on demand
if( d_check_vts_lemma_lc ){
+ Trace("inst-alg") << "-> Minimize delta heuristic, for " << q << std::endl;
d_check_vts_lemma_lc = false;
d_small_const = NodeManager::currentNM()->mkNode( MULT, d_small_const, d_small_const );
d_small_const = Rewriter::rewrite( d_small_const );
@@ -619,11 +642,24 @@ void InstStrategyCegqi::process( Node f, Theory::Effort effort, int e ) {
}
}
-bool InstStrategyCegqi::addInstantiation( std::vector< Node >& subs ) {
+bool InstStrategyCegqi::doAddInstantiation( std::vector< Node >& subs ) {
Assert( !d_curr_quant.isNull() );
- //check if we need virtual term substitution (if used delta or infinity)
- bool used_vts = d_quantEngine->getTermDatabase()->containsVtsTerm( subs, false );
- return d_quantEngine->addInstantiation( d_curr_quant, subs, false, false, false, used_vts );
+ //if doing partial quantifier elimination, record the instantiation and set the incomplete flag instead of sending instantiation lemma
+ if( d_quantEngine->getTermDatabase()->isQAttrQuantElimPartial( d_curr_quant ) ){
+ d_cbqi_set_quant_inactive = true;
+ d_incomplete_check = true;
+ d_quantEngine->recordInstantiationInternal( d_curr_quant, subs, false, false );
+ return true;
+ }else{
+ //check if we need virtual term substitution (if used delta or infinity)
+ bool used_vts = d_quantEngine->getTermDatabase()->containsVtsTerm( subs, false );
+ if( d_quantEngine->addInstantiation( d_curr_quant, subs, false, false, used_vts ) ){
+ //d_added_inst.insert( d_curr_quant );
+ return true;
+ }else{
+ return false;
+ }
+ }
}
bool InstStrategyCegqi::addLemma( Node lem ) {
@@ -665,7 +701,7 @@ void InstStrategyCegqi::registerCounterexampleLemma( Node q, Node lem ) {
//must register with the instantiator
//must explicitly remove ITEs so that we record dependencies
std::vector< Node > ce_vars;
- for( int i=0; i<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( q ); i++ ){
+ for( unsigned i=0; i<d_quantEngine->getTermDatabase()->getNumInstantiationConstants( q ); i++ ){
ce_vars.push_back( d_quantEngine->getTermDatabase()->getInstantiationConstant( q, i ) );
}
std::vector< Node > lems;
diff --git a/src/theory/quantifiers/inst_strategy_cbqi.h b/src/theory/quantifiers/inst_strategy_cbqi.h
index 5511af209..8ed59778b 100644
--- a/src/theory/quantifiers/inst_strategy_cbqi.h
+++ b/src/theory/quantifiers/inst_strategy_cbqi.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_strategy_cbqi.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief counterexample-guided quantifier instantiation
**/
@@ -39,6 +39,8 @@ protected:
bool d_incomplete_check;
/** whether we have added cbqi lemma */
NodeSet d_added_cbqi_lemma;
+ /** whether we have instantiated quantified formulas */
+ //NodeSet d_added_inst;
/** whether to do cbqi for this quantified formula */
std::map< Node, bool > d_do_cbqi;
/** register ce lemma */
@@ -120,7 +122,7 @@ class CegqiOutputInstStrategy : public CegqiOutput {
public:
CegqiOutputInstStrategy( InstStrategyCegqi * out ) : d_out( out ){}
InstStrategyCegqi * d_out;
- bool addInstantiation( std::vector< Node >& subs );
+ bool doAddInstantiation( std::vector< Node >& subs );
bool isEligibleForInstantiation( Node n );
bool addLemma( Node lem );
};
@@ -141,7 +143,7 @@ public:
InstStrategyCegqi( QuantifiersEngine * qe );
~InstStrategyCegqi() throw();
- bool addInstantiation( std::vector< Node >& subs );
+ bool doAddInstantiation( std::vector< Node >& subs );
bool isEligibleForInstantiation( Node n );
bool addLemma( Node lem );
/** identify */
diff --git a/src/theory/quantifiers/inst_strategy_e_matching.cpp b/src/theory/quantifiers/inst_strategy_e_matching.cpp
index 299eb51fd..630880690 100644
--- a/src/theory/quantifiers/inst_strategy_e_matching.cpp
+++ b/src/theory/quantifiers/inst_strategy_e_matching.cpp
@@ -1,20 +1,18 @@
/********************* */
/*! \file inst_strategy_e_matching.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of e matching instantiation strategies
**/
#include "theory/quantifiers/inst_strategy_e_matching.h"
-
-#include "options/quantifiers_options.h"
#include "theory/quantifiers/inst_match_generator.h"
#include "theory/quantifiers/relevant_domain.h"
#include "theory/quantifiers/term_database.h"
@@ -51,15 +49,18 @@ struct sortQuantifiersForSymbol {
struct sortTriggers {
bool operator() (Node i, Node j) {
- if( Trigger::isAtomicTrigger( i ) ){
- return i<j || !Trigger::isAtomicTrigger( j );
+ int wi = Trigger::getTriggerWeight( i );
+ int wj = Trigger::getTriggerWeight( j );
+ if( wi==wj ){
+ return i<j;
}else{
- return i<j && !Trigger::isAtomicTrigger( j );
+ return wi<wj;
}
}
};
void InstStrategyUserPatterns::processResetInstantiationRound( Theory::Effort effort ){
+ Trace("inst-alg-debug") << "reset user triggers" << std::endl;
//reset triggers
for( std::map< Node, std::vector< Trigger* > >::iterator it = d_user_gen.begin(); it != d_user_gen.end(); ++it ){
for( unsigned i=0; i<it->second.size(); i++ ){
@@ -67,6 +68,7 @@ void InstStrategyUserPatterns::processResetInstantiationRound( Theory::Effort ef
it->second[i]->reset( Node::null() );
}
}
+ Trace("inst-alg-debug") << "done reset user triggers" << std::endl;
}
int InstStrategyUserPatterns::process( Node f, Theory::Effort effort, int e ){
@@ -83,7 +85,7 @@ int InstStrategyUserPatterns::process( Node f, Theory::Effort effort, int e ){
if( d_quantEngine->getInstUserPatMode()==USER_PAT_MODE_RESORT ){
int matchOption = 0;
for( unsigned i=0; i<d_user_gen_wait[f].size(); i++ ){
- Trigger * t = Trigger::mkTrigger( d_quantEngine, f, d_user_gen_wait[f][i], matchOption, true, Trigger::TR_RETURN_NULL, options::smartTriggers() );
+ Trigger * t = Trigger::mkTrigger( d_quantEngine, f, d_user_gen_wait[f][i], matchOption, true, Trigger::TR_RETURN_NULL );
if( t ){
d_user_gen[f].push_back( t );
}
@@ -104,7 +106,9 @@ int InstStrategyUserPatterns::process( Node f, Theory::Effort effort, int e ){
if( d_user_gen[f][i]->isMultiTrigger() ){
d_quantEngine->d_statistics.d_multi_trigger_instantiations += numInst;
}
- //d_quantEngine->d_hasInstantiated[f] = true;
+ if( d_quantEngine->inConflict() ){
+ break;
+ }
}
}
}
@@ -118,11 +122,13 @@ void InstStrategyUserPatterns::addUserPattern( Node q, Node pat ){
bool usable = true;
std::vector< Node > nodes;
for( unsigned i=0; i<pat.getNumChildren(); i++ ){
- nodes.push_back( pat[i] );
- if( pat[i].getKind()!=INST_CONSTANT && !Trigger::isUsableTrigger( pat[i], q ) ){
+ Node pat_use = Trigger::getIsUsableTrigger( pat[i], q );
+ if( pat_use.isNull() ){
Trace("trigger-warn") << "User-provided trigger is not usable : " << pat << " because of " << pat[i] << std::endl;
usable = false;
break;
+ }else{
+ nodes.push_back( pat_use );
}
}
if( usable ){
@@ -132,19 +138,22 @@ void InstStrategyUserPatterns::addUserPattern( Node q, Node pat ){
if( d_quantEngine->getInstUserPatMode()==USER_PAT_MODE_RESORT ){
d_user_gen_wait[q].push_back( nodes );
}else{
- d_user_gen[q].push_back( Trigger::mkTrigger( d_quantEngine, q, nodes, matchOption, true, Trigger::TR_MAKE_NEW, options::smartTriggers() ) );
+ Trigger * t = Trigger::mkTrigger( d_quantEngine, q, nodes, matchOption, true, Trigger::TR_MAKE_NEW );
+ if( t ){
+ d_user_gen[q].push_back( t );
+ }else{
+ Trace("trigger-warn") << "Failed to construct trigger : " << pat << " due to variable mismatch" << std::endl;
+ }
}
}
}
InstStrategyAutoGenTriggers::InstStrategyAutoGenTriggers( QuantifiersEngine* qe ) : InstStrategy( qe ){
//how to select trigger terms
- if( options::triggerSelMode()==TRIGGER_SEL_MIN ){
- d_tr_strategy = Trigger::TS_MIN_TRIGGER;
- }else if( options::triggerSelMode()==TRIGGER_SEL_MAX ){
- d_tr_strategy = Trigger::TS_MAX_TRIGGER;
+ if( options::triggerSelMode()==quantifiers::TRIGGER_SEL_DEFAULT ){
+ d_tr_strategy = quantifiers::TRIGGER_SEL_MIN;
}else{
- d_tr_strategy = Trigger::TS_ALL;
+ d_tr_strategy = options::triggerSelMode();
}
//whether to select new triggers during the search
if( options::incrementTriggers() ){
@@ -156,6 +165,7 @@ InstStrategyAutoGenTriggers::InstStrategyAutoGenTriggers( QuantifiersEngine* qe
}
void InstStrategyAutoGenTriggers::processResetInstantiationRound( Theory::Effort effort ){
+ Trace("inst-alg-debug") << "reset auto-gen triggers" << std::endl;
//reset triggers
for( unsigned r=0; r<2; r++ ){
for( std::map< Node, std::map< Trigger*, bool > >::iterator it = d_auto_gen_trigger[r].begin(); it != d_auto_gen_trigger[r].end(); ++it ){
@@ -166,6 +176,7 @@ void InstStrategyAutoGenTriggers::processResetInstantiationRound( Theory::Effort
}
}
d_processed_trigger.clear();
+ Trace("inst-alg-debug") << "done reset auto-gen triggers" << std::endl;
}
int InstStrategyAutoGenTriggers::process( Node f, Theory::Effort effort, int e ){
@@ -220,11 +231,13 @@ int InstStrategyAutoGenTriggers::process( Node f, Theory::Effort effort, int e )
if( r==1 ){
d_quantEngine->d_statistics.d_multi_trigger_instantiations += numInst;
}
- //d_quantEngine->d_hasInstantiated[f] = true;
+ if( d_quantEngine->inConflict() ){
+ break;
+ }
}
}
}
- if( hasInst && options::multiTriggerPriority() ){
+ if( d_quantEngine->inConflict() || ( hasInst && options::multiTriggerPriority() ) ){
break;
}
}
@@ -237,67 +250,102 @@ int InstStrategyAutoGenTriggers::process( Node f, Theory::Effort effort, int e )
}
void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
- Trace("auto-gen-trigger-debug") << "Generate triggers for " << f << std::endl;
+ Trace("auto-gen-trigger-debug") << "Generate triggers for " << f << ", #var=" << f[0].getNumChildren() << "..." << std::endl;
if( d_patTerms[0].find( f )==d_patTerms[0].end() ){
//determine all possible pattern terms based on trigger term selection strategy d_tr_strategy
d_patTerms[0][f].clear();
d_patTerms[1][f].clear();
bool ntrivTriggers = options::relationalTriggers();
std::vector< Node > patTermsF;
+ std::map< Node, inst::TriggerTermInfo > tinfo;
//well-defined function: can assume LHS is only trigger
if( options::quantFunWellDefined() ){
Node hd = TermDb::getFunDefHead( f );
if( !hd.isNull() ){
hd = d_quantEngine->getTermDatabase()->getInstConstantNode( hd, f );
patTermsF.push_back( hd );
+ tinfo[hd].init( f, hd );
}
}
//otherwise, use algorithm for collecting pattern terms
if( patTermsF.empty() ){
Node bd = d_quantEngine->getTermDatabase()->getInstConstantBody( f );
- Trigger::collectPatTerms( d_quantEngine, f, bd, patTermsF, d_tr_strategy, d_user_no_gen[f], true );
- Trace("auto-gen-trigger-debug") << "Collected pat terms for " << bd << ", no-patterns : " << d_user_no_gen[f].size() << std::endl;
- Trace("auto-gen-trigger-debug") << " ";
- for( int i=0; i<(int)patTermsF.size(); i++ ){
- Trace("auto-gen-trigger-debug") << patTermsF[i] << " ";
- }
- Trace("auto-gen-trigger-debug") << std::endl;
+ Trigger::collectPatTerms( f, bd, patTermsF, d_tr_strategy, d_user_no_gen[f], tinfo, true );
if( ntrivTriggers ){
sortTriggers st;
std::sort( patTermsF.begin(), patTermsF.end(), st );
}
+ if( Trace.isOn("auto-gen-trigger-debug") ){
+ Trace("auto-gen-trigger-debug") << "Collected pat terms for " << bd << ", no-patterns : " << d_user_no_gen[f].size() << std::endl;
+ for( unsigned i=0; i<patTermsF.size(); i++ ){
+ Assert( tinfo.find( patTermsF[i] )!=tinfo.end() );
+ Trace("auto-gen-trigger-debug") << " " << patTermsF[i];
+ Trace("auto-gen-trigger-debug") << " info[" << tinfo[patTermsF[i]].d_reqPol << ", " << tinfo[patTermsF[i]].d_reqPolEq << ", " << tinfo[patTermsF[i]].d_fv.size() << "]" << std::endl;
+ }
+ Trace("auto-gen-trigger-debug") << std::endl;
+ }
}
- //sort into single/multi triggers
- std::map< Node, std::vector< Node > > varContains;
+ //sort into single/multi triggers, calculate which terms should not be considered
std::map< Node, bool > vcMap;
std::map< Node, bool > rmPatTermsF;
+ int last_weight = -1;
for( unsigned i=0; i<patTermsF.size(); i++ ){
- d_quantEngine->getTermDatabase()->getVarContainsNode( f, patTermsF[i], varContains[ patTermsF[i] ] );
+ Assert( patTermsF[i].getKind()!=NOT );
bool newVar = false;
- for( unsigned j=0; j<varContains[ patTermsF[i] ].size(); j++ ){
- if( vcMap.find( varContains[ patTermsF[i] ][j] )==vcMap.end() ){
- vcMap[varContains[ patTermsF[i] ][j]] = true;
+ for( unsigned j=0; j<tinfo[ patTermsF[i] ].d_fv.size(); j++ ){
+ if( vcMap.find( tinfo[ patTermsF[i] ].d_fv[j] )==vcMap.end() ){
+ vcMap[tinfo[ patTermsF[i] ].d_fv[j]] = true;
newVar = true;
}
}
- if( ntrivTriggers && !newVar && !Trigger::isAtomicTrigger( patTermsF[i] ) ){
- Trace("auto-gen-trigger-debug") << "Exclude expendible non-trivial trigger : " << patTermsF[i] << std::endl;
+ int curr_w = Trigger::getTriggerWeight( patTermsF[i] );
+ if( ntrivTriggers && !newVar && last_weight!=-1 && curr_w>last_weight ){
+ Trace("auto-gen-trigger-debug") << "...exclude expendible non-trivial trigger : " << patTermsF[i] << std::endl;
rmPatTermsF[patTermsF[i]] = true;
+ }else{
+ last_weight = curr_w;
}
}
- for( std::map< Node, std::vector< Node > >::iterator it = varContains.begin(); it != varContains.end(); ++it ){
- if( rmPatTermsF.find( it->first )==rmPatTermsF.end() ){
- if( it->second.size()==f[0].getNumChildren() && ( options::pureThTriggers() || !Trigger::isPureTheoryTrigger( it->first ) ) ){
- d_patTerms[0][f].push_back( it->first );
- d_is_single_trigger[ it->first ] = true;
+ for( unsigned i=0; i<patTermsF.size(); i++ ){
+ Node pat = patTermsF[i];
+ if( rmPatTermsF.find( pat )==rmPatTermsF.end() ){
+ Trace("auto-gen-trigger-debug") << "...processing pattern " << pat << std::endl;
+ //process the pattern: if it has a required polarity, consider it
+ Assert( tinfo.find( pat )!=tinfo.end() );
+ int rpol = tinfo[pat].d_reqPol;
+ Node rpoleq = tinfo[pat].d_reqPolEq;
+ unsigned num_fv = tinfo[pat].d_fv.size();
+ Trace("auto-gen-trigger-debug") << "...required polarity for " << pat << " is " << rpol << ", eq=" << rpoleq << std::endl;
+ if( rpol!=0 ){
+ if( Trigger::isRelationalTrigger( pat ) ){
+ pat = rpol==-1 ? pat.negate() : pat;
+ }else{
+ Assert( Trigger::isAtomicTrigger( pat ) );
+ if( pat.getType().isBoolean() && rpoleq.isNull() ){
+ pat = NodeManager::currentNM()->mkNode( IFF, pat, NodeManager::currentNM()->mkConst( rpol==-1 ) ).negate();
+ }else{
+ Assert( !rpoleq.isNull() );
+ if( rpol==-1 ){
+ //all equivalence classes except rpoleq
+ pat = NodeManager::currentNM()->mkNode( EQUAL, pat, rpoleq ).negate();
+ }else if( rpol==1 ){
+ //all equivalence classes that are not disequal to rpoleq TODO
+ }
+ }
+ }
+ Trace("auto-gen-trigger-debug") << "...got : " << pat << std::endl;
}else{
- d_patTerms[1][f].push_back( it->first );
- d_is_single_trigger[ it->first ] = false;
+ if( Trigger::isRelationalTrigger( pat ) ){
+ //consider both polarities
+ addPatternToPool( f, pat.negate(), num_fv );
+ }
}
+ addPatternToPool( f, pat, num_fv );
}
}
+ //tinfo not used below this point
d_made_multi_trigger[f] = false;
- Trace("auto-gen-trigger") << "Single triggers for " << f << " : " << std::endl;
+ Trace("auto-gen-trigger") << "Single trigger pool for " << f << " : " << std::endl;
for( unsigned i=0; i<d_patTerms[0][f].size(); i++ ){
Trace("auto-gen-trigger") << " " << d_patTerms[0][f][i] << std::endl;
}
@@ -327,7 +375,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
//sort based on # occurrences (this will cause Trigger to select rarer symbols)
std::sort( patTerms.begin(), patTerms.end(), sqfs );
Debug("relevant-trigger") << "Terms based on relevance: " << std::endl;
- for( int i=0; i<(int)patTerms.size(); i++ ){
+ for( unsigned i=0; i<patTerms.size(); i++ ){
Debug("relevant-trigger") << " " << patTerms[i] << " (";
Debug("relevant-trigger") << d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[i].getOperator() ) << ")" << std::endl;
}
@@ -336,7 +384,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
int matchOption = 0;
Trigger* tr = NULL;
if( d_is_single_trigger[ patTerms[0] ] ){
- tr = Trigger::mkTrigger( d_quantEngine, f, patTerms[0], matchOption, false, Trigger::TR_RETURN_NULL, options::smartTriggers() );
+ tr = Trigger::mkTrigger( d_quantEngine, f, patTerms[0], matchOption, false, Trigger::TR_RETURN_NULL );
d_single_trigger_gen[ patTerms[0] ] = true;
}else{
//only generate multi trigger if option set, or if no single triggers exist
@@ -354,7 +402,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
d_made_multi_trigger[f] = true;
}
//will possibly want to get an old trigger
- tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, false, Trigger::TR_GET_OLD, options::smartTriggers() );
+ tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, false, Trigger::TR_GET_OLD );
}
if( tr ){
unsigned tindex;
@@ -390,7 +438,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
if( !options::relevantTriggers() ||
d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[index].getOperator() )<=nqfs_curr ){
d_single_trigger_gen[ patTerms[index] ] = true;
- Trigger* tr2 = Trigger::mkTrigger( d_quantEngine, f, patTerms[index], matchOption, false, Trigger::TR_RETURN_NULL, options::smartTriggers() );
+ Trigger* tr2 = Trigger::mkTrigger( d_quantEngine, f, patTerms[index], matchOption, false, Trigger::TR_RETURN_NULL );
if( tr2 ){
//Notice() << "Add additional trigger " << patTerms[index] << std::endl;
tr2->resetInstantiationRound();
@@ -409,6 +457,16 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){
}
}
+void InstStrategyAutoGenTriggers::addPatternToPool( Node q, Node pat, unsigned num_fv ) {
+ if( num_fv==q[0].getNumChildren() && ( options::pureThTriggers() || !Trigger::isPureTheoryTrigger( pat ) ) ){
+ d_patTerms[0][q].push_back( pat );
+ d_is_single_trigger[ pat ] = true;
+ }else{
+ d_patTerms[1][q].push_back( pat );
+ d_is_single_trigger[ pat ] = false;
+ }
+}
+
bool InstStrategyAutoGenTriggers::hasUserPatterns( Node q ) {
if( q.getNumChildren()==3 ){
std::map< Node, bool >::iterator it = d_hasUserPatterns.find( q );
@@ -462,7 +520,7 @@ bool InstStrategyLocalTheoryExt::isLocalTheoryExt( Node f ) {
}
Trace("local-t-ext") << std::endl;
int matchOption = 0;
- Trigger * tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, true, Trigger::TR_GET_OLD, options::smartTriggers() );
+ Trigger * tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, true, Trigger::TR_GET_OLD );
d_lte_trigger[f] = tr;
}else{
Trace("local-t-ext") << "No local theory extensions trigger for " << f << "." << std::endl;
@@ -515,12 +573,15 @@ void FullSaturation::check( Theory::Effort e, unsigned quant_e ) {
Trace("fs-engine") << "---Full Saturation Round, effort = " << e << "---" << std::endl;
}
int addedLemmas = 0;
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
- Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ Node q = d_quantEngine->getModel()->getAssertedQuantifier( i, true );
if( d_quantEngine->hasOwnership( q, this ) && d_quantEngine->getModel()->isQuantifierActive( q ) ){
if( process( q, fullEffort ) ){
//added lemma
addedLemmas++;
+ if( d_quantEngine->inConflict() ){
+ break;
+ }
}
}
}
@@ -538,18 +599,6 @@ bool FullSaturation::process( Node f, bool fullEffort ){
unsigned rstart = options::fullSaturateQuantRd() ? 0 : 1;
unsigned rend = fullEffort ? 1 : rstart;
for( unsigned r=rstart; r<=rend; r++ ){
- /*
- //complete guess
- if( d_guessed.find( f )==d_guessed.end() ){
- Trace("inst-alg") << "-> Guess instantiate " << f << "..." << std::endl;
- d_guessed[f] = true;
- InstMatch m( f );
- if( d_quantEngine->addInstantiation( f, m ) ){
- ++(d_quantEngine->d_statistics.d_instantiations_guess);
- return true;
- }
- }
- */
if( rd || r>0 ){
if( r==0 ){
Trace("inst-alg") << "-> Relevant domain instantiate " << f << "..." << std::endl;
@@ -566,7 +615,7 @@ bool FullSaturation::process( Node f, bool fullEffort ){
if( r==0 ){
ts = rd->getRDomain( f, i )->d_terms.size();
}else{
- ts = d_quantEngine->getTermDatabase()->d_type_map[f[0][i].getType()].size();
+ ts = d_quantEngine->getTermDatabase()->getNumTypeGroundTerms( f[0][i].getType() );
}
max_zero.push_back( fullEffort && ts==0 );
ts = ( fullEffort && ts==0 ) ? 1 : ts;
@@ -582,6 +631,11 @@ bool FullSaturation::process( Node f, bool fullEffort ){
}
}
if( !has_zero ){
+ std::vector< TypeNode > ftypes;
+ for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
+ ftypes.push_back( f[0][i].getType() );
+ }
+
Trace("inst-alg-rd") << "Will do " << final_max_i << " stages of instantiation." << std::endl;
unsigned max_i = 0;
bool success;
@@ -599,7 +653,7 @@ bool FullSaturation::process( Node f, bool fullEffort ){
if( options::cbqi() && r==1 && !max_zero[index] ){
//skip inst constant nodes
while( nv<maxs[index] && nv<=max_i &&
- quantifiers::TermDb::hasInstConstAttr( d_quantEngine->getTermDatabase()->d_type_map[f[0][index].getType()][nv] ) ){
+ quantifiers::TermDb::hasInstConstAttr( d_quantEngine->getTermDatabase()->getTypeGroundTerm( ftypes[index], nv ) ) ){
nv++;
}
}
@@ -625,13 +679,16 @@ bool FullSaturation::process( Node f, bool fullEffort ){
if( max_zero[i] ){
//no terms available, will report incomplete instantiation
terms.push_back( Node::null() );
+ Trace("inst-alg-rd") << " null" << std::endl;
}else if( r==0 ){
terms.push_back( rd->getRDomain( f, i )->d_terms[childIndex[i]] );
+ Trace("inst-alg-rd") << " " << rd->getRDomain( f, i )->d_terms[childIndex[i]] << std::endl;
}else{
- terms.push_back( d_quantEngine->getTermDatabase()->d_type_map[f[0][i].getType()][childIndex[i]] );
+ terms.push_back( d_quantEngine->getTermDatabase()->getTypeGroundTerm( ftypes[i], childIndex[i] ) );
+ Trace("inst-alg-rd") << " " << d_quantEngine->getTermDatabase()->getTypeGroundTerm( ftypes[i], childIndex[i] ) << std::endl;
}
}
- if( d_quantEngine->addInstantiation( f, terms, false ) ){
+ if( d_quantEngine->addInstantiation( f, terms ) ){
Trace("inst-alg-rd") << "Success!" << std::endl;
++(d_quantEngine->d_statistics.d_instantiations_guess);
return true;
diff --git a/src/theory/quantifiers/inst_strategy_e_matching.h b/src/theory/quantifiers/inst_strategy_e_matching.h
index 4e7afad5d..028f24b27 100644
--- a/src/theory/quantifiers/inst_strategy_e_matching.h
+++ b/src/theory/quantifiers/inst_strategy_e_matching.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file inst_strategy_e_matching.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief E matching instantiation strategies
**/
@@ -23,6 +23,7 @@
#include "theory/quantifiers/trigger.h"
#include "theory/quantifiers_engine.h"
#include "util/statistics_registry.h"
+#include "options/quantifiers_options.h"
namespace CVC4 {
namespace theory {
@@ -64,7 +65,7 @@ public:
};
private:
/** trigger generation strategy */
- int d_tr_strategy;
+ TriggerSelMode d_tr_strategy;
/** regeneration */
bool d_regenerate;
int d_regenerate_frequency;
@@ -73,6 +74,8 @@ private:
std::map< Node, int > d_counter;
/** single, multi triggers for each quantifier */
std::map< Node, std::vector< Node > > d_patTerms[2];
+ std::map< Node, std::map< Node, bool > > d_patReqPol;
+ /** information about triggers */
std::map< Node, bool > d_is_single_trigger;
std::map< Node, bool > d_single_trigger_gen;
std::map< Node, bool > d_made_multi_trigger;
@@ -86,6 +89,7 @@ private:
int process( Node q, Theory::Effort effort, int e );
/** generate triggers */
void generateTriggers( Node q );
+ void addPatternToPool( Node q, Node pat, unsigned num_fv );
//bool addTrigger( inst::Trigger * tr, Node f, unsigned r );
/** has user patterns */
bool hasUserPatterns( Node q );
diff --git a/src/theory/quantifiers/instantiation_engine.cpp b/src/theory/quantifiers/instantiation_engine.cpp
index 88a67e3c8..955dc5d86 100644
--- a/src/theory/quantifiers/instantiation_engine.cpp
+++ b/src/theory/quantifiers/instantiation_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file instantiation_engine.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of instantiation engine class
**/
@@ -60,7 +60,7 @@ void InstantiationEngine::presolve() {
}
}
-bool InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
+void InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
unsigned lastWaiting = d_quantEngine->getNumLemmasWaiting();
//iterate over an internal effort level e
int e = 0;
@@ -83,8 +83,10 @@ bool InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
InstStrategy* is = d_instStrategies[j];
Trace("inst-engine-debug") << "Do " << is->identify() << " " << e_use << std::endl;
int quantStatus = is->process( q, effort, e_use );
- Trace("inst-engine-debug") << " -> status is " << quantStatus << std::endl;
- if( quantStatus==InstStrategy::STATUS_UNFINISHED ){
+ Trace("inst-engine-debug") << " -> status is " << quantStatus << ", conflict=" << d_quantEngine->inConflict() << std::endl;
+ if( d_quantEngine->inConflict() ){
+ return;
+ }else if( quantStatus==InstStrategy::STATUS_UNFINISHED ){
finished = false;
}
}
@@ -96,13 +98,6 @@ bool InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
}
e++;
}
- //Notice() << "All instantiators finished, # added lemmas = " << (int)d_lemmas_waiting.size() << std::endl;
- if( !d_quantEngine->hasAddedLemma() ){
- return false;
- }else{
- Trace("inst-engine") << "Added lemmas = " << (int)(d_quantEngine->getNumLemmasWaiting()-lastWaiting) << std::endl;
- return true;
- }
}
bool InstantiationEngine::needsCheck( Theory::Effort e ){
@@ -128,8 +123,8 @@ void InstantiationEngine::check( Theory::Effort e, unsigned quant_e ){
//collect all active quantified formulas belonging to this
bool quantActive = false;
d_quants.clear();
- for( int i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
- Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ Node q = d_quantEngine->getModel()->getAssertedQuantifier( i, true );
if( d_quantEngine->hasOwnership( q, this ) && d_quantEngine->getModel()->isQuantifierActive( q ) ){
quantActive = true;
d_quants.push_back( q );
@@ -138,8 +133,18 @@ void InstantiationEngine::check( Theory::Effort e, unsigned quant_e ){
Trace("inst-engine-debug") << "InstEngine: check: # asserted quantifiers " << d_quants.size() << "/";
Trace("inst-engine-debug") << d_quantEngine->getModel()->getNumAssertedQuantifiers() << " " << quantActive << std::endl;
if( quantActive ){
- bool addedLemmas = doInstantiationRound( e );
- Trace("inst-engine-debug") << "Add lemmas = " << addedLemmas << std::endl;
+ unsigned lastWaiting = d_quantEngine->getNumLemmasWaiting();
+ doInstantiationRound( e );
+ if( d_quantEngine->inConflict() ){
+ Assert( d_quantEngine->getNumLemmasWaiting()>lastWaiting );
+ Trace("inst-engine") << "Conflict = " << d_quantEngine->getNumLemmasWaiting() << " / " << d_quantEngine->getNumLemmasAddedThisRound();
+ if( lastWaiting>0 ){
+ Trace("inst-engine") << " (prev " << lastWaiting << ")";
+ }
+ Trace("inst-engine") << std::endl;
+ }else if( d_quantEngine->hasAddedLemma() ){
+ Trace("inst-engine") << "Added lemmas = " << (d_quantEngine->getNumLemmasWaiting()-lastWaiting) << std::endl;
+ }
}else{
d_quants.clear();
}
@@ -165,6 +170,22 @@ bool InstantiationEngine::isIncomplete( Node q ) {
return true;
}
+void InstantiationEngine::preRegisterQuantifier( Node q ) {
+ if( options::strictTriggers() && q.getNumChildren()==3 ){
+ //if strict triggers, take ownership of this quantified formula
+ bool hasPat = false;
+ for( unsigned i=0; i<q[2].getNumChildren(); i++ ){
+ if( q[2][i].getKind()==INST_PATTERN || q[2][i].getKind()==INST_NO_PATTERN ){
+ hasPat = true;
+ break;
+ }
+ }
+ if( hasPat ){
+ d_quantEngine->setOwner( q, this, 1 );
+ }
+ }
+}
+
void InstantiationEngine::registerQuantifier( Node f ){
if( d_quantEngine->hasOwnership( f, this ) ){
//for( unsigned i=0; i<d_instStrategies.size(); ++i ){
diff --git a/src/theory/quantifiers/instantiation_engine.h b/src/theory/quantifiers/instantiation_engine.h
index bfa610369..d2b3740a1 100644
--- a/src/theory/quantifiers/instantiation_engine.h
+++ b/src/theory/quantifiers/instantiation_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file instantiation_engine.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Instantiation Engine classes
**/
@@ -70,7 +70,7 @@ private:
/** is the engine incomplete for this quantifier */
bool isIncomplete( Node q );
/** do instantiation round */
- bool doInstantiationRound( Theory::Effort effort );
+ void doInstantiationRound( Theory::Effort effort );
public:
InstantiationEngine( QuantifiersEngine* qe );
~InstantiationEngine();
@@ -79,6 +79,7 @@ public:
void reset_round( Theory::Effort e );
void check( Theory::Effort e, unsigned quant_e );
bool checkComplete();
+ void preRegisterQuantifier( Node q );
void registerQuantifier( Node q );
Node explain(TNode n){ return Node::null(); }
/** add user pattern */
diff --git a/src/theory/quantifiers/local_theory_ext.cpp b/src/theory/quantifiers/local_theory_ext.cpp
index 794032c87..ada28c084 100644
--- a/src/theory/quantifiers/local_theory_ext.cpp
+++ b/src/theory/quantifiers/local_theory_ext.cpp
@@ -1,13 +1,13 @@
/********************* */
-/*! \file quant_util.cpp
+/*! \file local_theory_ext.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of local theory ext utilities
**/
@@ -31,69 +31,69 @@ QuantifiersModule( qe ), d_wasInvoked( false ), d_needsCheck( false ){
}
/** add quantifier */
-bool LtePartialInst::addQuantifier( Node q ) {
- if( d_do_inst.find( q )!=d_do_inst.end() ){
- if( d_do_inst[q] ){
- d_lte_asserts.push_back( q );
- return true;
+void LtePartialInst::preRegisterQuantifier( Node q ) {
+ if( !q.getAttribute(LtePartialInstAttribute()) ){
+ if( d_do_inst.find( q )!=d_do_inst.end() ){
+ if( d_do_inst[q] ){
+ d_lte_asserts.push_back( q );
+ d_quantEngine->setOwner( q, this );
+ }
}else{
- return false;
- }
- }else{
- d_vars[q].clear();
- d_pat_var_order[q].clear();
- //check if this quantified formula is eligible for partial instantiation
- std::map< Node, bool > vars;
- for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
- vars[q[0][i]] = false;
- }
- getEligibleInstVars( q[1], vars );
-
- //instantiate only if we would force ground instances
- std::map< Node, int > var_order;
- bool doInst = true;
- for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
- if( vars[q[0][i]] ){
- d_vars[q].push_back( q[0][i] );
- var_order[q[0][i]] = i;
- }else{
- Trace("lte-partial-inst-debug") << "...do not consider, variable " << q[0][i] << " was not found in correct position in body." << std::endl;
- doInst = false;
- break;
+ d_vars[q].clear();
+ d_pat_var_order[q].clear();
+ //check if this quantified formula is eligible for partial instantiation
+ std::map< Node, bool > vars;
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+ vars[q[0][i]] = false;
}
- }
- if( doInst ){
- //also needs patterns
- if( q.getNumChildren()==3 && q[2].getNumChildren()==1 ){
- for( unsigned i=0; i<q[2][0].getNumChildren(); i++ ){
- Node pat = q[2][0][i];
- if( pat.getKind()==APPLY_UF ){
- for( unsigned j=0; j<pat.getNumChildren(); j++ ){
- if( !addVariableToPatternList( pat[j], d_pat_var_order[q], var_order ) ){
- doInst = false;
+ getEligibleInstVars( q[1], vars );
+
+ //instantiate only if we would force ground instances
+ std::map< Node, int > var_order;
+ bool doInst = true;
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+ if( vars[q[0][i]] ){
+ d_vars[q].push_back( q[0][i] );
+ var_order[q[0][i]] = i;
+ }else{
+ Trace("lte-partial-inst-debug") << "...do not consider, variable " << q[0][i] << " was not found in correct position in body." << std::endl;
+ doInst = false;
+ break;
+ }
+ }
+ if( doInst ){
+ //also needs patterns
+ if( q.getNumChildren()==3 && q[2].getNumChildren()==1 ){
+ for( unsigned i=0; i<q[2][0].getNumChildren(); i++ ){
+ Node pat = q[2][0][i];
+ if( pat.getKind()==APPLY_UF ){
+ for( unsigned j=0; j<pat.getNumChildren(); j++ ){
+ if( !addVariableToPatternList( pat[j], d_pat_var_order[q], var_order ) ){
+ doInst = false;
+ }
}
+ }else if( !addVariableToPatternList( pat, d_pat_var_order[q], var_order ) ){
+ doInst = false;
+ }
+ if( !doInst ){
+ Trace("lte-partial-inst-debug") << "...do not consider, cannot resolve pattern : " << pat << std::endl;
+ break;
}
- }else if( !addVariableToPatternList( pat, d_pat_var_order[q], var_order ) ){
- doInst = false;
- }
- if( !doInst ){
- Trace("lte-partial-inst-debug") << "...do not consider, cannot resolve pattern : " << pat << std::endl;
- break;
}
+ }else{
+ Trace("lte-partial-inst-debug") << "...do not consider (must have exactly one pattern)." << std::endl;
}
- }else{
- Trace("lte-partial-inst-debug") << "...do not consider (must have exactly one pattern)." << std::endl;
+ }
+
+
+ Trace("lte-partial-inst") << "LTE: ...will " << ( doInst ? "" : "not ") << "instantiate " << q << std::endl;
+ d_do_inst[q] = doInst;
+ if( doInst ){
+ d_lte_asserts.push_back( q );
+ d_needsCheck = true;
+ d_quantEngine->setOwner( q, this );
}
}
-
-
- Trace("lte-partial-inst") << "LTE: ...will " << ( doInst ? "" : "not ") << "instantiate " << q << std::endl;
- d_do_inst[q] = doInst;
- if( doInst ){
- d_lte_asserts.push_back( q );
- d_needsCheck = true;
- }
- return doInst;
}
}
@@ -188,7 +188,6 @@ void LtePartialInst::getInstantiations( std::vector< Node >& lemmas ) {
Assert( !conj.empty() );
lemmas.push_back( NodeManager::currentNM()->mkNode( OR, q.negate(), conj.size()==1 ? conj[0] : NodeManager::currentNM()->mkNode( AND, conj ) ) );
d_wasInvoked = true;
- d_quantEngine->getModel()->markQuantifierReduced( q );
}
}
}
diff --git a/src/theory/quantifiers/local_theory_ext.h b/src/theory/quantifiers/local_theory_ext.h
index 6e2ee34af..94abf3c90 100644
--- a/src/theory/quantifiers/local_theory_ext.h
+++ b/src/theory/quantifiers/local_theory_ext.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file local_theory_ext.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief local theory extensions util
**/
@@ -55,8 +55,8 @@ private:
bool addVariableToPatternList( Node v, std::vector< int >& pat_var_order, std::map< Node, int >& var_order );
public:
LtePartialInst( QuantifiersEngine * qe, context::Context* c );
- /** add quantifier : special form of registration */
- bool addQuantifier( Node q );
+ /** determine whether this quantified formula will be reduced */
+ void preRegisterQuantifier( Node q );
/** was invoked */
bool wasInvoked() { return d_wasInvoked; }
diff --git a/src/theory/quantifiers/macros.cpp b/src/theory/quantifiers/macros.cpp
index a5e3dada8..582599680 100644
--- a/src/theory/quantifiers/macros.cpp
+++ b/src/theory/quantifiers/macros.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file macros.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sort inference module
**
@@ -39,9 +39,15 @@ bool QuantifierMacros::simplify( std::vector< Node >& assertions, bool doRewrite
d_ground_macros = (r==0);
Trace("macros") << "Find macros, ground=" << d_ground_macros << "..." << std::endl;
//first, collect macro definitions
- for( int i=0; i<(int)assertions.size(); i++ ){
+ std::vector< Node > macro_assertions;
+ for( unsigned i=0; i<assertions.size(); i++ ){
Trace("macros-debug") << " process assertion " << assertions[i] << std::endl;
if( processAssertion( assertions[i] ) ){
+ PROOF(
+ if( std::find( macro_assertions.begin(), macro_assertions.end(), assertions[i] )==macro_assertions.end() ){
+ macro_assertions.push_back( assertions[i] );
+ }
+ );
//process this assertion again
i--;
}
@@ -56,7 +62,17 @@ bool QuantifierMacros::simplify( std::vector< Node >& assertions, bool doRewrite
if( curr!=assertions[i] ){
curr = Rewriter::rewrite( curr );
Trace("macros-rewrite") << "Rewrite " << assertions[i] << " to " << curr << std::endl;
- PROOF( ProofManager::currentPM()->addDependence(curr, assertions[i]); );
+ //for now, it is dependent upon all assertions involving macros, this is an over-approximation.
+ //a more fine-grained unsat core computation would require caching dependencies for each subterm of the formula,
+ // which is expensive.
+ PROOF(
+ ProofManager::currentPM()->addDependence(curr, assertions[i]);
+ for( unsigned j=0; j<macro_assertions.size(); j++ ){
+ if( macro_assertions[j]!=assertions[i] ){
+ ProofManager::currentPM()->addDependence(curr,macro_assertions[j]);
+ }
+ }
+ );
assertions[i] = curr;
retVal = true;
}
@@ -68,7 +84,7 @@ bool QuantifierMacros::simplify( std::vector< Node >& assertions, bool doRewrite
}
}
if( Trace.isOn("macros-warn") ){
- for( int i=0; i<(int)assertions.size(); i++ ){
+ for( unsigned i=0; i<assertions.size(); i++ ){
debugMacroDefinition( assertions[i], assertions[i] );
}
}
@@ -137,7 +153,7 @@ bool QuantifierMacros::isGroundUfTerm( Node f, Node n ) {
d_qe->getTermDatabase()->getVarContainsNode( f, icn, var );
Trace("macros-debug2") << "Get trigger variables for " << icn << std::endl;
std::vector< Node > trigger_var;
- inst::Trigger::getTriggerVariables( d_qe, icn, f, trigger_var );
+ inst::Trigger::getTriggerVariables( icn, f, trigger_var );
Trace("macros-debug2") << "Done." << std::endl;
//only if all variables are also trigger variables
return trigger_var.size()>=var.size();
@@ -145,18 +161,24 @@ bool QuantifierMacros::isGroundUfTerm( Node f, Node n ) {
bool QuantifierMacros::isBoundVarApplyUf( Node n ) {
Assert( n.getKind()==APPLY_UF );
- TypeNode tn = n.getOperator().getType();
+ TypeNode tno = n.getOperator().getType();
+ std::map< Node, bool > vars;
for( unsigned i=0; i<n.getNumChildren(); i++ ){
if( n[i].getKind()!=BOUND_VARIABLE ){
return false;
}
- if( n[i].getType()!=tn[i] ){
+ if( n[i].getType()!=tno[i] ){
return false;
}
- for( unsigned j=0; j<i; j++ ){
- if( n[j]==n[i] ){
- return false;
- }
+ if( !tno[i].isSort() && !tno[i].isReal() && ( !tno[i].isDatatype() || tno[i].isParametricDatatype() ) &&
+ !tno[i].isBitVector() && !tno[i].isString() && !tno[i].isFloatingPoint() ){
+ //only non-parametric types are supported
+ return false;
+ }
+ if( vars.find( n[i] )==vars.end() ){
+ vars[n[i]] = true;
+ }else{
+ return false;
}
}
return true;
@@ -388,13 +410,33 @@ Node QuantifierMacros::simplify( Node n ){
Node op = n.getOperator();
std::map< Node, Node >::iterator it = d_macro_defs.find( op );
if( it!=d_macro_defs.end() && !it->second.isNull() ){
- //do substitution if necessary
- ret = it->second;
- std::map< Node, std::vector< Node > >::iterator itb = d_macro_basis.find( op );
- if( itb!=d_macro_basis.end() ){
- ret = ret.substitute( itb->second.begin(), itb->second.end(), children.begin(), children.end() );
+ //only apply if children are subtypes of arguments
+ bool success = true;
+ std::vector< Node > cond;
+ TypeNode tno = op.getType();
+ for( unsigned i=0; i<children.size(); i++ ){
+ if( !TermDb::getEnsureTypeCondition( children[i], tno[i], cond ) ){
+ //if this does fail, we are incomplete, since we are eliminating quantified formula corresponding to op,
+ // and not ensuring it applies to n when its types are correct.
+ //however, this should never fail: we never process types for which we cannot constuct conditions that ensure correct types, e.g. (is-int t).
+ Assert( false );
+ success = false;
+ break;
+ }
+ }
+ if( success ){
+ //do substitution if necessary
+ ret = it->second;
+ std::map< Node, std::vector< Node > >::iterator itb = d_macro_basis.find( op );
+ if( itb!=d_macro_basis.end() ){
+ ret = ret.substitute( itb->second.begin(), itb->second.end(), children.begin(), children.end() );
+ }
+ if( !cond.empty() ){
+ Node cc = cond.size()==1 ? cond[0] : NodeManager::currentNM()->mkNode( kind::AND, cond );
+ ret = NodeManager::currentNM()->mkNode( kind::ITE, cc, ret, n );
+ }
+ retSet = true;
}
- retSet = true;
}
}
if( !retSet && childChanged ){
diff --git a/src/theory/quantifiers/macros.h b/src/theory/quantifiers/macros.h
index 06e2d652a..39ec2f0a1 100644
--- a/src/theory/quantifiers/macros.h
+++ b/src/theory/quantifiers/macros.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file macros.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Pre-process step for detecting quantifier macro definitions
**/
diff --git a/src/theory/quantifiers/model_builder.cpp b/src/theory/quantifiers/model_builder.cpp
index 95b674cca..3ae36b1d4 100644
--- a/src/theory/quantifiers/model_builder.cpp
+++ b/src/theory/quantifiers/model_builder.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file model_builder.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of model builder class
**/
@@ -50,14 +50,14 @@ bool QModelBuilder::optUseModel() {
void QModelBuilder::debugModel( FirstOrderModel* fm ){
//debug the model: cycle through all instantiations for all quantifiers, report ones that are not true
- if( Trace.isOn("quant-model-warn") ){
- Trace("quant-model-warn") << "Testing quantifier instantiations..." << std::endl;
+ if( Trace.isOn("quant-check-model") ){
+ Trace("quant-check-model") << "Testing quantifier instantiations..." << std::endl;
int tests = 0;
int bad = 0;
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
Node f = fm->getAssertedQuantifier( i );
std::vector< Node > vars;
- for( int j=0; j<(int)f[0].getNumChildren(); j++ ){
+ for( unsigned j=0; j<f[0].getNumChildren(); j++ ){
vars.push_back( f[0][j] );
}
RepSetIterator riter( d_qe, &(fm->d_rep_set) );
@@ -65,26 +65,26 @@ void QModelBuilder::debugModel( FirstOrderModel* fm ){
while( !riter.isFinished() ){
tests++;
std::vector< Node > terms;
- for( int i=0; i<riter.getNumTerms(); i++ ){
- terms.push_back( riter.getTerm( i ) );
+ for( int k=0; k<riter.getNumTerms(); k++ ){
+ terms.push_back( riter.getTerm( k ) );
}
Node n = d_qe->getInstantiation( f, vars, terms );
Node val = fm->getValue( n );
if( val!=fm->d_true ){
- Trace("quant-model-warn") << "******* Instantiation " << n << " for " << std::endl;
- Trace("quant-model-warn") << " " << f << std::endl;
- Trace("quant-model-warn") << " Evaluates to " << val << std::endl;
+ Trace("quant-check-model") << "******* Instantiation " << n << " for " << std::endl;
+ Trace("quant-check-model") << " " << f << std::endl;
+ Trace("quant-check-model") << " Evaluates to " << val << std::endl;
bad++;
}
riter.increment();
}
- Trace("quant-model-warn") << "Tested " << tests << " instantiations";
+ Trace("quant-check-model") << "Tested " << tests << " instantiations";
if( bad>0 ){
- Trace("quant-model-warn") << ", " << bad << " failed" << std::endl;
+ Trace("quant-check-model") << ", " << bad << " failed" << std::endl;
}
- Trace("quant-model-warn") << "." << std::endl;
+ Trace("quant-check-model") << "." << std::endl;
}else{
- Trace("quant-model-warn") << "Warning: Could not test quantifier " << f << std::endl;
+ Trace("quant-check-model") << "Warning: Could not test quantifier " << f << std::endl;
}
}
}
@@ -149,17 +149,21 @@ void QModelBuilderIG::processBuildModel( TheoryModel* m, bool fullModel ) {
if( optUseModel() ){
Trace("model-engine-debug") << "Initializing " << fm->getNumAssertedQuantifiers() << " quantifiers..." << std::endl;
//check if any quantifiers are un-initialized
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
Node f = fm->getAssertedQuantifier( i );
if( isQuantifierActive( f ) ){
int lems = initializeQuantifier( f, f );
d_statistics.d_init_inst_gen_lemmas += lems;
d_addedLemmas += lems;
+ if( d_qe->inConflict() ){
+ break;
+ }
}
}
if( d_addedLemmas>0 ){
Trace("model-engine") << "Initialize, Added Lemmas = " << d_addedLemmas << std::endl;
}else{
+ Assert( !d_qe->inConflict() );
//initialize model
fm->initialize();
//analyze the functions
@@ -169,7 +173,7 @@ void QModelBuilderIG::processBuildModel( TheoryModel* m, bool fullModel ) {
Trace("model-engine-debug") << "Analyzing quantifiers..." << std::endl;
d_quant_sat.clear();
d_uf_prefs.clear();
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
Node f = fm->getAssertedQuantifier( i );
if( isQuantifierActive( f ) ){
analyzeQuantifier( fm, f );
@@ -186,7 +190,7 @@ void QModelBuilderIG::processBuildModel( TheoryModel* m, bool fullModel ) {
d_numQuantNoSelForm = 0;
//now, see if we know that any exceptions via InstGen exist
Trace("model-engine-debug") << "Perform InstGen techniques for quantifiers..." << std::endl;
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
Node f = fm->getAssertedQuantifier( i );
if( isQuantifierActive( f ) ){
int lems = doInstGen( fm, f );
@@ -202,7 +206,7 @@ void QModelBuilderIG::processBuildModel( TheoryModel* m, bool fullModel ) {
}else{
d_numQuantNoSelForm++;
}
- if( options::fmfInstGenOneQuantPerRound() && lems>0 ){
+ if( d_qe->inConflict() || ( options::fmfInstGenOneQuantPerRound() && lems>0 ) ){
break;
}
}else if( d_quant_sat.find( f )!=d_quant_sat.end() ){
@@ -276,7 +280,7 @@ int QModelBuilderIG::initializeQuantifier( Node f, Node fp ){
//try to add it
Trace("inst-fmf-init") << "Init: try to add match " << d_quant_basis_match[f] << std::endl;
//add model basis instantiation
- if( d_qe->addInstantiation( fp, d_quant_basis_match[f], false ) ){
+ if( d_qe->addInstantiation( fp, d_quant_basis_match[f] ) ){
d_quant_basis_match_added[f] = true;
return 1;
}else{
@@ -426,8 +430,11 @@ bool QModelBuilderIG::doExhaustiveInstantiation( FirstOrderModel * fm, Node f, i
}
Debug("fmf-model-eval") << "* Add instantiation " << m << std::endl;
//add as instantiation
- if( d_qe->addInstantiation( f, m ) ){
+ if( d_qe->addInstantiation( f, m, true ) ){
d_addedLemmas++;
+ if( d_qe->inConflict() ){
+ break;
+ }
//if the instantiation is show to be false, and we wish to skip multiple instantiations at once
if( eval==-1 ){
riter.increment2( depIndex );
@@ -660,7 +667,7 @@ int QModelBuilderDefault::doInstGen( FirstOrderModel* fm, Node f ){
//if applicable, try to add exceptions here
if( !tr_terms.empty() ){
//make a trigger for these terms, add instantiations
- inst::Trigger* tr = inst::Trigger::mkTrigger( d_qe, f, tr_terms, 0, true, inst::Trigger::TR_MAKE_NEW, options::smartTriggers() );
+ inst::Trigger* tr = inst::Trigger::mkTrigger( d_qe, f, tr_terms, 0, true, inst::Trigger::TR_MAKE_NEW );
//Notice() << "Trigger = " << (*tr) << std::endl;
tr->resetInstantiationRound();
tr->reset( Node::null() );
diff --git a/src/theory/quantifiers/model_builder.h b/src/theory/quantifiers/model_builder.h
index b45aa0ff0..906673903 100644
--- a/src/theory/quantifiers/model_builder.h
+++ b/src/theory/quantifiers/model_builder.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file model_builder.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Model Builder class
**/
diff --git a/src/theory/quantifiers/model_engine.cpp b/src/theory/quantifiers/model_engine.cpp
index 4b173c833..0bbca88eb 100644
--- a/src/theory/quantifiers/model_engine.cpp
+++ b/src/theory/quantifiers/model_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file model_engine.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of model engine class
**/
@@ -62,6 +62,7 @@ void ModelEngine::reset_round( Theory::Effort e ) {
void ModelEngine::check( Theory::Effort e, unsigned quant_e ){
if( quant_e==QuantifiersEngine::QEFFORT_MODEL ){
+ Assert( !d_quantEngine->inConflict() );
int addedLemmas = 0;
FirstOrderModel* fm = d_quantEngine->getModel();
@@ -82,8 +83,10 @@ void ModelEngine::check( Theory::Effort e, unsigned quant_e ){
Trace("model-engine-debug") << "Check model..." << std::endl;
d_incomplete_check = false;
//print debug
- Trace("fmf-model-complete") << std::endl;
- debugPrint("fmf-model-complete");
+ if( Trace.isOn("fmf-model-complete") ){
+ Trace("fmf-model-complete") << std::endl;
+ debugPrint("fmf-model-complete");
+ }
//successfully built an acceptable model, now check it
addedLemmas += checkModel();
}else{
@@ -98,10 +101,10 @@ void ModelEngine::check( Theory::Effort e, unsigned quant_e ){
if( addedLemmas==0 ){
Trace("model-engine-debug") << "No lemmas added, incomplete = " << d_incomplete_check << std::endl;
//CVC4 will answer SAT or unknown
- Trace("fmf-consistent") << std::endl;
- debugPrint("fmf-consistent");
- }else{
- //otherwise, the search will continue
+ if( Trace.isOn("fmf-consistent") ){
+ Trace("fmf-consistent") << std::endl;
+ debugPrint("fmf-consistent");
+ }
}
}
}
@@ -178,49 +181,51 @@ int ModelEngine::checkModel(){
d_addedLemmas = 0;
d_totalLemmas = 0;
//for statistics
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
- Node f = fm->getAssertedQuantifier( i );
- int totalInst = 1;
- for( size_t i=0; i<f[0].getNumChildren(); i++ ){
- TypeNode tn = f[0][i].getType();
- if( fm->d_rep_set.hasType( tn ) ){
- totalInst = totalInst * (int)fm->d_rep_set.d_type_reps[ tn ].size();
+ if( Trace.isOn("model-engine") ){
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ Node f = fm->getAssertedQuantifier( i );
+ int totalInst = 1;
+ for( unsigned j=0; j<f[0].getNumChildren(); j++ ){
+ TypeNode tn = f[0][j].getType();
+ if( fm->d_rep_set.hasType( tn ) ){
+ totalInst = totalInst * (int)fm->d_rep_set.d_type_reps[ tn ].size();
+ }
}
+ d_totalLemmas += totalInst;
}
- d_totalLemmas += totalInst;
}
Trace("model-engine-debug") << "Do exhaustive instantiation..." << std::endl;
// FMC uses two sub-effort levels
int e_max = options::mbqiMode()==MBQI_FMC || options::mbqiMode()==MBQI_FMC_INTERVAL ? 2 : ( options::mbqiMode()==MBQI_TRUST ? 0 : 1 );
for( int e=0; e<e_max; e++) {
- if (d_addedLemmas==0) {
- for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
- Node f = fm->getAssertedQuantifier( i );
- Trace("fmf-exh-inst") << "-> Exhaustive instantiate " << f << ", effort = " << e << "..." << std::endl;
- //determine if we should check this quantifier
- if( considerQuantifiedFormula( f ) ){
- exhaustiveInstantiate( f, e );
- if( Trace.isOn("model-engine-warn") ){
- if( d_addedLemmas>10000 ){
- Debug("fmf-exit") << std::endl;
- debugPrint("fmf-exit");
- exit( 0 );
- }
- }
- if( optOneQuantPerRound() && d_addedLemmas>0 ){
- break;
- }
- }else{
- Trace("fmf-exh-inst") << "-> Inactive : " << f << std::endl;
+ for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
+ Node f = fm->getAssertedQuantifier( i, true );
+ Trace("fmf-exh-inst") << "-> Exhaustive instantiate " << f << ", effort = " << e << "..." << std::endl;
+ //determine if we should check this quantifier
+ if( considerQuantifiedFormula( f ) ){
+ exhaustiveInstantiate( f, e );
+ if( d_quantEngine->inConflict() || ( optOneQuantPerRound() && d_addedLemmas>0 ) ){
+ break;
}
+ }else{
+ Trace("fmf-exh-inst") << "-> Inactive : " << f << std::endl;
}
}
+ if( d_addedLemmas>0 ){
+ break;
+ }else{
+ Assert( !d_quantEngine->inConflict() );
+ }
}
//print debug information
- Trace("model-engine") << "Added Lemmas = " << d_addedLemmas << " / " << d_triedLemmas << " / ";
- Trace("model-engine") << d_totalLemmas << std::endl;
+ if( d_quantEngine->inConflict() ){
+ Trace("model-engine") << "Conflict = " << d_quantEngine->getNumLemmasWaiting() << " / " << d_quantEngine->getNumLemmasAddedThisRound() << std::endl;
+ }else{
+ Trace("model-engine") << "Added Lemmas = " << d_addedLemmas << " / " << d_triedLemmas << " / ";
+ Trace("model-engine") << d_totalLemmas << std::endl;
+ }
return d_addedLemmas;
}
@@ -266,15 +271,17 @@ void ModelEngine::exhaustiveInstantiate( Node f, int effort ){
d_incomplete_check = d_incomplete_check || mb->d_incomplete_check;
d_statistics.d_mbqi_inst_lemmas += mb->d_addedLemmas;
}else{
- Trace("fmf-exh-inst-debug") << " Instantiation Constants: ";
- for( size_t i=0; i<f[0].getNumChildren(); i++ ){
- Trace("fmf-exh-inst-debug") << d_quantEngine->getTermDatabase()->getInstantiationConstant( f, i ) << " ";
+ if( Trace.isOn("fmf-exh-inst-debug") ){
+ Trace("fmf-exh-inst-debug") << " Instantiation Constants: ";
+ for( size_t i=0; i<f[0].getNumChildren(); i++ ){
+ Trace("fmf-exh-inst-debug") << d_quantEngine->getTermDatabase()->getInstantiationConstant( f, i ) << " ";
+ }
+ Trace("fmf-exh-inst-debug") << std::endl;
}
- Trace("fmf-exh-inst-debug") << std::endl;
//create a rep set iterator and iterate over the (relevant) domain of the quantifier
RepSetIterator riter( d_quantEngine, &(d_quantEngine->getModel()->d_rep_set) );
if( riter.setQuantifier( f ) ){
- Trace("fmf-exh-inst") << "...exhaustive instantiation incomplete=" << riter.d_incomplete << "..." << std::endl;
+ Trace("fmf-exh-inst") << "...exhaustive instantiation set, incomplete=" << riter.d_incomplete << "..." << std::endl;
if( !riter.d_incomplete ){
int triedLemmas = 0;
int addedLemmas = 0;
@@ -287,8 +294,11 @@ void ModelEngine::exhaustiveInstantiate( Node f, int effort ){
Debug("fmf-model-eval") << "* Add instantiation " << m << std::endl;
triedLemmas++;
//add as instantiation
- if( d_quantEngine->addInstantiation( f, m ) ){
+ if( d_quantEngine->addInstantiation( f, m, true ) ){
addedLemmas++;
+ if( d_quantEngine->inConflict() ){
+ break;
+ }
}else{
Debug("fmf-model-eval") << "* Failed Add instantiation " << m << std::endl;
}
@@ -299,6 +309,7 @@ void ModelEngine::exhaustiveInstantiate( Node f, int effort ){
d_statistics.d_exh_inst_lemmas += addedLemmas;
}
}else{
+ Trace("fmf-exh-inst") << "...exhaustive instantiation failed to set, incomplete=" << riter.d_incomplete << "..." << std::endl;
Assert( riter.d_incomplete );
}
//if the iterator is incomplete, we will return unknown instead of sat if no instantiations are added this round
@@ -308,15 +319,15 @@ void ModelEngine::exhaustiveInstantiate( Node f, int effort ){
void ModelEngine::debugPrint( const char* c ){
Trace( c ) << "Quantifiers: " << std::endl;
- for( int i=0; i<(int)d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
- Node f = d_quantEngine->getModel()->getAssertedQuantifier( i );
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
Trace( c ) << " ";
- if( !d_quantEngine->getModelBuilder()->isQuantifierActive( f ) ){
+ if( !d_quantEngine->getModelBuilder()->isQuantifierActive( q ) ){
Trace( c ) << "*Inactive* ";
}else{
Trace( c ) << " ";
}
- Trace( c ) << f << std::endl;
+ Trace( c ) << q << std::endl;
}
//d_quantEngine->getModel()->debugPrint( c );
}
diff --git a/src/theory/quantifiers/model_engine.h b/src/theory/quantifiers/model_engine.h
index 1fb4255b2..12f18aa08 100644
--- a/src/theory/quantifiers/model_engine.h
+++ b/src/theory/quantifiers/model_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file model_engine.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Model Engine class
**/
diff --git a/src/theory/quantifiers/quant_conflict_find.cpp b/src/theory/quantifiers/quant_conflict_find.cpp
index a890276f7..ca87a607d 100644
--- a/src/theory/quantifiers/quant_conflict_find.cpp
+++ b/src/theory/quantifiers/quant_conflict_find.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quant_conflict_find.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief quant conflict find class
**
@@ -22,19 +22,32 @@
#include "theory/quantifiers/quant_util.h"
#include "theory/quantifiers/term_database.h"
#include "theory/quantifiers/trigger.h"
+#include "theory/quantifiers/first_order_model.h"
#include "theory/theory_engine.h"
-using namespace CVC4;
using namespace CVC4::kind;
-using namespace CVC4::theory;
-using namespace CVC4::theory::quantifiers;
using namespace std;
namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+QuantInfo::QuantInfo()
+ : d_mg( NULL )
+{}
+
+QuantInfo::~QuantInfo() {
+ delete d_mg;
+ for(std::map< int, MatchGen * >::iterator i = d_var_mg.begin(),
+ iend=d_var_mg.end(); i != iend; ++i) {
+ MatchGen* currentMatchGenerator = (*i).second;
+ delete currentMatchGenerator;
+ }
+ d_var_mg.clear();
+}
-void QuantInfo::initialize( Node q, Node qn ) {
+void QuantInfo::initialize( QuantConflictFind * p, Node q, Node qn ) {
d_q = q;
for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
d_match.push_back( TNode::null() );
@@ -95,6 +108,59 @@ void QuantInfo::initialize( Node q, Node qn ) {
Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;
}
Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;
+
+ if( d_mg->isValid() ){
+ //optimization : record variable argument positions for terms that must be matched
+ std::vector< TNode > vars;
+ //TODO: revisit this, makes QCF faster, but misses conflicts due to caring about paths that may not be relevant (starExec jobs 14136/14137)
+ //if( options::qcfSkipRd() ){
+ // for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){
+ // vars.push_back( d_vars[j] );
+ // }
+ //}
+ //get all variables that are always relevant
+ std::map< TNode, bool > visited;
+ getPropagateVars( vars, q[1], false, visited );
+ for( unsigned j=0; j<vars.size(); j++ ){
+ Node v = vars[j];
+ TNode f = p->getTermDatabase()->getMatchOperator( v );
+ if( !f.isNull() ){
+ Trace("qcf-opt") << "Record variable argument positions in " << v << ", op=" << f << "..." << std::endl;
+ for( unsigned k=0; k<v.getNumChildren(); k++ ){
+ Node n = v[k];
+ std::map< TNode, int >::iterator itv = d_var_num.find( n );
+ if( itv!=d_var_num.end() ){
+ Trace("qcf-opt") << " arg " << k << " is var #" << itv->second << std::endl;
+ if( std::find( d_var_rel_dom[itv->second][f].begin(), d_var_rel_dom[itv->second][f].end(), k )==d_var_rel_dom[itv->second][f].end() ){
+ d_var_rel_dom[itv->second][f].push_back( k );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void QuantInfo::getPropagateVars( std::vector< TNode >& vars, TNode n, bool pol, std::map< TNode, bool >& visited ){
+ std::map< TNode, bool >::iterator itv = visited.find( n );
+ if( itv==visited.end() ){
+ visited[n] = true;
+ bool rec = true;
+ bool newPol = pol;
+ if( d_var_num.find( n )!=d_var_num.end() ){
+ Assert( std::find( vars.begin(), vars.end(), n )==vars.end() );
+ vars.push_back( n );
+ }else if( MatchGen::isHandledBoolConnective( n ) ){
+ Assert( n.getKind()!=IMPLIES );
+ QuantPhaseReq::getEntailPolarity( n, 0, true, pol, rec, newPol );
+ }
+ Trace("qcf-opt-debug") << "getPropagateVars " << n << ", pol = " << pol << ", rec = " << rec << std::endl;
+ if( rec ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ getPropagateVars( vars, n[i], pol, visited );
+ }
+ }
+ }
}
void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {
@@ -315,7 +381,7 @@ int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, boo
return 1;
}else{
//std::map< int, TNode >::iterator itm = d_match.find( v );
-
+ bool isGroundRep = false;
if( vn!=-1 ){
Debug("qcf-match-debug") << " ...Variable bound to variable" << std::endl;
//std::map< int, TNode >::iterator itmn = d_match.find( vn );
@@ -361,13 +427,14 @@ int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, boo
}else{
Debug("qcf-match-debug") << " ...Variable bound to ground" << std::endl;
if( d_match[v].isNull() ){
+ //isGroundRep = true; ??
}else{
//compare ground values
Debug("qcf-match-debug") << " -> Ground value, compare " << d_match[v] << " "<< n << std::endl;
return p->areMatchEqual( d_match[v], n ) ? 0 : -1;
}
}
- if( setMatch( p, v, n ) ){
+ if( setMatch( p, v, n, isGroundRep ) ){
Debug("qcf-match-debug") << " -> success" << std::endl;
return 1;
}else{
@@ -433,8 +500,23 @@ bool QuantInfo::isConstrainedVar( int v ) {
}
}
-bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {
+bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n, bool isGroundRep ) {
if( getCurrentCanBeEqual( p, v, n ) ){
+ if( isGroundRep ){
+ //fail if n does not exist in the relevant domain of each of the argument positions
+ std::map< int, std::map< TNode, std::vector< unsigned > > >::iterator it = d_var_rel_dom.find( v );
+ if( it!=d_var_rel_dom.end() ){
+ for( std::map< TNode, std::vector< unsigned > >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+ for( unsigned j=0; j<it2->second.size(); j++ ){
+ Debug("qcf-match-debug2") << n << " in relevant domain " << it2->first << "." << it2->second[j] << "?" << std::endl;
+ if( !p->getTermDatabase()->inRelevantDomain( it2->first, it2->second[j], n ) ){
+ Debug("qcf-match-debug") << " -> fail, since " << n << " is not in relevant domain of " << it2->first << "." << it2->second[j] << std::endl;
+ return false;
+ }
+ }
+ }
+ }
+ }
Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " << d_curr_var_deq[v].size() << " disequalities" << std::endl;
d_match[v] = n;
return true;
@@ -477,7 +559,22 @@ bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {
Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;
return false;
}else if( rew!=p->d_true ){
- //if checking for conflicts, we must be sure that the constraint is entailed
+ //if checking for conflicts, we must be sure that the (negation of) constraint is (not) entailed
+ if( !chEnt ){
+ rew = Rewriter::rewrite( rew.negate() );
+ }
+ //check if it is entailed
+ Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;
+ std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );
+ ++(p->d_statistics.d_entailment_checks);
+ Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;
+ if( !et.first ){
+ Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;
+ return !chEnt;
+ }else{
+ return chEnt;
+ }
+/*
if( chEnt ){
//check if it is entailed
Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;
@@ -494,6 +591,7 @@ bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {
Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;
return true;
}
+*/
}else{
Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;
return true;
@@ -538,7 +636,7 @@ bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assign
if( !z.isNull() ){
Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;
assigned.push_back( vn );
- if( !setMatch( p, vn, z ) ){
+ if( !setMatch( p, vn, z, false ) ){
success = false;
break;
}
@@ -580,7 +678,7 @@ bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assign
if( !sum.isNull() ){
assigned.push_back( slv_v );
Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;
- if( !setMatch( p, slv_v, sum ) ){
+ if( !setMatch( p, slv_v, sum, false ) ){
success = false;
}
p->d_tempCache.push_back( sum );
@@ -666,7 +764,7 @@ bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assign
int currIndex = d_una_eqc_count[d_una_index];
d_una_eqc_count[d_una_index]++;
Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;
- if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){
+ if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex], true ) ){
d_match_term[d_unassigned[d_una_index]] = TNode::null();
Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;
d_una_index++;
@@ -801,6 +899,7 @@ MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar )
if( isVar ){
Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );
if( n.getKind()==ITE ){
+ /*
d_type = typ_ite_var;
d_type_not = false;
d_n = n;
@@ -817,15 +916,16 @@ MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar )
}
}
}else{
+*/
d_type = typ_invalid;
- }
+ //}
}else{
d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;
d_qni_var_num[0] = qi->getVarNum( n );
d_qni_size++;
d_type_not = false;
d_n = n;
- //Node f = getOperator( n );
+ //Node f = getMatchOperator( n );
for( unsigned j=0; j<d_n.getNumChildren(); j++ ){
Node nn = d_n[j];
Trace("qcf-qregister-debug") << " " << d_qni_size;
@@ -1031,16 +1131,27 @@ void MatchGen::reset_round( QuantConflictFind * p ) {
d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );
}
if( d_type==typ_ground ){
- int e = p->evaluate( d_n );
- if( e==1 ){
- d_ground_eval[0] = p->d_true;
- }else if( e==-1 ){
- d_ground_eval[0] = p->d_false;
+ //int e = p->evaluate( d_n );
+ //if( e==1 ){
+ // d_ground_eval[0] = p->d_true;
+ //}else if( e==-1 ){
+ // d_ground_eval[0] = p->d_false;
+ //}
+ //modified
+ for( unsigned i=0; i<2; i++ ){
+ if( p->getTermDatabase()->isEntailed( d_n, i==0 ) ){
+ d_ground_eval[0] = i==0 ? p->d_true : p->d_false;
+ }
}
}else if( d_type==typ_eq ){
for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
if( !d_n[i].hasBoundVar() ){
- d_ground_eval[i] = p->evaluateTerm( d_n[i] );
+ TNode t = p->getTermDatabase()->getEntailedTerm( d_n[i] );
+ if( t.isNull() ){
+ d_ground_eval[i] = d_n[i];
+ }else{
+ d_ground_eval[i] = t;
+ }
}
}
}
@@ -1073,14 +1184,18 @@ void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {
int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );
if( vn==-1 ){
//evaluate the value, see if it is compatible
- int e = p->evaluate( n );
- if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){
+ //int e = p->evaluate( n );
+ //if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){
+ // d_child_counter = 0;
+ //}
+ //modified
+ if( p->getTermDatabase()->isEntailed( n, d_tgt ) ){
d_child_counter = 0;
}
}else{
//unassigned, set match to true/false
d_qni_bound[0] = vn;
- qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );
+ qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false, false );
d_child_counter = 0;
}
if( d_child_counter==0 ){
@@ -1088,7 +1203,7 @@ void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {
}
}else if( d_type==typ_var ){
Assert( isHandledUfTerm( d_n ) );
- Node f = getOperator( p, d_n );
+ Node f = getMatchOperator( p, d_n );
Debug("qcf-match-debug") << " reset: Var will match operators of " << f << std::endl;
TermArgTrie * qni = p->getTermDatabase()->getTermArgTrie( Node::null(), f );
if( qni!=NULL ){
@@ -1242,12 +1357,12 @@ bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {
Debug("qcf-match-debug") << "..." << std::endl;
while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){
- std::map< int, MatchGen * >::iterator itm;
+ QuantInfo::VarMgMap::const_iterator itm;
if( !doFail ){
Debug("qcf-match-debug") << " check variable " << d_binding_it->second << std::endl;
- itm = qi->d_var_mg.find( d_binding_it->second );
+ itm = qi->var_mg_find( d_binding_it->second );
}
- if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){
+ if( doFail || ( d_binding_it->first!=0 && itm != qi->var_mg_end() ) ){
Debug("qcf-match-debug") << " we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;
if( doReset ){
itm->second->reset( p, true, qi );
@@ -1261,7 +1376,9 @@ bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {
--d_binding_it;
Debug("qcf-match-debug") << " decrement..." << std::endl;
}
- }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );
+ }while( success &&
+ ( d_binding_it->first==0 ||
+ (!qi->containsVarMg(d_binding_it->second))));
doReset = false;
doFail = false;
}else{
@@ -1318,17 +1435,6 @@ bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {
d_qni_bound_cons.clear();
}
}
- /*
- if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){
- d_matched_basis = true;
- Node f = getOperator( d_n );
- TNode mbo = p->getTermDatabase()->getModelBasisOpTerm( f );
- if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){
- success = true;
- d_qni_bound[0] = d_qni_var_num[0];
- }
- }
- */
}
Debug("qcf-match") << " ...finished matching for " << d_n << ", success = " << success << std::endl;
d_wasSet = success;
@@ -1548,7 +1654,7 @@ bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {
if( it != d_qn[index]->d_data.end() ) {
d_qni.push_back( it );
//set the match
- if( it->first.getType().isComparableTo( qi->d_var_types[repVar] ) && qi->setMatch( p, d_qni_bound[index], it->first ) ){
+ if( it->first.getType().isComparableTo( qi->d_var_types[repVar] ) && qi->setMatch( p, d_qni_bound[index], it->first, true ) ){
Debug("qcf-match-debug") << " Binding variable" << std::endl;
if( d_qn.size()<d_qni_size ){
d_qn.push_back( &it->second );
@@ -1593,7 +1699,7 @@ bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {
d_qni[index]++;
if( d_qni[index]!=d_qn[index]->d_data.end() ){
success = true;
- if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){
+ if( qi->setMatch( p, itb->second, d_qni[index]->first, true ) ){
Debug("qcf-match-debug") << " Bind next variable" << std::endl;
if( d_qn.size()<d_qni_size ){
d_qn.push_back( &d_qni[index]->second );
@@ -1679,12 +1785,14 @@ bool MatchGen::isHandledBoolConnective( TNode n ) {
bool MatchGen::isHandledUfTerm( TNode n ) {
//return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||
// n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;
+ //TODO : treat APPLY_TESTER as a T-constraint instead of matching (currently leads to overabundance of instantiations)
+ //return inst::Trigger::isAtomicTriggerKind( n.getKind() ) && ( !options::qcfTConstraint() || n.getKind()!=APPLY_TESTER );
return inst::Trigger::isAtomicTriggerKind( n.getKind() );
}
-Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {
+Node MatchGen::getMatchOperator( QuantConflictFind * p, Node n ) {
if( isHandledUfTerm( n ) ){
- return p->getTermDatabase()->getOperator( n );
+ return p->getTermDatabase()->getMatchOperator( n );
}else{
return Node::null();
}
@@ -1707,8 +1815,7 @@ bool MatchGen::isHandled( TNode n ) {
QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :
QuantifiersModule( qe ),
-d_conflict( c, false ),
-d_qassert( c ) {
+d_conflict( c, false ) {
d_fid_count = 0;
d_true = NodeManager::currentNM()->mkConst<bool>(true);
d_false = NodeManager::currentNM()->mkConst<bool>(false);
@@ -1733,7 +1840,7 @@ void QuantConflictFind::registerQuantifier( Node q ) {
Trace("qcf-qregister") << " : " << q << std::endl;
//make QcfNode structure
Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;
- d_qinfo[q].initialize( q, q[1] );
+ d_qinfo[q].initialize( this, q, q[1] );
//debug print
Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;
@@ -1748,96 +1855,16 @@ void QuantConflictFind::registerQuantifier( Node q ) {
Trace("qcf-qregister") << std::endl;
}
}
-
+
Trace("qcf-qregister") << "Done registering quantifier." << std::endl;
}
}
-int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {
- int ret = 0;
- if( n.getKind()==EQUAL ){
- Node n1 = evaluateTerm( n[0] );
- Node n2 = evaluateTerm( n[1] );
- Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;
- if( areEqual( n1, n2 ) ){
- ret = 1;
- }else if( areDisequal( n1, n2 ) ){
- ret = -1;
- }
- //else if( d_effort>QuantConflictFind::effort_conflict ){
- // ret = -1;
- //}
- }else if( MatchGen::isHandledUfTerm( n ) ){ //predicate
- Node nn = evaluateTerm( n );
- Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;
- if( areEqual( nn, d_true ) ){
- ret = 1;
- }else if( areEqual( nn, d_false ) ){
- ret = -1;
- }
- //else if( d_effort>QuantConflictFind::effort_conflict ){
- // ret = -1;
- //}
- }else if( n.getKind()==NOT ){
- return -evaluate( n[0] );
- }else if( n.getKind()==ITE ){
- int cev1 = evaluate( n[0] );
- int cevc[2] = { 0, 0 };
- for( unsigned i=0; i<2; i++ ){
- if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){
- cevc[i] = evaluate( n[i+1] );
- if( cev1!=0 ){
- ret = cevc[i];
- break;
- }else if( cevc[i]==0 ){
- break;
- }
- }
- }
- if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){
- ret = cevc[0];
- }
- }else if( n.getKind()==IFF ){
- int cev1 = evaluate( n[0] );
- if( cev1!=0 ){
- int cev2 = evaluate( n[1] );
- if( cev2!=0 ){
- ret = cev1==cev2 ? 1 : -1;
- }
- }
-
- }else{
- int ssval = 0;
- if( n.getKind()==OR ){
- ssval = 1;
- }else if( n.getKind()==AND ){
- ssval = -1;
- }
- bool isUnk = false;
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- int cev = evaluate( n[i] );
- if( cev==ssval ){
- ret = ssval;
- break;
- }else if( cev==0 ){
- isUnk = true;
- }
- }
- if( ret==0 && !isUnk ){
- ret = -ssval;
- }
- }
- Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;
- return ret;
-}
-
short QuantConflictFind::getMaxQcfEffort() {
if( options::qcfMode()==QCF_CONFLICT_ONLY ){
return effort_conflict;
- }else if( options::qcfMode()==QCF_PROP_EQ ){
+ }else if( options::qcfMode()==QCF_PROP_EQ || options::qcfMode()==QCF_PARTIAL ){
return effort_prop_eq;
- }else if( options::qcfMode()==QCF_MC ){
- return effort_mc;
}else{
return 0;
}
@@ -1862,48 +1889,13 @@ bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {
//-------------------------------------------------- handling assertions / eqc
void QuantConflictFind::assertNode( Node q ) {
+ /*
if( d_quantEngine->hasOwnership( q, this ) ){
Trace("qcf-proc") << "QCF : assertQuantifier : ";
debugPrintQuant("qcf-proc", q);
Trace("qcf-proc") << std::endl;
- d_qassert.push_back( q );
- //set the eqRegistries that this depends on to true
- //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){
- // it->first->d_active.set( true );
- //}
}
-}
-
-Node QuantConflictFind::evaluateTerm( Node n ) {
- if( MatchGen::isHandledUfTerm( n ) ){
- Node f = MatchGen::getOperator( this, n );
- Node nn;
- if( getEqualityEngine()->hasTerm( n ) ){
- nn = getTermDatabase()->existsTerm( f, n );
- }else{
- std::vector< TNode > args;
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- Node c = evaluateTerm( n[i] );
- args.push_back( c );
- }
- nn = getTermDatabase()->d_func_map_trie[f].existsTerm( args );
- }
- if( !nn.isNull() ){
- Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n ) << std::endl;
- return getRepresentative( nn );
- }else{
- Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n ) << std::endl;
- return n;
- }
- }else if( n.getKind()==ITE ){
- int v = evaluate( n[0], false, false );
- if( v==1 ){
- return evaluateTerm( n[1] );
- }else if( v==-1 ){
- return evaluateTerm( n[2] );
- }
- }
- return getRepresentative( n );
+ */
}
/** new node */
@@ -1965,28 +1957,12 @@ void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
//determine order for quantified formulas
std::vector< Node > qorder;
- std::map< Node, bool > qassert;
- //mark which are asserted
- for( unsigned i=0; i<d_qassert.size(); i++ ){
- qassert[d_qassert[i]] = true;
- }
- //add which ones are specified in the order
- for( unsigned i=0; i<d_quant_order.size(); i++ ){
- Node n = d_quant_order[i];
- if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){
- qorder.push_back( n );
- }
- }
- d_quant_order.clear();
- d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );
- //add remaining
- for( unsigned i=0; i<d_qassert.size(); i++ ){
- Node n = d_qassert[i];
- if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){
- qorder.push_back( n );
+ for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ Node q = d_quantEngine->getModel()->getAssertedQuantifier( i, true );
+ if( d_quantEngine->hasOwnership( q, this ) ){
+ qorder.push_back( q );
}
}
-
if( Trace.isOn("qcf-debug") ){
Trace("qcf-debug") << std::endl;
debugPrint("qcf-debug");
@@ -2002,7 +1978,7 @@ void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
QuantInfo * qi = &d_qinfo[q];
Assert( d_qinfo.find( q )!=d_qinfo.end() );
- if( qi->d_mg->isValid() ){
+ if( qi->matchGeneratorIsValid() ){
Trace("qcf-check") << "Check quantified formula ";
debugPrintQuant("qcf-check", q);
Trace("qcf-check") << " : " << q << "..." << std::endl;
@@ -2011,7 +1987,7 @@ void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
qi->reset_round( this );
//try to make a matches making the body false
Trace("qcf-check-debug") << "Get next match..." << std::endl;
- while( qi->d_mg->getNextMatch( this, qi ) ){
+ while( qi->getNextMatch( this ) ){
Trace("qcf-inst") << "*** Produced match at effort " << e << " : " << std::endl;
qi->debugPrintMatch("qcf-inst");
Trace("qcf-inst") << std::endl;
@@ -2021,22 +1997,21 @@ void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
std::vector< Node > terms;
qi->getMatch( terms );
if( !qi->isTConstraintSpurious( this, terms ) ){
+ //for debugging
if( Debug.isOn("qcf-check-inst") ){
- //if( e==effort_conflict ){
Node inst = d_quantEngine->getInstantiation( q, terms );
Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;
- Assert( evaluate( inst )!=1 );
- Assert( evaluate( inst )==-1 || e>effort_conflict );
- //}
+ Assert( !getTermDatabase()->isEntailed( inst, true ) );
+ Assert( getTermDatabase()->isEntailed( inst, false ) || e>effort_conflict );
}
- if( d_quantEngine->addInstantiation( q, terms, false ) ){
+ if( d_quantEngine->addInstantiation( q, terms ) ){
Trace("qcf-check") << " ... Added instantiation" << std::endl;
Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;
qi->debugPrintMatch("qcf-inst");
Trace("qcf-inst") << std::endl;
++addedLemmas;
if( e==effort_conflict ){
- d_quant_order.insert( d_quant_order.begin(), q );
+ d_quantEngine->markRelevant( q );
++(d_statistics.d_conflict_inst);
if( options::qcfAllConflict() ){
isConflict = true;
@@ -2045,11 +2020,14 @@ void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
}
break;
}else if( e==effort_prop_eq ){
+ d_quantEngine->markRelevant( q );
++(d_statistics.d_prop_inst);
}
}else{
Trace("qcf-inst") << " ... Failed to add instantiation" << std::endl;
- //Assert( false );
+ //this should only happen if the algorithm generates the same propagating instance twice this round
+ //in this case, break to avoid exponential behavior
+ break;
}
}
//clean up assigned
@@ -2062,6 +2040,7 @@ void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
Trace("qcf-inst") << " ... Spurious instantiation (match is inconsistent)" << std::endl;
}
}
+ Trace("qcf-check") << "Done, conflict = " << d_conflict << std::endl;
if( d_conflict ){
break;
}
@@ -2099,60 +2078,24 @@ void QuantConflictFind::computeRelevantEqr() {
//d_uf_terms.clear();
//d_eqc_uf_terms.clear();
d_eqcs.clear();
- d_model_basis.clear();
//d_arg_reps.clear();
//double clSet = 0;
//if( Trace.isOn("qcf-opt") ){
// clSet = double(clock())/double(CLOCKS_PER_SEC);
//}
- //long nTermst = 0;
- //long nTerms = 0;
- //long nEqc = 0;
-
- //which nodes are irrelevant for disequality matches
- std::map< TNode, bool > irrelevant_dnode;
//now, store matches
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
while( !eqcs_i.isFinished() ){
- //nEqc++;
Node r = (*eqcs_i);
if( getTermDatabase()->hasTermCurrent( r ) ){
TypeNode rtn = r.getType();
- if( options::qcfMode()==QCF_MC ){
- std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );
- if( itt==d_eqcs.end() ){
- Node mb = getTermDatabase()->getModelBasisTerm( rtn );
- if( !getEqualityEngine()->hasTerm( mb ) ){
- Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;
- Assert( false );
- }
- Node mbr = getRepresentative( mb );
- if( mbr!=r ){
- d_eqcs[rtn].push_back( mbr );
- }
- d_eqcs[rtn].push_back( r );
- d_model_basis[rtn] = mb;
- }else{
- itt->second.push_back( r );
- }
- }else{
- if( !options::cbqi() || !TermDb::hasInstConstAttr( r ) ){
- d_eqcs[rtn].push_back( r );
- }
+ if( !options::cbqi() || !TermDb::hasInstConstAttr( r ) ){
+ d_eqcs[rtn].push_back( r );
}
}
++eqcs_i;
}
- /*
- if( Trace.isOn("qcf-opt") ){
- double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
- Trace("qcf-opt") << "Compute rel eqc : " << std::endl;
- Trace("qcf-opt") << " " << nEqc << " equivalence classes. " << std::endl;
- Trace("qcf-opt") << " " << nTerms << " / " << nTermst << " terms." << std::endl;
- Trace("qcf-opt") << " Time : " << (clSet2-clSet) << std::endl;
- }
- */
}
}
@@ -2179,21 +2122,6 @@ void QuantConflictFind::debugPrint( const char * c ) {
++eqc_i;
}
Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
- /*
- EqcInfo * eqcn = getEqcInfo( n, false );
- if( eqcn ){
- Trace(c) << " DEQ : {";
- pr = false;
- for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){
- if( (*it).second ){
- Trace(c) << (pr ? "," : "" ) << " " << (*it).first;
- pr = true;
- }
- }
- Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
- }
- //}
- */
++eqcs_i;
}
}
@@ -2255,5 +2183,6 @@ TNode QuantConflictFind::getZero( Kind k ) {
}
}
-
-}
+} /* namespace CVC4::theory::quantifiers */
+} /* namespace CVC4::theory */
+} /* namespace CVC4 */
diff --git a/src/theory/quantifiers/quant_conflict_find.h b/src/theory/quantifiers/quant_conflict_find.h
index 11299b532..8b42b0916 100644
--- a/src/theory/quantifiers/quant_conflict_find.h
+++ b/src/theory/quantifiers/quant_conflict_find.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quant_conflict_find.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief quantifiers conflict find class
**/
@@ -98,7 +98,7 @@ public:
// is this term treated as UF application?
static bool isHandledBoolConnective( TNode n );
static bool isHandledUfTerm( TNode n );
- static Node getOperator( QuantConflictFind * p, Node n );
+ static Node getMatchOperator( QuantConflictFind * p, Node n );
//can this node be handled by the algorithm
static bool isHandled( TNode n );
};
@@ -114,9 +114,12 @@ private: //for completing match
int d_unassigned_nvar;
int d_una_index;
std::vector< int > d_una_eqc_count;
+ //optimization: track which arguments variables appear under UF terms in
+ std::map< int, std::map< TNode, std::vector< unsigned > > > d_var_rel_dom;
+ void getPropagateVars( std::vector< TNode >& vars, TNode n, bool pol, std::map< TNode, bool >& visited );
public:
- QuantInfo() : d_mg( NULL ) {}
- ~QuantInfo() { delete d_mg; }
+ QuantInfo();
+ ~QuantInfo();
std::vector< TNode > d_vars;
std::vector< TypeNode > d_var_types;
std::map< TNode, int > d_var_num;
@@ -128,13 +131,25 @@ public:
int getNumVars() { return (int)d_vars.size(); }
TNode getVar( int i ) { return d_vars[i]; }
+ typedef std::map< int, MatchGen * > VarMgMap;
+ private:
MatchGen * d_mg;
+ VarMgMap d_var_mg;
+ public:
+ VarMgMap::const_iterator var_mg_find(int i) const { return d_var_mg.find(i); }
+ VarMgMap::const_iterator var_mg_end() const { return d_var_mg.end(); }
+ bool containsVarMg(int i) const { return var_mg_find(i) != var_mg_end(); }
+
+ bool matchGeneratorIsValid() const { return d_mg->isValid(); }
+ bool getNextMatch( QuantConflictFind * p ) {
+ return d_mg->getNextMatch(p, this);
+ }
+
Node d_q;
- std::map< int, MatchGen * > d_var_mg;
void reset_round( QuantConflictFind * p );
public:
//initialize
- void initialize( Node q, Node qn );
+ void initialize( QuantConflictFind * p, Node q, Node qn );
//current constraints
std::vector< TNode > d_match;
std::vector< TNode > d_match_term;
@@ -146,7 +161,7 @@ public:
bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
- bool setMatch( QuantConflictFind * p, int v, TNode n );
+ bool setMatch( QuantConflictFind * p, int v, TNode n, bool isGroundRep );
bool isMatchSpurious( QuantConflictFind * p );
bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );
bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );
@@ -166,7 +181,6 @@ class QuantConflictFind : public QuantifiersModule
typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
private:
context::CDO< bool > d_conflict;
- std::vector< Node > d_quant_order;
std::map< Kind, Node > d_zero;
//for storing nodes created during t-constraint solving (prevents memory leaks)
std::vector< Node > d_tempCache;
@@ -180,21 +194,14 @@ public: //for ground terms
Node d_false;
TNode getZero( Kind k );
private:
- Node evaluateTerm( Node n );
- int evaluate( Node n, bool pref = false, bool hasPref = false );
-private:
- //currently asserted quantifiers
- NodeList d_qassert;
std::map< Node, QuantInfo > d_qinfo;
private: //for equivalence classes
// type -> list(eqc)
std::map< TypeNode, std::vector< TNode > > d_eqcs;
- std::map< TypeNode, Node > d_model_basis;
public:
enum {
effort_conflict,
effort_prop_eq,
- effort_mc,
};
short d_effort;
void setEffort( int e ) { d_effort = e; }
@@ -248,8 +255,8 @@ public:
std::string identify() const { return "QcfEngine"; }
};
-}
-}
-}
+} /* namespace CVC4::theory::quantifiers */
+} /* namespace CVC4::theory */
+} /* namespace CVC4 */
#endif
diff --git a/src/theory/quantifiers/quant_equality_engine.cpp b/src/theory/quantifiers/quant_equality_engine.cpp
index 54a931196..3f89a799c 100644
--- a/src/theory/quantifiers/quant_equality_engine.cpp
+++ b/src/theory/quantifiers/quant_equality_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quant_equality_engine.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** Congruence closure with free variables
**/
@@ -32,6 +32,7 @@ d_conflict(c, false),
d_quant_red(c),
d_quant_unproc(c){
d_uequalityEngine.addFunctionKind( kind::APPLY_UF );
+ d_intType = NodeManager::currentNM()->integerType();
}
void QuantEqualityEngine::conflict(TNode t1, TNode t2) {
@@ -86,56 +87,130 @@ void QuantEqualityEngine::registerQuantifier( Node q ) {
void QuantEqualityEngine::assertNode( Node n ) {
Assert( n.getKind()==FORALL );
Trace("qee-debug") << "QEE assert : " << n << std::endl;
- Node lit = n[1].getKind()==NOT ? n[1][0] : n[1];
- bool pol = n[1].getKind()!=NOT;
- if( lit.getKind()==APPLY_UF || lit.getKind()==EQUAL ){
- lit = getTermDatabase()->getCanonicalTerm( lit );
- Trace("qee-debug") << "Canonical : " << lit << ", pol = " << pol << std::endl;
- Node t1 = lit.getKind()==APPLY_UF ? lit : lit[0];
+ if( !d_conflict ){
+ Node lit = n[1].getKind()==NOT ? n[1][0] : n[1];
+ bool pol = n[1].getKind()!=NOT;
+ bool success = true;
+ Node t1;
Node t2;
- if( lit.getKind()==APPLY_UF ){
- t2 = pol ? getTermDatabase()->d_true : getTermDatabase()->d_false;
- pol = true;
+ if( lit.getKind()==APPLY_UF || lit.getKind()==EQUAL || lit.getKind()==IFF ){
+ lit = getTermDatabase()->getCanonicalTerm( lit );
+ Trace("qee-debug") << "Canonical : " << lit << ", pol = " << pol << std::endl;
+ if( lit.getKind()==APPLY_UF ){
+ t1 = getFunctionAppForPredicateApp( lit );
+ t2 = pol ? getTermDatabase()->d_one : getTermDatabase()->d_zero;
+ pol = true;
+ lit = NodeManager::currentNM()->mkNode( EQUAL, t1, t2 );
+ }else if( lit.getKind()==EQUAL ){
+ t1 = lit[0];
+ t2 = lit[1];
+ }else if( lit.getKind()==IFF ){
+ if( lit[0].getKind()==NOT ){
+ t1 = lit[0][0];
+ pol = !pol;
+ }else{
+ t1 = lit[0];
+ }
+ if( lit[1].getKind()==NOT ){
+ t2 = lit[1][0];
+ pol = !pol;
+ }else{
+ t2 = lit[1];
+ }
+ if( t1.getKind()==APPLY_UF && t2.getKind()==APPLY_UF ){
+ t1 = getFunctionAppForPredicateApp( t1 );
+ t2 = getFunctionAppForPredicateApp( t2 );
+ lit = NodeManager::currentNM()->mkNode( EQUAL, t1, t2 );
+ }else{
+ success = false;
+ }
+ }
}else{
- t2 = lit[1];
- }
- bool alreadyHolds = false;
- if( pol && areUnivEqual( t1, t2 ) ){
- alreadyHolds = true;
- }else if( !pol && areUnivDisequal( t1, t2 ) ){
- alreadyHolds = true;
+ success = false;
}
+ if( success ){
+ bool alreadyHolds = false;
+ if( pol && areUnivEqualInternal( t1, t2 ) ){
+ alreadyHolds = true;
+ }else if( !pol && areUnivDisequalInternal( t1, t2 ) ){
+ alreadyHolds = true;
+ }
- if( alreadyHolds ){
- d_quant_red.push_back( n );
- Trace("qee-debug") << "...add to redundant" << std::endl;
- }else{
- Trace("qee-debug") << "...assert" << std::endl;
- Trace("qee-assert") << "QEE : assert : " << lit << ", pol = " << pol << ", kind = " << lit.getKind() << std::endl;
- if( lit.getKind()==APPLY_UF ){
- d_uequalityEngine.assertPredicate(lit, pol, n);
+ if( alreadyHolds ){
+ d_quant_red.push_back( n );
+ Trace("qee-debug") << "...add to redundant" << std::endl;
}else{
- d_uequalityEngine.assertEquality(lit, pol, n);
+ Trace("qee-debug") << "...assert" << std::endl;
+ Trace("qee-assert") << "QEE : assert : " << lit << ", pol = " << pol << ", kind = " << lit.getKind() << std::endl;
+ if( lit.getKind()==APPLY_UF ){
+ d_uequalityEngine.assertPredicate(lit, pol, n);
+ }else{
+ d_uequalityEngine.assertEquality(lit, pol, n);
+ }
}
+ }else{
+ d_quant_unproc[n] = true;
+ Trace("qee-debug") << "...add to unprocessed (" << lit.getKind() << ")" << std::endl;
}
- }else{
- d_quant_unproc[n] = true;
- Trace("qee-debug") << "...add to unprocessed (" << lit.getKind() << ")" << std::endl;
}
}
-bool QuantEqualityEngine::areUnivDisequal( TNode n1, TNode n2 ) {
+bool QuantEqualityEngine::areUnivDisequalInternal( TNode n1, TNode n2 ) {
return n1!=n2 && d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areDisequal( n1, n2, false );
}
-bool QuantEqualityEngine::areUnivEqual( TNode n1, TNode n2 ) {
+bool QuantEqualityEngine::areUnivEqualInternal( TNode n1, TNode n2 ) {
return n1==n2 || ( d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areEqual( n1, n2 ) );
}
-TNode QuantEqualityEngine::getUnivRepresentative( TNode n ) {
+TNode QuantEqualityEngine::getUnivRepresentativeInternal( TNode n ) {
if( d_uequalityEngine.hasTerm( n ) ){
return d_uequalityEngine.getRepresentative( n );
}else{
return n;
}
-} \ No newline at end of file
+}
+bool QuantEqualityEngine::areUnivDisequal( TNode n1, TNode n2 ) {
+ //TODO: must convert to internal representation
+ return areUnivDisequalInternal( n1, n2 );
+}
+
+bool QuantEqualityEngine::areUnivEqual( TNode n1, TNode n2 ) {
+ //TODO: must convert to internal representation
+ return areUnivEqualInternal( n1, n2 );
+}
+
+TNode QuantEqualityEngine::getUnivRepresentative( TNode n ) {
+ //TODO: must convert to internal representation
+ return getUnivRepresentativeInternal( n );
+}
+
+Node QuantEqualityEngine::getFunctionForPredicate( Node f ) {
+ std::map< Node, Node >::iterator it = d_pred_to_func.find( f );
+ if( it==d_pred_to_func.end() ){
+ std::vector< TypeNode > argTypes;
+ TypeNode tn = f.getType();
+ for( unsigned i=0; i<(tn.getNumChildren()-1); i++ ){
+ argTypes.push_back( tn[i] );
+ }
+ TypeNode ftn = NodeManager::currentNM()->mkFunctionType( argTypes, d_intType );
+ std::stringstream ss;
+ ss << "ee_" << f;
+ Node op = NodeManager::currentNM()->mkSkolem( ss.str(), ftn, "op created for internal ee" );
+ d_pred_to_func[f] = op;
+ return op;
+ }else{
+ return it->second;
+ }
+}
+
+Node QuantEqualityEngine::getFunctionAppForPredicateApp( Node n ) {
+ Assert( n.getKind()==APPLY_UF );
+ std::vector< Node > children;
+ children.push_back( getFunctionForPredicate( n.getOperator() ) );
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ children.push_back( n[i] );
+ }
+ return NodeManager::currentNM()->mkNode( APPLY_UF, children );
+}
+
diff --git a/src/theory/quantifiers/quant_equality_engine.h b/src/theory/quantifiers/quant_equality_engine.h
index 35a328147..26654de4d 100644
--- a/src/theory/quantifiers/quant_equality_engine.h
+++ b/src/theory/quantifiers/quant_equality_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quant_equality_engine.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Congruence closure with free variables
**/
@@ -56,12 +56,21 @@ private:
context::CDList<Node> d_quant_red;
/** unprocessed quantifiers in current context */
NodeBoolMap d_quant_unproc;
+ // map predicates to functions over int
+ TypeNode d_intType;
+ std::map< Node, Node > d_pred_to_func;
+ Node getFunctionForPredicate( Node f );
+ Node getFunctionAppForPredicateApp( Node n );
private:
void conflict(TNode t1, TNode t2);
void eqNotifyNewClass(TNode t);
void eqNotifyPreMerge(TNode t1, TNode t2);
void eqNotifyPostMerge(TNode t1, TNode t2);
void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);
+ //queries
+ bool areUnivDisequalInternal( TNode n1, TNode n2 );
+ bool areUnivEqualInternal( TNode n1, TNode n2 );
+ TNode getUnivRepresentativeInternal( TNode n );
public:
QuantEqualityEngine( QuantifiersEngine * qe, context::Context* c );
virtual ~QuantEqualityEngine() throw (){}
diff --git a/src/theory/quantifiers/quant_split.cpp b/src/theory/quantifiers/quant_split.cpp
new file mode 100644
index 000000000..9fb943e5e
--- /dev/null
+++ b/src/theory/quantifiers/quant_split.cpp
@@ -0,0 +1,134 @@
+/********************* */
+/*! \file quant_split.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Implementation of dynamic quantifiers splitting
+ **/
+
+#include "theory/quantifiers/quant_split.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/quantifiers/first_order_model.h"
+#include "options/quantifiers_options.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+
+
+QuantDSplit::QuantDSplit( QuantifiersEngine * qe, context::Context* c ) :
+QuantifiersModule( qe ), d_added_split( qe->getUserContext() ){
+
+}
+
+/** pre register quantifier */
+void QuantDSplit::preRegisterQuantifier( Node q ) {
+ int max_index = -1;
+ int max_score = -1;
+ if( q.getNumChildren()==3 ){
+ return;
+ }
+ Trace("quant-dsplit-debug") << "Check split quantified formula : " << q << std::endl;
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+ TypeNode tn = q[0][i].getType();
+ if( tn.isDatatype() ){
+ const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
+ if( dt.isRecursiveSingleton() ){
+ Trace("quant-dsplit-debug") << "Datatype " << dt.getName() << " is recursive singleton." << std::endl;
+ }else{
+ int score = -1;
+ if( options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_AGG ){
+ score = dt.isUFinite() ? 1 : -1;
+ }else if( options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_DEFAULT ){
+ score = dt.isUFinite() ? 1 : -1;
+ }
+ Trace("quant-dsplit-debug") << "Datatype " << dt.getName() << " is score " << score << " (" << dt.isUFinite() << " " << dt.isFinite() << ")" << std::endl;
+ if( score>max_score ){
+ max_index = i;
+ max_score = score;
+ }
+ }
+ }
+ }
+
+ if( max_index!=-1 ){
+ Trace("quant-dsplit-debug") << "Will split at index " << max_index << "." << std::endl;
+ d_quant_to_reduce[q] = max_index;
+ d_quantEngine->setOwner( q, this );
+ }
+}
+
+/* whether this module needs to check this round */
+bool QuantDSplit::needsCheck( Theory::Effort e ) {
+ return e>=Theory::EFFORT_FULL && !d_quant_to_reduce.empty();
+}
+
+/* Call during quantifier engine's check */
+void QuantDSplit::check( Theory::Effort e, unsigned quant_e ) {
+ //add lemmas ASAP (they are a reduction)
+ if( quant_e==QuantifiersEngine::QEFFORT_CONFLICT ){
+ std::vector< Node > lemmas;
+ for(std::map< Node, int >::iterator it = d_quant_to_reduce.begin(); it != d_quant_to_reduce.end(); ++it) {
+ Node q = it->first;
+ if( d_added_split.find( q )==d_added_split.end() ){
+ d_added_split.insert( q );
+ std::vector< Node > bvs;
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+ if( (int)i!=it->second ){
+ bvs.push_back( q[0][i] );
+ }
+ }
+ std::vector< Node > disj;
+ disj.push_back( q.negate() );
+ TNode svar = q[0][it->second];
+ TypeNode tn = svar.getType();
+ if( tn.isDatatype() ){
+ std::vector< Node > cons;
+ const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
+ for( unsigned j=0; j<dt.getNumConstructors(); j++ ){
+ std::vector< Node > vars;
+ for( unsigned k=0; k<dt[j].getNumArgs(); k++ ){
+ TypeNode tns = TypeNode::fromType( dt[j][k].getRangeType() );
+ Node v = NodeManager::currentNM()->mkBoundVar( tns );
+ vars.push_back( v );
+ }
+ std::vector< Node > bvs_cmb;
+ bvs_cmb.insert( bvs_cmb.end(), bvs.begin(), bvs.end() );
+ bvs_cmb.insert( bvs_cmb.end(), vars.begin(), vars.end() );
+ vars.insert( vars.begin(), Node::fromExpr( dt[j].getConstructor() ) );
+ Node c = NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, vars );
+ TNode ct = c;
+ Node body = q[1].substitute( svar, ct );
+ if( !bvs_cmb.empty() ){
+ body = NodeManager::currentNM()->mkNode( kind::FORALL, NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, bvs_cmb ), body );
+ }
+ cons.push_back( body );
+ }
+ Node conc = cons.size()==1 ? cons[0] : NodeManager::currentNM()->mkNode( kind::AND, cons );
+ disj.push_back( conc );
+ }else{
+ Assert( false );
+ }
+ lemmas.push_back( disj.size()==1 ? disj[0] : NodeManager::currentNM()->mkNode( kind::OR, disj ) );
+ }
+ }
+
+ //add lemmas to quantifiers engine
+ for( unsigned i=0; i<lemmas.size(); i++ ){
+ Trace("quant-dsplit") << "QuantDSplit lemma : " << lemmas[i] << std::endl;
+ d_quantEngine->addLemma( lemmas[i], false );
+ }
+ d_quant_to_reduce.clear();
+ }
+}
+
diff --git a/src/theory/quantifiers/quant_split.h b/src/theory/quantifiers/quant_split.h
new file mode 100644
index 000000000..d36824998
--- /dev/null
+++ b/src/theory/quantifiers/quant_split.h
@@ -0,0 +1,54 @@
+/********************* */
+/*! \file quant_split.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief dynamic quantifiers splitting
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANT_SPLIT_H
+#define __CVC4__THEORY__QUANT_SPLIT_H
+
+#include "theory/quantifiers_engine.h"
+#include "context/cdo.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class QuantDSplit : public QuantifiersModule {
+ typedef context::CDHashSet<Node, NodeHashFunction> NodeSet;
+private:
+ /** list of relevant quantifiers asserted in the current context */
+ std::map< Node, int > d_quant_to_reduce;
+ /** whether we have instantiated quantified formulas */
+ NodeSet d_added_split;
+public:
+ QuantDSplit( QuantifiersEngine * qe, context::Context* c );
+ /** determine whether this quantified formula will be reduced */
+ void preRegisterQuantifier( Node q );
+
+ /* whether this module needs to check this round */
+ bool needsCheck( Theory::Effort e );
+ /* Call during quantifier engine's check */
+ void check( Theory::Effort e, unsigned quant_e );
+ /* Called for new quantifiers */
+ void registerQuantifier( Node q ) {}
+ void assertNode( Node n ) {}
+ /** Identify this module (for debugging, dynamic configuration, etc..) */
+ std::string identify() const { return "QuantDSplit"; }
+};
+
+}
+}
+}
+
+#endif
diff --git a/src/theory/quantifiers/quant_util.cpp b/src/theory/quantifiers/quant_util.cpp
index bf91f74c6..3b7787a20 100644
--- a/src/theory/quantifiers/quant_util.cpp
+++ b/src/theory/quantifiers/quant_util.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quant_util.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of quantifier utilities
**/
@@ -23,6 +23,38 @@ using namespace CVC4::kind;
using namespace CVC4::context;
using namespace CVC4::theory;
+
+unsigned QuantifiersModule::needsModel( Theory::Effort e ) {
+ return QuantifiersEngine::QEFFORT_NONE;
+}
+
+eq::EqualityEngine * QuantifiersModule::getEqualityEngine() {
+ return d_quantEngine->getMasterEqualityEngine();
+}
+
+bool QuantifiersModule::areEqual( TNode n1, TNode n2 ) {
+ eq::EqualityEngine * ee = getEqualityEngine();
+ return n1==n2 || ( ee->hasTerm( n1 ) && ee->hasTerm( n2 ) && ee->areEqual( n1, n2 ) );
+}
+
+bool QuantifiersModule::areDisequal( TNode n1, TNode n2 ) {
+ eq::EqualityEngine * ee = getEqualityEngine();
+ return n1!=n2 && ee->hasTerm( n1 ) && ee->hasTerm( n2 ) && ee->areDisequal( n1, n2, false );
+}
+
+TNode QuantifiersModule::getRepresentative( TNode n ) {
+ eq::EqualityEngine * ee = getEqualityEngine();
+ if( ee->hasTerm( n ) ){
+ return ee->getRepresentative( n );
+ }else{
+ return n;
+ }
+}
+
+quantifiers::TermDb * QuantifiersModule::getTermDatabase() {
+ return d_quantEngine->getTermDatabase();
+}
+
bool QuantArith::getMonomial( Node n, Node& c, Node& v ){
if( n.getKind()==MULT && n.getNumChildren()==2 && n[0].isConst() ){
c = n[0];
@@ -33,8 +65,13 @@ bool QuantArith::getMonomial( Node n, Node& c, Node& v ){
}
}
bool QuantArith::getMonomial( Node n, std::map< Node, Node >& msum ) {
- if ( n.getKind()==MULT ){
- if( n.getNumChildren()==2 && msum.find(n[1])==msum.end() && n[0].isConst() ){
+ if( n.isConst() ){
+ if( msum.find(Node::null())==msum.end() ){
+ msum[Node::null()] = n;
+ return true;
+ }
+ }else if( n.getKind()==MULT && n.getNumChildren()==2 && n[0].isConst() ){
+ if( msum.find(n[1])==msum.end() ){
msum[n[1]] = n[0];
return true;
}
@@ -63,10 +100,7 @@ bool QuantArith::getMonomialSum( Node n, std::map< Node, Node >& msum ) {
bool QuantArith::getMonomialSumLit( Node lit, std::map< Node, Node >& msum ) {
if( lit.getKind()==GEQ || lit.getKind()==EQUAL ){
if( getMonomialSum( lit[0], msum ) ){
- if( lit[1].isConst() ){
- if( !lit[1].getConst<Rational>().isZero() ){
- msum[Node::null()] = negate( lit[1] );
- }
+ if( lit[1].isConst() && lit[1].getConst<Rational>().isZero() ){
return true;
}else{
//subtract the other side
@@ -90,7 +124,29 @@ bool QuantArith::getMonomialSumLit( Node lit, std::map< Node, Node >& msum ) {
return false;
}
-int QuantArith::isolate( Node v, std::map< Node, Node >& msum, Node & veq, Kind k, bool doCoeff ) {
+Node QuantArith::mkNode( std::map< Node, Node >& msum ) {
+ std::vector< Node > children;
+ for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ){
+ Node m;
+ if( !it->first.isNull() ){
+ if( !it->second.isNull() ){
+ m = NodeManager::currentNM()->mkNode( MULT, it->second, it->first );
+ }else{
+ m = it->first;
+ }
+ }else{
+ Assert( !it->second.isNull() );
+ m = it->second;
+ }
+ children.push_back(m);
+ }
+ return children.size()>1 ? NodeManager::currentNM()->mkNode( PLUS, children ) : (children.size()==1 ? children[0] : NodeManager::currentNM()->mkConst( Rational(0) ));
+}
+
+// given (msum <k> 0), solve (veq_c * v <k> val) or (val <k> veq_c * v), where:
+// veq_c is either null (meaning 1), or positive.
+// return value 1: veq_c*v is RHS, -1: veq_c*v is LHS, 0: failed.
+int QuantArith::isolate( Node v, std::map< Node, Node >& msum, Node & veq_c, Node & val, Kind k ) {
std::map< Node, Node >::iterator itv = msum.find( v );
if( itv!=msum.end() ){
std::vector< Node > children;
@@ -111,46 +167,42 @@ int QuantArith::isolate( Node v, std::map< Node, Node >& msum, Node & veq, Kind
children.push_back(m);
}
}
- veq = children.size()>1 ? NodeManager::currentNM()->mkNode( PLUS, children ) :
+ val = children.size()>1 ? NodeManager::currentNM()->mkNode( PLUS, children ) :
(children.size()==1 ? children[0] : NodeManager::currentNM()->mkConst( Rational(0) ));
- Node vc = v;
if( !r.isOne() && !r.isNegativeOne() ){
- if( vc.getType().isInteger() ){
- if( doCoeff ){
- vc = NodeManager::currentNM()->mkNode( MULT, NodeManager::currentNM()->mkConst( r.abs() ), vc );
- }else{
- return 0;
- }
+ if( v.getType().isInteger() ){
+ veq_c = NodeManager::currentNM()->mkConst( r.abs() );
}else{
- veq = NodeManager::currentNM()->mkNode( MULT, veq, NodeManager::currentNM()->mkConst( Rational(1) / r.abs() ) );
+ val = NodeManager::currentNM()->mkNode( MULT, val, NodeManager::currentNM()->mkConst( Rational(1) / r.abs() ) );
}
}
if( r.sgn()==1 ){
- veq = negate(veq);
+ val = negate(val);
+ }else{
+ val = Rewriter::rewrite( val );
}
- veq = Rewriter::rewrite( veq );
- bool inOrder = r.sgn()==1 || k==EQUAL;
- veq = NodeManager::currentNM()->mkNode( k, inOrder ? vc : veq, inOrder ? veq : vc );
- return inOrder ? 1 : -1;
+ return ( r.sgn()==1 || k==EQUAL ) ? 1 : -1;
}
}
return 0;
}
-int QuantArith::isolate( Node v, std::map< Node, Node >& msum, Node & veq_c, Node & val, Kind k ) {
- Node vatom;
- //isolate pv in the inequality
- int ires = isolate( v, msum, vatom, k, true );
+int QuantArith::isolate( Node v, std::map< Node, Node >& msum, Node & veq, Kind k, bool doCoeff ) {
+ Node veq_c;
+ Node val;
+ //isolate v in the (in)equality
+ int ires = isolate( v, msum, veq_c, val, k );
if( ires!=0 ){
- val = vatom[ ires==1 ? 1 : 0 ];
- Node pvm = vatom[ ires==1 ? 0 : 1 ];
- //get monomial
- if( pvm!=v ){
- Node veq_v;
- if( QuantArith::getMonomial( pvm, veq_c, veq_v ) ){
- Assert( veq_v==v );
+ Node vc = v;
+ if( !veq_c.isNull() ){
+ if( doCoeff ){
+ vc = NodeManager::currentNM()->mkNode( MULT, veq_c, vc );
+ }else{
+ return 0;
}
}
+ bool inOrder = ires==1;
+ veq = NodeManager::currentNM()->mkNode( k, inOrder ? vc : val, inOrder ? val : vc );
}
return ires;
}
@@ -164,7 +216,7 @@ Node QuantArith::solveEqualityFor( Node lit, Node v ) {
return lit[1-r];
}
}
- if( tn.isInteger() || tn.isReal() ){
+ if( tn.isReal() ){
if( quantifiers::TermDb::containsTerm( lit, v ) ){
std::map< Node, Node > msum;
if( QuantArith::getMonomialSumLit( lit, msum ) ){
@@ -357,3 +409,20 @@ void QuantPhaseReq::getPolarity( Node n, int child, bool hasPol, bool pol, bool&
newPol = pol;
}
}
+
+void QuantPhaseReq::getEntailPolarity( Node n, int child, bool hasPol, bool pol, bool& newHasPol, bool& newPol ) {
+ if( n.getKind()==AND || n.getKind()==OR ){
+ newHasPol = hasPol && pol==( n.getKind()==AND );
+ newPol = pol;
+ }else if( n.getKind()==IMPLIES ){
+ newHasPol = hasPol && !pol;
+ newPol = child==0 ? !pol : pol;
+ }else if( n.getKind()==NOT ){
+ newHasPol = hasPol;
+ newPol = !pol;
+ }else{
+ newHasPol = false;
+ newPol = pol;
+ }
+}
+
diff --git a/src/theory/quantifiers/quant_util.h b/src/theory/quantifiers/quant_util.h
index 566a09923..79cdae437 100644
--- a/src/theory/quantifiers/quant_util.h
+++ b/src/theory/quantifiers/quant_util.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quant_util.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief quantifier util
**/
@@ -29,6 +29,58 @@ namespace theory {
class QuantifiersEngine;
+namespace quantifiers {
+ class TermDb;
+}
+
+class QuantifiersModule {
+protected:
+ QuantifiersEngine* d_quantEngine;
+public:
+ QuantifiersModule( QuantifiersEngine* qe ) : d_quantEngine( qe ){}
+ virtual ~QuantifiersModule(){}
+ //get quantifiers engine
+ QuantifiersEngine* getQuantifiersEngine() { return d_quantEngine; }
+ /** presolve */
+ virtual void presolve() {}
+ /* whether this module needs to check this round */
+ virtual bool needsCheck( Theory::Effort e ) { return e>=Theory::EFFORT_LAST_CALL; }
+ /* whether this module needs a model built */
+ virtual unsigned needsModel( Theory::Effort e );
+ /* reset at a round */
+ virtual void reset_round( Theory::Effort e ){}
+ /* Call during quantifier engine's check */
+ virtual void check( Theory::Effort e, unsigned quant_e ) = 0;
+ /* check was complete (e.g. no lemmas implies a model) */
+ virtual bool checkComplete() { return true; }
+ /* Called for new quantified formulas */
+ virtual void preRegisterQuantifier( Node q ) { }
+ /* Called for new quantifiers after owners are finalized */
+ virtual void registerQuantifier( Node q ) = 0;
+ virtual void assertNode( Node n ) {}
+ virtual void propagate( Theory::Effort level ){}
+ virtual Node getNextDecisionRequest() { return TNode::null(); }
+ /** Identify this module (for debugging, dynamic configuration, etc..) */
+ virtual std::string identify() const = 0;
+public:
+ eq::EqualityEngine * getEqualityEngine();
+ bool areDisequal( TNode n1, TNode n2 );
+ bool areEqual( TNode n1, TNode n2 );
+ TNode getRepresentative( TNode n );
+ quantifiers::TermDb * getTermDatabase();
+};/* class QuantifiersModule */
+
+class QuantifiersUtil {
+public:
+ QuantifiersUtil(){}
+ virtual ~QuantifiersUtil(){}
+ /* reset at a round */
+ virtual bool reset( Theory::Effort e ) = 0;
+ /** Identify this module (for debugging, dynamic configuration, etc..) */
+ virtual std::string identify() const = 0;
+};
+
+
class QuantArith
{
public:
@@ -36,9 +88,10 @@ public:
static bool getMonomial( Node n, std::map< Node, Node >& msum );
static bool getMonomialSum( Node n, std::map< Node, Node >& msum );
static bool getMonomialSumLit( Node lit, std::map< Node, Node >& msum );
+ static Node mkNode( std::map< Node, Node >& msum );
//return 1 : solved on LHS, return -1 : solved on RHS, return 0: failed
- static int isolate( Node v, std::map< Node, Node >& msum, Node & veq, Kind k, bool doCoeff = false );
static int isolate( Node v, std::map< Node, Node >& msum, Node & veq_c, Node & val, Kind k );
+ static int isolate( Node v, std::map< Node, Node >& msum, Node & veq, Kind k, bool doCoeff = false );
static Node solveEqualityFor( Node lit, Node v );
static Node negate( Node t );
static Node offset( Node t, int i );
@@ -92,15 +145,16 @@ public:
std::map< Node, Node > d_phase_reqs_equality_term;
static void getPolarity( Node n, int child, bool hasPol, bool pol, bool& newHasPol, bool& newPol );
+ static void getEntailPolarity( Node n, int child, bool hasPol, bool pol, bool& newHasPol, bool& newPol );
};
-class EqualityQuery {
+class EqualityQuery : public QuantifiersUtil{
public:
EqualityQuery(){}
virtual ~EqualityQuery(){};
- /** reset */
- virtual void reset() = 0;
+ /** extends engine */
+ virtual bool extendsEngine() { return false; }
/** contains term */
virtual bool hasTerm( Node a ) = 0;
/** get the representative of the equivalence class of a */
@@ -113,6 +167,8 @@ public:
virtual eq::EqualityEngine* getEngine() = 0;
/** get the equivalence class of a */
virtual void getEquivalenceClass( Node a, std::vector< Node >& eqc ) = 0;
+ /** get the term that exists in EE that is congruent to f with args (f is returned by TermDb::getMatchOperator(...) */
+ virtual TNode getCongruentTerm( Node f, std::vector< TNode >& args ) = 0;
};/* class EqualityQuery */
diff --git a/src/theory/quantifiers/quantifiers_attributes.cpp b/src/theory/quantifiers/quantifiers_attributes.cpp
index 8c6b30124..b797f4ce9 100644
--- a/src/theory/quantifiers/quantifiers_attributes.cpp
+++ b/src/theory/quantifiers/quantifiers_attributes.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_attributes.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of QuantifiersAttributes class
**/
@@ -24,7 +24,7 @@ using namespace CVC4::context;
using namespace CVC4::theory;
using namespace CVC4::theory::quantifiers;
-void QuantifiersAttributes::setUserAttribute( const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value ){
+void QuantifiersAttributes::setUserAttribute( const std::string& attr, Node n, std::vector< Node >& node_values, std::string str_value ){
Trace("quant-attr-debug") << "Set " << attr << " " << n << std::endl;
if( attr=="axiom" ){
Trace("quant-attr-debug") << "Set axiom " << n << std::endl;
@@ -58,5 +58,13 @@ void QuantifiersAttributes::setUserAttribute( const std::string& attr, Node n, s
Trace("quant-attr-debug") << "Set rewrite rule priority " << n << " to " << lvl << std::endl;
RrPriorityAttribute rrpa;
n.setAttribute( rrpa, lvl );
+ }else if( attr=="quant-elim" ){
+ Trace("quant-attr-debug") << "Set quantifier elimination " << n << std::endl;
+ QuantElimAttribute qea;
+ n.setAttribute( qea, true );
+ }else if( attr=="quant-elim-partial" ){
+ Trace("quant-attr-debug") << "Set partial quantifier elimination " << n << std::endl;
+ QuantElimPartialAttribute qepa;
+ n.setAttribute( qepa, true );
}
}
diff --git a/src/theory/quantifiers/quantifiers_attributes.h b/src/theory/quantifiers/quantifiers_attributes.h
index bad58eef8..53cef796a 100644
--- a/src/theory/quantifiers/quantifiers_attributes.h
+++ b/src/theory/quantifiers/quantifiers_attributes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_attributes.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Attributes for the theory quantifiers
**
@@ -36,7 +36,7 @@ struct QuantifiersAttributes
* This function will apply a custom set of attributes to all top-level universal
* quantifiers contained in n
*/
- static void setUserAttribute( const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value );
+ static void setUserAttribute( const std::string& attr, Node n, std::vector< Node >& node_values, std::string str_value );
};
diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp
index afe8cd598..5aae4d640 100644
--- a/src/theory/quantifiers/quantifiers_rewriter.cpp
+++ b/src/theory/quantifiers/quantifiers_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_rewriter.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of QuantifiersRewriter class
**/
@@ -229,52 +229,48 @@ RewriteResponse QuantifiersRewriter::preRewrite(TNode in) {
RewriteResponse QuantifiersRewriter::postRewrite(TNode in) {
Trace("quantifiers-rewrite-debug") << "post-rewriting " << in << std::endl;
- if( !options::quantRewriteRules() || !TermDb::isRewriteRule( in ) ){
- RewriteStatus status = REWRITE_DONE;
- Node ret = in;
- //get the arguments
- std::vector< Node > args;
- for( int i=0; i<(int)in[0].getNumChildren(); i++ ){
- args.push_back( in[0][i] );
- }
- //get the instantiation pattern list
- Node ipl;
+ RewriteStatus status = REWRITE_DONE;
+ Node ret = in;
+ int rew_op = -1;
+ //get the body
+ if( in.getKind()==EXISTS ){
+ std::vector< Node > children;
+ children.push_back( in[0] );
+ children.push_back( in[1].negate() );
if( in.getNumChildren()==3 ){
- ipl = in[2];
- }
- //get the body
- if( in.getKind()==EXISTS ){
- std::vector< Node > children;
- children.push_back( in[0] );
- children.push_back( in[1].negate() );
- if( in.getNumChildren()==3 ){
- children.push_back( in[2] );
- }
- ret = NodeManager::currentNM()->mkNode( FORALL, children );
- ret = ret.negate();
- status = REWRITE_AGAIN_FULL;
+ children.push_back( in[2] );
+ }
+ ret = NodeManager::currentNM()->mkNode( FORALL, children );
+ ret = ret.negate();
+ status = REWRITE_AGAIN_FULL;
+ }else if( in.getKind()==FORALL ){
+ if( in[1].isConst() ){
+ return RewriteResponse( status, in[1] );
}else{
- for( int op=0; op<COMPUTE_LAST; op++ ){
- //TODO : compute isNested (necessary?)
- bool isNested = false;
- if( doOperation( in, isNested, op ) ){
- ret = computeOperation( in, isNested, op );
- if( ret!=in ){
- status = REWRITE_AGAIN_FULL;
- break;
+ //compute attributes
+ QAttributes qa;
+ TermDb::computeQuantAttributes( in, qa );
+ if( !qa.isRewriteRule() ){
+ for( int op=0; op<COMPUTE_LAST; op++ ){
+ if( doOperation( in, op, qa ) ){
+ ret = computeOperation( in, op, qa );
+ if( ret!=in ){
+ rew_op = op;
+ status = REWRITE_AGAIN_FULL;
+ break;
+ }
}
}
}
}
- //print if changed
- if( in!=ret ){
- Trace("quantifiers-rewrite") << "*** rewrite " << in << std::endl;
- Trace("quantifiers-rewrite") << " to " << std::endl;
- Trace("quantifiers-rewrite") << ret << std::endl;
- }
- return RewriteResponse( status, ret );
}
- return RewriteResponse(REWRITE_DONE, in);
+ //print if changed
+ if( in!=ret ){
+ Trace("quantifiers-rewrite") << "*** rewrite (op=" << rew_op << ") " << in << std::endl;
+ Trace("quantifiers-rewrite") << " to " << std::endl;
+ Trace("quantifiers-rewrite") << ret << std::endl;
+ }
+ return RewriteResponse( status, ret );
}
Node QuantifiersRewriter::computeElimSymbols( Node body ) {
@@ -315,6 +311,10 @@ Node QuantifiersRewriter::computeElimSymbols( Node body ) {
}
childrenChanged = childrenChanged || c!=body[i];
}
+ //if( body.getKind()==ITE && isLiteral( body[0] ) ){
+ // ret = NodeManager::currentNM()->mkNode( AND, NodeManager::currentNM()->mkNode( OR, body[0].negate(), body[1] ),
+ // NodeManager::currentNM()->mkNode( OR, body[0], body[2] ) );
+ //}
if( childrenChanged ){
return ( children.size()==1 && k!=NOT ) ? children[0] : NodeManager::currentNM()->mkNode( k, children );
}else{
@@ -330,7 +330,7 @@ Node QuantifiersRewriter::computeNNF( Node body ){
}else if( isLiteral( body[0] ) ){
return body;
}else{
- std::vector< Node > children;
+ std::vector< Node > children;
Kind k = body[0].getKind();
if( body[0].getKind()==OR || body[0].getKind()==AND ){
@@ -564,12 +564,23 @@ void setEntailedCond( Node n, bool pol, std::map< Node, bool >& currCond, std::v
}
}
-Node QuantifiersRewriter::computeProcessTerms( Node body, std::vector< Node >& new_vars, std::vector< Node >& new_conds, Node q ){
+void removeEntailedCond( std::map< Node, bool >& currCond, std::vector< Node >& new_cond, std::map< Node, Node >& cache ) {
+ if( !new_cond.empty() ){
+ for( unsigned j=0; j<new_cond.size(); j++ ){
+ currCond.erase( new_cond[j] );
+ }
+ new_cond.clear();
+ cache.clear();
+ }
+}
+
+Node QuantifiersRewriter::computeProcessTerms( Node body, std::vector< Node >& new_vars, std::vector< Node >& new_conds, Node q, QAttributes& qa ){
std::map< Node, bool > curr_cond;
std::map< Node, Node > cache;
std::map< Node, Node > icache;
- Node h = TermDb::getFunDefHead( q );
- if( !h.isNull() ){
+ if( qa.isFunDef() ){
+ Node h = TermDb::getFunDefHead( q );
+ Assert( !h.isNull() );
// if it is a function definition, rewrite the body independently
Node fbody = TermDb::getFunDefBody( q );
Assert( !body.isNull() );
@@ -591,96 +602,119 @@ Node QuantifiersRewriter::computeProcessTerms2( Node body, bool hasPol, bool pol
ret = iti->second;
Trace("quantifiers-rewrite-term-debug2") << "Return (cached) " << ret << " for " << body << std::endl;
}else{
- bool firstTimeCD = true;
+ //only do context dependent processing up to depth 8
+ bool doCD = nCurrCond<8;
bool changed = false;
std::vector< Node > children;
- for( size_t i=0; i<body.getNumChildren(); i++ ){
- std::vector< Node > new_cond;
+ //set entailed conditions based on OR/AND
+ std::map< int, std::vector< Node > > new_cond_children;
+ if( doCD && ( body.getKind()==OR || body.getKind()==AND ) ){
+ nCurrCond = nCurrCond + 1;
bool conflict = false;
- //only do context dependent processing up to depth 8
- if( nCurrCond<8 ){
- if( firstTimeCD ){
- firstTimeCD = false;
- nCurrCond = nCurrCond + 1;
- }
- if( Trace.isOn("quantifiers-rewrite-term-debug") ){
- //if( ( body.getKind()==ITE && i>0 ) || ( hasPol && ( ( body.getKind()==OR && pol ) || (body.getKind()==AND && !pol ) ) ) ){
- if( ( body.getKind()==ITE && i>0 ) || body.getKind()==OR || body.getKind()==AND ){
- Trace("quantifiers-rewrite-term-debug") << "---rewrite " << body[i] << " under conditions:----" << std::endl;
+ bool use_pol = body.getKind()==AND;
+ for( unsigned j=0; j<body.getNumChildren(); j++ ){
+ setEntailedCond( body[j], use_pol, currCond, new_cond_children[j], conflict );
+ }
+ if( conflict ){
+ Trace("quantifiers-rewrite-term-debug") << "-------conflict, return " << !use_pol << std::endl;
+ ret = NodeManager::currentNM()->mkConst( !use_pol );
+ }
+ }
+ if( ret.isNull() ){
+ for( size_t i=0; i<body.getNumChildren(); i++ ){
+
+ //set/update entailed conditions
+ std::vector< Node > new_cond;
+ bool conflict = false;
+ if( doCD ){
+ if( Trace.isOn("quantifiers-rewrite-term-debug") ){
+ if( ( body.getKind()==ITE && i>0 ) || body.getKind()==OR || body.getKind()==AND ){
+ Trace("quantifiers-rewrite-term-debug") << "---rewrite " << body[i] << " under conditions:----" << std::endl;
+ }
}
- }
- if( body.getKind()==ITE && i>0 ){
- setEntailedCond( children[0], i==1, currCond, new_cond, conflict );
- //should not conflict (entailment check failed)
- Assert( !conflict );
- }
- //if( hasPol && ( ( body.getKind()==OR && pol ) || ( body.getKind()==AND && !pol ) ) ){
- // bool use_pol = !pol;
- if( body.getKind()==OR || body.getKind()==AND ){
- bool use_pol = body.getKind()==AND;
- for( unsigned j=0; j<body.getNumChildren(); j++ ){
- if( j<i ){
- setEntailedCond( children[j], use_pol, currCond, new_cond, conflict );
- }else if( j>i ){
- setEntailedCond( body[j], use_pol, currCond, new_cond, conflict );
+ if( body.getKind()==ITE && i>0 ){
+ if( i==1 ){
+ nCurrCond = nCurrCond + 1;
}
+ setEntailedCond( children[0], i==1, currCond, new_cond, conflict );
+ //should not conflict (entailment check failed)
+ Assert( !conflict );
}
- if( conflict ){
- Trace("quantifiers-rewrite-term-debug") << "-------conflict, return " << !use_pol << std::endl;
- ret = NodeManager::currentNM()->mkConst( !use_pol );
+ if( body.getKind()==OR || body.getKind()==AND ){
+ bool use_pol = body.getKind()==AND;
+ //remove the current condition
+ removeEntailedCond( currCond, new_cond_children[i], cache );
+ if( i>0 ){
+ //add the previous condition
+ setEntailedCond( children[i-1], use_pol, currCond, new_cond_children[i-1], conflict );
+ }
+ if( conflict ){
+ Trace("quantifiers-rewrite-term-debug") << "-------conflict, return " << !use_pol << std::endl;
+ ret = NodeManager::currentNM()->mkConst( !use_pol );
+ }
}
- }
- if( !new_cond.empty() ){
- cache.clear();
- }
- if( Trace.isOn("quantifiers-rewrite-term-debug") ){
- //if( ( body.getKind()==ITE && i>0 ) || ( hasPol && ( ( body.getKind()==OR && pol ) || (body.getKind()==AND && !pol ) ) ) ){
- if( ( body.getKind()==ITE && i>0 ) || body.getKind()==OR || body.getKind()==AND ){
- Trace("quantifiers-rewrite-term-debug") << "-------" << std::endl;
+ if( !new_cond.empty() ){
+ cache.clear();
+ }
+ if( Trace.isOn("quantifiers-rewrite-term-debug") ){
+ if( ( body.getKind()==ITE && i>0 ) || body.getKind()==OR || body.getKind()==AND ){
+ Trace("quantifiers-rewrite-term-debug") << "-------" << std::endl;
+ }
}
}
- }
- if( !conflict ){
- bool newHasPol;
- bool newPol;
- QuantPhaseReq::getPolarity( body, i, hasPol, pol, newHasPol, newPol );
- Node nn = computeProcessTerms2( body[i], newHasPol, newPol, currCond, nCurrCond, cache, icache, new_vars, new_conds );
- if( body.getKind()==ITE && i==0 ){
- int res = getEntailedCond( nn, currCond );
- Trace("quantifiers-rewrite-term-debug") << "Condition for " << body << " is " << nn << ", entailment check=" << res << std::endl;
- if( res==1 ){
- ret = computeProcessTerms2( body[1], hasPol, pol, currCond, nCurrCond, cache, icache, new_vars, new_conds );
- }else if( res==-1 ){
- ret = computeProcessTerms2( body[2], hasPol, pol, currCond, nCurrCond, cache, icache, new_vars, new_conds );
+
+ //do the recursive call on children
+ if( !conflict ){
+ bool newHasPol;
+ bool newPol;
+ QuantPhaseReq::getPolarity( body, i, hasPol, pol, newHasPol, newPol );
+ Node nn = computeProcessTerms2( body[i], newHasPol, newPol, currCond, nCurrCond, cache, icache, new_vars, new_conds );
+ if( body.getKind()==ITE && i==0 ){
+ int res = getEntailedCond( nn, currCond );
+ Trace("quantifiers-rewrite-term-debug") << "Condition for " << body << " is " << nn << ", entailment check=" << res << std::endl;
+ if( res==1 ){
+ ret = computeProcessTerms2( body[1], hasPol, pol, currCond, nCurrCond, cache, icache, new_vars, new_conds );
+ }else if( res==-1 ){
+ ret = computeProcessTerms2( body[2], hasPol, pol, currCond, nCurrCond, cache, icache, new_vars, new_conds );
+ }
}
+ children.push_back( nn );
+ changed = changed || nn!=body[i];
+ }
+
+ //clean up entailed conditions
+ removeEntailedCond( currCond, new_cond, cache );
+
+ if( !ret.isNull() ){
+ break;
}
- children.push_back( nn );
- changed = changed || nn!=body[i];
}
- if( !new_cond.empty() ){
- for( unsigned j=0; j<new_cond.size(); j++ ){
- currCond.erase( new_cond[j] );
+
+ //make return value
+ if( ret.isNull() ){
+ if( changed ){
+ if( body.getMetaKind() == kind::metakind::PARAMETERIZED ){
+ children.insert( children.begin(), body.getOperator() );
+ }
+ ret = NodeManager::currentNM()->mkNode( body.getKind(), children );
+ }else{
+ ret = body;
}
- cache.clear();
- }
- if( !ret.isNull() ){
- break;
}
}
- if( ret.isNull() ){
- if( changed ){
- if( body.getMetaKind() == kind::metakind::PARAMETERIZED ){
- children.insert( children.begin(), body.getOperator() );
- }
- ret = NodeManager::currentNM()->mkNode( body.getKind(), children );
- }else{
- ret = body;
+
+ //clean up entailed conditions
+ if( body.getKind()==OR || body.getKind()==AND ){
+ for( unsigned j=0; j<body.getNumChildren(); j++ ){
+ removeEntailedCond( currCond, new_cond_children[j], cache );
}
}
+
Trace("quantifiers-rewrite-term-debug2") << "Returning " << ret << " for " << body << std::endl;
cache[body] = ret;
}
+ //do context-independent rewriting
iti = icache.find( ret );
if( iti!=icache.end() ){
return iti->second;
@@ -710,46 +744,60 @@ Node QuantifiersRewriter::computeProcessTerms2( Node body, bool hasPol, bool pol
}
}
}
- }else if( ret.getKind()==INTS_DIVISION_TOTAL || ret.getKind()==INTS_MODULUS_TOTAL ){
- Node num = ret[0];
- Node den = ret[1];
- if(den.isConst()) {
- const Rational& rat = den.getConst<Rational>();
- Assert(!num.isConst());
- if(rat != 0) {
- Node intVar = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());
- new_vars.push_back( intVar );
- Node cond;
- if(rat > 0) {
- cond = NodeManager::currentNM()->mkNode(kind::AND,
- NodeManager::currentNM()->mkNode(kind::LEQ, NodeManager::currentNM()->mkNode(kind::MULT, den, intVar), num),
- NodeManager::currentNM()->mkNode(kind::LT, num,
- NodeManager::currentNM()->mkNode(kind::MULT, den, NodeManager::currentNM()->mkNode(kind::PLUS, intVar, NodeManager::currentNM()->mkConst(Rational(1))))));
- } else {
- cond = NodeManager::currentNM()->mkNode(kind::AND,
- NodeManager::currentNM()->mkNode(kind::LEQ, NodeManager::currentNM()->mkNode(kind::MULT, den, intVar), num),
- NodeManager::currentNM()->mkNode(kind::LT, num,
- NodeManager::currentNM()->mkNode(kind::MULT, den, NodeManager::currentNM()->mkNode(kind::PLUS, intVar, NodeManager::currentNM()->mkConst(Rational(-1))))));
- }
- new_conds.push_back( cond.negate() );
- if( ret.getKind()==INTS_DIVISION_TOTAL ){
- ret = intVar;
- }else{
- ret = NodeManager::currentNM()->mkNode(kind::MINUS, num, NodeManager::currentNM()->mkNode(kind::MULT, den, intVar));
+ /* ITE lifting
+ if( ret.getKind()==ITE ){
+ TypeNode ite_t = ret[1].getType();
+ if( !ite_t.isBoolean() ){
+ ite_t = TypeNode::leastCommonTypeNode( ite_t, ret[2].getType() );
+ Node ite_v = NodeManager::currentNM()->mkBoundVar(ite_t);
+ new_vars.push_back( ite_v );
+ Node cond = NodeManager::currentNM()->mkNode(kind::ITE, ret[0], ite_v.eqNode( ret[1] ), ite_v.eqNode( ret[2] ) );
+ new_conds.push_back( cond.negate() );
+ ret = ite_v;
+ }
+ */
+ }else if( options::elimExtArithQuant() ){
+ if( ret.getKind()==INTS_DIVISION_TOTAL || ret.getKind()==INTS_MODULUS_TOTAL ){
+ Node num = ret[0];
+ Node den = ret[1];
+ if(den.isConst()) {
+ const Rational& rat = den.getConst<Rational>();
+ Assert(!num.isConst());
+ if(rat != 0) {
+ Node intVar = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());
+ new_vars.push_back( intVar );
+ Node cond;
+ if(rat > 0) {
+ cond = NodeManager::currentNM()->mkNode(kind::AND,
+ NodeManager::currentNM()->mkNode(kind::LEQ, NodeManager::currentNM()->mkNode(kind::MULT, den, intVar), num),
+ NodeManager::currentNM()->mkNode(kind::LT, num,
+ NodeManager::currentNM()->mkNode(kind::MULT, den, NodeManager::currentNM()->mkNode(kind::PLUS, intVar, NodeManager::currentNM()->mkConst(Rational(1))))));
+ } else {
+ cond = NodeManager::currentNM()->mkNode(kind::AND,
+ NodeManager::currentNM()->mkNode(kind::LEQ, NodeManager::currentNM()->mkNode(kind::MULT, den, intVar), num),
+ NodeManager::currentNM()->mkNode(kind::LT, num,
+ NodeManager::currentNM()->mkNode(kind::MULT, den, NodeManager::currentNM()->mkNode(kind::PLUS, intVar, NodeManager::currentNM()->mkConst(Rational(-1))))));
+ }
+ new_conds.push_back( cond.negate() );
+ if( ret.getKind()==INTS_DIVISION_TOTAL ){
+ ret = intVar;
+ }else{
+ ret = NodeManager::currentNM()->mkNode(kind::MINUS, num, NodeManager::currentNM()->mkNode(kind::MULT, den, intVar));
+ }
}
}
- }
- }else if( ret.getKind()==TO_INTEGER || ret.getKind()==IS_INTEGER ){
- Node intVar = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());
- new_vars.push_back( intVar );
- new_conds.push_back(NodeManager::currentNM()->mkNode(kind::AND,
- NodeManager::currentNM()->mkNode(kind::LT,
- NodeManager::currentNM()->mkNode(kind::MINUS, ret[0], NodeManager::currentNM()->mkConst(Rational(1))), intVar),
- NodeManager::currentNM()->mkNode(kind::LEQ, intVar, ret[0])).negate());
- if( ret.getKind()==TO_INTEGER ){
- ret = intVar;
- }else{
- ret = ret[0].eqNode( intVar );
+ }else if( ret.getKind()==TO_INTEGER || ret.getKind()==IS_INTEGER ){
+ Node intVar = NodeManager::currentNM()->mkBoundVar(NodeManager::currentNM()->integerType());
+ new_vars.push_back( intVar );
+ new_conds.push_back(NodeManager::currentNM()->mkNode(kind::AND,
+ NodeManager::currentNM()->mkNode(kind::LT,
+ NodeManager::currentNM()->mkNode(kind::MINUS, ret[0], NodeManager::currentNM()->mkConst(Rational(1))), intVar),
+ NodeManager::currentNM()->mkNode(kind::LEQ, intVar, ret[0])).negate());
+ if( ret.getKind()==TO_INTEGER ){
+ ret = intVar;
+ }else{
+ ret = ret[0].eqNode( intVar );
+ }
}
}
icache[prev] = ret;
@@ -782,7 +830,7 @@ bool QuantifiersRewriter::isConditionalVariableElim( Node n, int pol ){
return false;
}
-Node QuantifiersRewriter::computeCondSplit( Node body, Node ipl ){
+Node QuantifiersRewriter::computeCondSplit( Node body, QAttributes& qa ){
if( options::iteDtTesterSplitQuant() && body.getKind()==ITE ){
Trace("quantifiers-rewrite-ite-debug") << "DTT split : " << body << std::endl;
std::map< Node, Node > pcons;
@@ -799,7 +847,8 @@ Node QuantifiersRewriter::computeCondSplit( Node body, Node ipl ){
}
}
if( options::condVarSplitQuant() ){
- if( body.getKind()==ITE || ( body.getKind()==IFF && options::condVarSplitQuantAgg() && !TermDb::isFunDefAnnotation( ipl ) ) ){
+ if( body.getKind()==ITE || ( body.getKind()==IFF && options::condVarSplitQuantAgg() ) ){
+ Assert( !qa.isFunDef() );
Trace("quantifiers-rewrite-debug") << "Conditional var elim split " << body << "?" << std::endl;
bool do_split = false;
unsigned index_max = body.getKind()==ITE ? 0 : 1;
@@ -932,8 +981,7 @@ bool QuantifiersRewriter::computeVariableElimLit( Node lit, bool pol, std::vecto
newChildren.push_back( Node::fromExpr( c.getConstructor() ) );
std::vector< Node > newVars;
for( unsigned j=0; j<c.getNumArgs(); j++ ){
- TypeNode tn = TypeNode::fromType( c[j].getSelector().getType() );
- tn = tn[1];
+ TypeNode tn = TypeNode::fromType( c[j].getRangeType() );
Node v = NodeManager::currentNM()->mkBoundVar( tn );
newChildren.push_back( v );
newVars.push_back( v );
@@ -957,7 +1005,7 @@ bool QuantifiersRewriter::computeVariableElimLit( Node lit, bool pol, std::vecto
return false;
}
-Node QuantifiersRewriter::computeVarElimination2( Node body, std::vector< Node >& args, Node& ipl, std::map< Node, std::vector< int > >& var_parent ){
+Node QuantifiersRewriter::computeVarElimination2( Node body, std::vector< Node >& args, QAttributes& qa, std::map< Node, std::vector< int > >& var_parent ){
Trace("var-elim-quant-debug") << "Compute var elimination for " << body << std::endl;
QuantPhaseReq qpr( body );
std::vector< Node > vars;
@@ -977,15 +1025,15 @@ Node QuantifiersRewriter::computeVarElimination2( Node body, std::vector< Node >
//remake with eliminated nodes
body = body.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
body = Rewriter::rewrite( body );
- if( !ipl.isNull() ){
- ipl = ipl.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
+ if( !qa.d_ipl.isNull() ){
+ qa.d_ipl = qa.d_ipl.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
}
Trace("var-elim-quant") << "Return " << body << std::endl;
}
return body;
}
-Node QuantifiersRewriter::computeVarElimination( Node body, std::vector< Node >& args, Node& ipl ){
+Node QuantifiersRewriter::computeVarElimination( Node body, std::vector< Node >& args, QAttributes& qa ){
//the parent id's for each variable, if using purifyQuant
std::map< Node, std::vector< int > > var_parent;
if( options::purifyQuant() ){
@@ -995,7 +1043,7 @@ Node QuantifiersRewriter::computeVarElimination( Node body, std::vector< Node >&
Node prev;
do{
prev = body;
- body = computeVarElimination2( body, args, ipl, var_parent );
+ body = computeVarElimination2( body, args, qa, var_parent );
}while( prev!=body && !args.empty() );
}
return body;
@@ -1290,13 +1338,13 @@ Node QuantifiersRewriter::computeSplit( Node f, std::vector< Node >& args, Node
return f;
}
-Node QuantifiersRewriter::mkForAll( std::vector< Node >& args, Node body, Node ipl ){
+Node QuantifiersRewriter::mkForAll( std::vector< Node >& args, Node body, QAttributes& qa ){
std::vector< Node > activeArgs;
//if cegqi is on, may be synthesis conjecture, in which case we want to keep all variables
- if( options::ceGuidedInst() && TermDb::isSygusConjectureAnnotation( ipl ) ){
+ if( options::ceGuidedInst() && qa.d_sygus ){
activeArgs.insert( activeArgs.end(), args.begin(), args.end() );
}else{
- computeArgVec2( args, activeArgs, body, ipl );
+ computeArgVec2( args, activeArgs, body, qa.d_ipl );
}
if( activeArgs.empty() ){
return body;
@@ -1304,14 +1352,14 @@ Node QuantifiersRewriter::mkForAll( std::vector< Node >& args, Node body, Node i
std::vector< Node > children;
children.push_back( NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, activeArgs ) );
children.push_back( body );
- if( !ipl.isNull() ){
- children.push_back( ipl );
+ if( !qa.d_ipl.isNull() ){
+ children.push_back( qa.d_ipl );
}
return NodeManager::currentNM()->mkNode( kind::FORALL, children );
}
}
-Node QuantifiersRewriter::computeMiniscoping( Node f, std::vector< Node >& args, Node body, Node ipl ){
+Node QuantifiersRewriter::computeMiniscoping( Node f, std::vector< Node >& args, Node body, QAttributes& qa ){
if( body.getKind()==FORALL ){
//combine arguments
std::vector< Node > newArgs;
@@ -1319,26 +1367,26 @@ Node QuantifiersRewriter::computeMiniscoping( Node f, std::vector< Node >& args,
newArgs.push_back( body[0][i] );
}
newArgs.insert( newArgs.end(), args.begin(), args.end() );
- return mkForAll( newArgs, body[ 1 ], ipl );
+ return mkForAll( newArgs, body[ 1 ], qa );
}else{
if( body.getKind()==NOT ){
//push not downwards
if( body[0].getKind()==NOT ){
- return computeMiniscoping( f, args, body[0][0], ipl );
+ return computeMiniscoping( f, args, body[0][0], qa );
}else if( body[0].getKind()==AND ){
if( options::miniscopeQuantFreeVar() ){
NodeBuilder<> t(kind::OR);
for( int i=0; i<(int)body[0].getNumChildren(); i++ ){
t << ( body[0][i].getKind()==NOT ? body[0][i][0] : body[0][i].notNode() );
}
- return computeMiniscoping( f, args, t.constructNode(), ipl );
+ return computeMiniscoping( f, args, t.constructNode(), qa );
}
}else if( body[0].getKind()==OR ){
if( options::miniscopeQuant() ){
NodeBuilder<> t(kind::AND);
for( int i=0; i<(int)body[0].getNumChildren(); i++ ){
Node trm = body[0][i].negate();
- t << computeMiniscoping( f, args, trm, ipl );
+ t << computeMiniscoping( f, args, trm, qa );
}
return t.constructNode();
}
@@ -1348,7 +1396,7 @@ Node QuantifiersRewriter::computeMiniscoping( Node f, std::vector< Node >& args,
//break apart
NodeBuilder<> t(kind::AND);
for( unsigned i=0; i<body.getNumChildren(); i++ ){
- t << computeMiniscoping( f, args, body[i], ipl );
+ t << computeMiniscoping( f, args, body[i], qa );
}
Node retVal = t;
return retVal;
@@ -1376,7 +1424,7 @@ Node QuantifiersRewriter::computeMiniscoping( Node f, std::vector< Node >& args,
return body_split;
}else if( body_split.getNumChildren()>0 ){
newBody = tb.getNumChildren()==1 ? tb.getChild( 0 ) : tb;
- body_split << mkForAll( args, newBody, ipl );
+ body_split << mkForAll( args, newBody, qa );
return body_split.getNumChildren()==1 ? body_split.getChild( 0 ) : body_split;
}
}
@@ -1385,7 +1433,7 @@ Node QuantifiersRewriter::computeMiniscoping( Node f, std::vector< Node >& args,
//if( body==f[1] ){
// return f;
//}else{
- return mkForAll( args, body, ipl );
+ return mkForAll( args, body, qa );
//}
}
@@ -1491,101 +1539,96 @@ Node QuantifiersRewriter::computeAggressiveMiniscoping( std::vector< Node >& arg
return n;
}
}
- return mkForAll( args, body, Node::null() );
+ QAttributes qa;
+ return mkForAll( args, body, qa );
}
-bool QuantifiersRewriter::doOperation( Node f, bool isNested, int computeOption ){
+bool QuantifiersRewriter::doOperation( Node q, int computeOption, QAttributes& qa ){
+ bool is_strict_trigger = qa.d_hasPattern && options::userPatternsQuant()==USER_PAT_MODE_TRUST;
+ bool is_std = !qa.d_sygus && !qa.d_quant_elim && !qa.isFunDef() && !is_strict_trigger;
if( computeOption==COMPUTE_ELIM_SYMBOLS ){
return true;
}else if( computeOption==COMPUTE_MINISCOPING ){
- return true;
+ return is_std;
}else if( computeOption==COMPUTE_AGGRESSIVE_MINISCOPING ){
- return options::aggressiveMiniscopeQuant();
+ return options::aggressiveMiniscopeQuant() && is_std;
}else if( computeOption==COMPUTE_NNF ){
- return options::nnfQuant();
+ return true;
}else if( computeOption==COMPUTE_PROCESS_TERMS ){
return true;
//return options::iteLiftQuant()!=ITE_LIFT_QUANT_MODE_NONE || options::iteCondVarSplitQuant();
}else if( computeOption==COMPUTE_COND_SPLIT ){
- return options::iteDtTesterSplitQuant() || options::condVarSplitQuant();
+ return ( options::iteDtTesterSplitQuant() || options::condVarSplitQuant() ) && !is_strict_trigger;
}else if( computeOption==COMPUTE_PRENEX ){
- return options::prenexQuant()!=PRENEX_NONE && !options::aggressiveMiniscopeQuant();
+ return options::prenexQuant()!=PRENEX_NONE && !options::aggressiveMiniscopeQuant() && is_std;
}else if( computeOption==COMPUTE_VAR_ELIMINATION ){
- return options::varElimQuant() || options::dtVarExpandQuant() || options::purifyQuant();
+ return ( options::varElimQuant() || options::dtVarExpandQuant() || options::purifyQuant() ) && is_std;
//}else if( computeOption==COMPUTE_CNF ){
// return options::cnfQuant();
}else if( computeOption==COMPUTE_PURIFY_EXPAND ){
- return options::purifyQuant();
+ return options::purifyQuant() && is_std;
}else{
return false;
}
}
//general method for computing various rewrites
-Node QuantifiersRewriter::computeOperation( Node f, bool isNested, int computeOption ){
- if( f.getKind()==FORALL ){
- Trace("quantifiers-rewrite-debug") << "Compute operation " << computeOption << " on " << f << ", nested = " << isNested << std::endl;
- std::vector< Node > args;
- for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
- args.push_back( f[0][i] );
- }
- Node n = f[1];
- Node ipl;
- if( f.getNumChildren()==3 ){
- ipl = f[2];
- }
- if( computeOption==COMPUTE_ELIM_SYMBOLS ){
- n = computeElimSymbols( n );
- }else if( computeOption==COMPUTE_MINISCOPING ){
- //return directly
- return computeMiniscoping( f, args, n, ipl );
- }else if( computeOption==COMPUTE_AGGRESSIVE_MINISCOPING ){
- return computeAggressiveMiniscoping( args, n );
- }else if( computeOption==COMPUTE_NNF ){
- n = computeNNF( n );
- }else if( computeOption==COMPUTE_PROCESS_TERMS ){
- std::vector< Node > new_conds;
- n = computeProcessTerms( n, args, new_conds, f );
- if( !new_conds.empty() ){
- new_conds.push_back( n );
- n = NodeManager::currentNM()->mkNode( OR, new_conds );
- }
- }else if( computeOption==COMPUTE_COND_SPLIT ){
- n = computeCondSplit( n, ipl );
- }else if( computeOption==COMPUTE_PRENEX ){
- n = computePrenex( n, args, true );
- }else if( computeOption==COMPUTE_VAR_ELIMINATION ){
- n = computeVarElimination( n, args, ipl );
- //}else if( computeOption==COMPUTE_CNF ){
- //n = computeCNF( n, args, defs, false );
- //ipl = Node::null();
- }else if( computeOption==COMPUTE_PURIFY_EXPAND ){
- std::vector< Node > conj;
- computePurifyExpand( n, conj, args, ipl );
- if( !conj.empty() ){
- return conj.size()==1 ? conj[0] : NodeManager::currentNM()->mkNode( AND, conj );
- }else{
- return f;
- }
+Node QuantifiersRewriter::computeOperation( Node f, int computeOption, QAttributes& qa ){
+ Trace("quantifiers-rewrite-debug") << "Compute operation " << computeOption << " on " << f << std::endl;
+ std::vector< Node > args;
+ for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
+ args.push_back( f[0][i] );
+ }
+ Node n = f[1];
+ if( computeOption==COMPUTE_ELIM_SYMBOLS ){
+ n = computeElimSymbols( n );
+ }else if( computeOption==COMPUTE_MINISCOPING ){
+ //return directly
+ return computeMiniscoping( f, args, n, qa );
+ }else if( computeOption==COMPUTE_AGGRESSIVE_MINISCOPING ){
+ return computeAggressiveMiniscoping( args, n );
+ }else if( computeOption==COMPUTE_NNF ){
+ n = computeNNF( n );
+ }else if( computeOption==COMPUTE_PROCESS_TERMS ){
+ std::vector< Node > new_conds;
+ n = computeProcessTerms( n, args, new_conds, f, qa );
+ if( !new_conds.empty() ){
+ new_conds.push_back( n );
+ n = NodeManager::currentNM()->mkNode( OR, new_conds );
}
- Trace("quantifiers-rewrite-debug") << "Compute Operation: return " << n << ", " << args.size() << std::endl;
- if( f[1]==n && args.size()==f[0].getNumChildren() ){
+ }else if( computeOption==COMPUTE_COND_SPLIT ){
+ n = computeCondSplit( n, qa );
+ }else if( computeOption==COMPUTE_PRENEX ){
+ n = computePrenex( n, args, true );
+ }else if( computeOption==COMPUTE_VAR_ELIMINATION ){
+ n = computeVarElimination( n, args, qa );
+ //}else if( computeOption==COMPUTE_CNF ){
+ //n = computeCNF( n, args, defs, false );
+ //ipl = Node::null();
+ }else if( computeOption==COMPUTE_PURIFY_EXPAND ){
+ std::vector< Node > conj;
+ computePurifyExpand( n, conj, args, qa );
+ if( !conj.empty() ){
+ return conj.size()==1 ? conj[0] : NodeManager::currentNM()->mkNode( AND, conj );
+ }else{
return f;
+ }
+ }
+ Trace("quantifiers-rewrite-debug") << "Compute Operation: return " << n << ", " << args.size() << std::endl;
+ if( f[1]==n && args.size()==f[0].getNumChildren() ){
+ return f;
+ }else{
+ if( args.empty() ){
+ return n;
}else{
- if( args.empty() ){
- return n;
- }else{
- std::vector< Node > children;
- children.push_back( NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, args ) );
- children.push_back( n );
- if( !ipl.isNull() ){
- children.push_back( ipl );
- }
- return NodeManager::currentNM()->mkNode(kind::FORALL, children );
+ std::vector< Node > children;
+ children.push_back( NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, args ) );
+ children.push_back( n );
+ if( !qa.d_ipl.isNull() && args.size()==f[0].getNumChildren() ){
+ children.push_back( qa.d_ipl );
}
+ return NodeManager::currentNM()->mkNode(kind::FORALL, children );
}
- }else{
- return f;
}
}
@@ -1754,31 +1797,29 @@ Node QuantifiersRewriter::preSkolemizeQuantifiers( Node n, bool polarity, std::v
//check if it contains a quantifier as a subterm
//if so, we will write this node
if( containsQuantifiers( n ) ){
- if( n.getType().isBoolean() ){
- if( n.getKind()==kind::ITE || n.getKind()==kind::IFF || n.getKind()==kind::XOR || n.getKind()==kind::IMPLIES ){
- if( options::preSkolemQuantAgg() ){
- Node nn;
- //must remove structure
- if( n.getKind()==kind::ITE ){
- nn = NodeManager::currentNM()->mkNode( kind::AND,
- NodeManager::currentNM()->mkNode( kind::OR, n[0].notNode(), n[1] ),
- NodeManager::currentNM()->mkNode( kind::OR, n[0], n[2] ) );
- }else if( n.getKind()==kind::IFF || n.getKind()==kind::XOR ){
- nn = NodeManager::currentNM()->mkNode( kind::AND,
- NodeManager::currentNM()->mkNode( kind::OR, n[0].notNode(), n.getKind()==kind::XOR ? n[1].notNode() : n[1] ),
- NodeManager::currentNM()->mkNode( kind::OR, n[0], n.getKind()==kind::XOR ? n[1] : n[1].notNode() ) );
- }else if( n.getKind()==kind::IMPLIES ){
- nn = NodeManager::currentNM()->mkNode( kind::OR, n[0].notNode(), n[1] );
- }
- return preSkolemizeQuantifiers( nn, polarity, fvTypes, fvs );
- }
- }else if( n.getKind()==kind::AND || n.getKind()==kind::OR ){
- vector< Node > children;
- for( int i=0; i<(int)n.getNumChildren(); i++ ){
- children.push_back( preSkolemizeQuantifiers( n[i], polarity, fvTypes, fvs ) );
+ if( ( n.getKind()==kind::ITE && n.getType().isBoolean() ) || n.getKind()==kind::IFF ){
+ if( options::preSkolemQuantAgg() ){
+ Node nn;
+ //must remove structure
+ if( n.getKind()==kind::ITE ){
+ nn = NodeManager::currentNM()->mkNode( kind::AND,
+ NodeManager::currentNM()->mkNode( kind::OR, n[0].notNode(), n[1] ),
+ NodeManager::currentNM()->mkNode( kind::OR, n[0], n[2] ) );
+ }else if( n.getKind()==kind::IFF || n.getKind()==kind::XOR ){
+ nn = NodeManager::currentNM()->mkNode( kind::AND,
+ NodeManager::currentNM()->mkNode( kind::OR, n[0].notNode(), n.getKind()==kind::XOR ? n[1].notNode() : n[1] ),
+ NodeManager::currentNM()->mkNode( kind::OR, n[0], n.getKind()==kind::XOR ? n[1] : n[1].notNode() ) );
+ }else if( n.getKind()==kind::IMPLIES ){
+ nn = NodeManager::currentNM()->mkNode( kind::OR, n[0].notNode(), n[1] );
}
- return NodeManager::currentNM()->mkNode( n.getKind(), children );
+ return preSkolemizeQuantifiers( nn, polarity, fvTypes, fvs );
}
+ }else if( n.getKind()==kind::AND || n.getKind()==kind::OR ){
+ vector< Node > children;
+ for( int i=0; i<(int)n.getNumChildren(); i++ ){
+ children.push_back( preSkolemizeQuantifiers( n[i], polarity, fvTypes, fvs ) );
+ }
+ return NodeManager::currentNM()->mkNode( n.getKind(), children );
}
}
}
@@ -1786,15 +1827,20 @@ Node QuantifiersRewriter::preSkolemizeQuantifiers( Node n, bool polarity, std::v
}
Node QuantifiersRewriter::preprocess( Node n, bool isInst ) {
+ Node prev = n;
if( options::preSkolemQuant() ){
if( !isInst || !options::preSkolemQuantNested() ){
- //apply pre-skolemization to existential quantifiers
Trace("quantifiers-preprocess-debug") << "Pre-skolemize " << n << "..." << std::endl;
+ //apply pre-skolemization to existential quantifiers
std::vector< TypeNode > fvTypes;
std::vector< TNode > fvs;
- n = quantifiers::QuantifiersRewriter::preSkolemizeQuantifiers( n, true, fvTypes, fvs );
+ n = quantifiers::QuantifiersRewriter::preSkolemizeQuantifiers( prev, true, fvTypes, fvs );
}
}
+ if( n!=prev ){
+ Trace("quantifiers-preprocess") << "Preprocess " << prev<< std::endl;
+ Trace("quantifiers-preprocess") << "..returned " << n << std::endl;
+ }
return n;
}
@@ -1886,7 +1932,7 @@ Node QuantifiersRewriter::computePurify( Node body, std::vector< Node >& args, s
}
}
-void QuantifiersRewriter::computePurifyExpand( Node body, std::vector< Node >& conj, std::vector< Node >& args, Node ipl ) {
+void QuantifiersRewriter::computePurifyExpand( Node body, std::vector< Node >& conj, std::vector< Node >& args, QAttributes& qa ) {
if( body.getKind()==OR ){
Trace("quantifiers-rewrite-purify-exp") << "Purify expansion : " << body << std::endl;
std::map< int, std::vector< Node > > disj;
diff --git a/src/theory/quantifiers/quantifiers_rewriter.h b/src/theory/quantifiers/quantifiers_rewriter.h
index 47997f9a7..2071d1793 100644
--- a/src/theory/quantifiers/quantifiers_rewriter.h
+++ b/src/theory/quantifiers/quantifiers_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_rewriter.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter for the theory of inductive quantifiers
**
@@ -26,6 +26,8 @@ namespace CVC4 {
namespace theory {
namespace quantifiers {
+class QAttributes;
+
class QuantifiersRewriter {
private:
static int getPurifyIdLit2( Node n, std::map< Node, int >& visited );
@@ -37,7 +39,7 @@ public:
static int getPurifyIdLit( Node n );
private:
static void addNodeToOrBuilder( Node n, NodeBuilder<>& t );
- static Node mkForAll( std::vector< Node >& args, Node body, Node ipl );
+ static Node mkForAll( std::vector< Node >& args, Node body, QAttributes& qa );
static void computeArgs( std::vector< Node >& args, std::map< Node, bool >& activeMap, Node n, std::map< Node, bool >& visited );
static void computeArgVec( std::vector< Node >& args, std::vector< Node >& activeArgs, Node n );
static void computeArgVec2( std::vector< Node >& args, std::vector< Node >& activeArgs, Node n, Node ipl );
@@ -52,21 +54,21 @@ private:
std::map< Node, std::vector< int > >& var_parent );
static Node computePurify2( Node body, std::vector< Node >& args, std::map< Node, Node >& visited, std::map< Node, Node >& var_to_term,
std::map< Node, std::vector< int > >& var_parent, int parentId );
- static Node computeVarElimination2( Node body, std::vector< Node >& args, Node& ipl, std::map< Node, std::vector< int > >& var_parent );
+ static Node computeVarElimination2( Node body, std::vector< Node >& args, QAttributes& qa, std::map< Node, std::vector< int > >& var_parent );
private:
static Node computeElimSymbols( Node body );
- static Node computeMiniscoping( Node f, std::vector< Node >& args, Node body, Node ipl );
+ static Node computeMiniscoping( Node f, std::vector< Node >& args, Node body, QAttributes& qa );
static Node computeAggressiveMiniscoping( std::vector< Node >& args, Node body );
static Node computeNNF( Node body );
//cache is dependent upon currCond, icache is not, new_conds are negated conditions
- static Node computeProcessTerms( Node body, std::vector< Node >& new_vars, std::vector< Node >& new_conds, Node q );
- static Node computeCondSplit( Node body, Node ipl );
+ static Node computeProcessTerms( Node body, std::vector< Node >& new_vars, std::vector< Node >& new_conds, Node q, QAttributes& qa );
+ static Node computeCondSplit( Node body, QAttributes& qa );
static Node computeCNF( Node body, std::vector< Node >& args, NodeBuilder<>& defs, bool forcePred );
static Node computePrenex( Node body, std::vector< Node >& args, bool pol );
static Node computeSplit( Node f, std::vector< Node >& args, Node body );
- static Node computeVarElimination( Node body, std::vector< Node >& args, Node& ipl );
+ static Node computeVarElimination( Node body, std::vector< Node >& args, QAttributes& qa );
static Node computePurify( Node body, std::vector< Node >& args, std::map< Node, std::vector< int > >& var_parent );
- static void computePurifyExpand( Node body, std::vector< Node >& conj, std::vector< Node >& args, Node ipl );
+ static void computePurifyExpand( Node body, std::vector< Node >& conj, std::vector< Node >& args, QAttributes& qa );
private:
enum{
COMPUTE_ELIM_SYMBOLS = 0,
@@ -82,7 +84,7 @@ private:
//COMPUTE_CNF,
COMPUTE_LAST
};
- static Node computeOperation( Node f, bool isNested, int computeOption );
+ static Node computeOperation( Node f, int computeOption, QAttributes& qa );
public:
static RewriteResponse preRewrite(TNode in);
static RewriteResponse postRewrite(TNode in);
@@ -90,7 +92,7 @@ public:
static inline void shutdown() {}
private:
/** options */
- static bool doOperation( Node f, bool isNested, int computeOption );
+ static bool doOperation( Node f, int computeOption, QAttributes& qa );
private:
static Node preSkolemizeQuantifiers(Node n, bool polarity, std::vector< TypeNode >& fvTypes, std::vector<TNode>& fvs);
public:
diff --git a/src/theory/quantifiers/relevant_domain.cpp b/src/theory/quantifiers/relevant_domain.cpp
index 88793358e..b353fce2f 100644
--- a/src/theory/quantifiers/relevant_domain.cpp
+++ b/src/theory/quantifiers/relevant_domain.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file relevant_domain.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of relevant domain class
**/
@@ -82,8 +82,9 @@ RelevantDomain::RDomain * RelevantDomain::getRDomain( Node n, int i, bool getPar
return getParent ? d_rel_doms[n][i]->getParent() : d_rel_doms[n][i];
}
-void RelevantDomain::reset(){
+bool RelevantDomain::reset( Theory::Effort e ) {
d_is_computed = false;
+ return true;
}
void RelevantDomain::compute(){
@@ -94,7 +95,7 @@ void RelevantDomain::compute(){
it2->second->reset();
}
}
- for( int i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
+ for( unsigned i=0; i<d_model->getNumAssertedQuantifiers(); i++ ){
Node q = d_model->getAssertedQuantifier( i );
Node icf = d_qe->getTermDatabase()->getInstConstantBody( q );
Trace("rel-dom-debug") << "compute relevant domain for " << icf << std::endl;
@@ -140,7 +141,7 @@ void RelevantDomain::compute(){
}
void RelevantDomain::computeRelevantDomain( Node q, Node n, bool hasPol, bool pol ) {
- Node op = d_qe->getTermDatabase()->getOperator( n );
+ Node op = d_qe->getTermDatabase()->getMatchOperator( n );
for( unsigned i=0; i<n.getNumChildren(); i++ ){
if( !op.isNull() ){
RDomain * rf = getRDomain( op, i );
diff --git a/src/theory/quantifiers/relevant_domain.h b/src/theory/quantifiers/relevant_domain.h
index 3ce285bc8..2b90520fd 100644
--- a/src/theory/quantifiers/relevant_domain.h
+++ b/src/theory/quantifiers/relevant_domain.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file relevant_domain.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief relevant domain class
**/
@@ -23,7 +23,7 @@ namespace CVC4 {
namespace theory {
namespace quantifiers {
-class RelevantDomain
+class RelevantDomain : public QuantifiersUtil
{
private:
class RDomain
@@ -62,7 +62,10 @@ private:
public:
RelevantDomain( QuantifiersEngine* qe, FirstOrderModel* m );
virtual ~RelevantDomain(){}
- void reset();
+ /* reset */
+ bool reset( Theory::Effort e );
+ /** identify */
+ std::string identify() const { return "RelevantDomain"; }
//compute the relevant domain
void compute();
diff --git a/src/theory/quantifiers/rewrite_engine.cpp b/src/theory/quantifiers/rewrite_engine.cpp
index 4c8050239..5365dbcfa 100644
--- a/src/theory/quantifiers/rewrite_engine.cpp
+++ b/src/theory/quantifiers/rewrite_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file rewrite_engine.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewrite engine module
**
@@ -68,7 +68,7 @@ bool RewriteEngine::needsCheck( Theory::Effort e ){
void RewriteEngine::check( Theory::Effort e, unsigned quant_e ) {
if( quant_e==QuantifiersEngine::QEFFORT_STANDARD ){
- //if( e==Theory::EFFORT_FULL ){
+ Assert( !d_quantEngine->inConflict() );
Trace("rewrite-engine") << "---Rewrite Engine Round, effort = " << e << "---" << std::endl;
//if( e==Theory::EFFORT_LAST_CALL ){
// if( !d_quantEngine->getModel()->isModelSet() ){
@@ -95,7 +95,7 @@ void RewriteEngine::check( Theory::Effort e, unsigned quant_e ) {
//per priority level
int index = 0;
bool success = true;
- while( success && index<(int)d_priority_order.size() ) {
+ while( !d_quantEngine->inConflict() && success && index<(int)d_priority_order.size() ) {
addedLemmas += checkRewriteRule( d_priority_order[index], e );
index++;
if( index<(int)d_priority_order.size() ){
@@ -104,11 +104,6 @@ void RewriteEngine::check( Theory::Effort e, unsigned quant_e ) {
}
Trace("rewrite-engine") << "Finished rewrite engine, added " << addedLemmas << " lemmas." << std::endl;
- if (addedLemmas==0) {
-
- }else{
- //otherwise, the search will continue
- }
}
}
@@ -124,12 +119,13 @@ int RewriteEngine::checkRewriteRule( Node f, Theory::Effort e ) {
std::map< Node, QuantInfo >::iterator it = d_qinfo.find( f );
if( it!=d_qinfo.end() ){
QuantInfo * qi = &it->second;
- if( qi->d_mg->isValid() ){
+ if( qi->matchGeneratorIsValid() ){
Node rr = TermDb::getRewriteRule( f );
Trace("rewrite-engine-inst-debug") << " Reset round..." << std::endl;
qi->reset_round( qcf );
Trace("rewrite-engine-inst-debug") << " Get matches..." << std::endl;
- while( qi->d_mg->getNextMatch( qcf, qi ) && ( addedLemmas==0 || !options::rrOneInstPerRound() ) ){
+ while( !d_quantEngine->inConflict() && qi->getNextMatch( qcf ) &&
+ ( addedLemmas==0 || !options::rrOneInstPerRound() ) ){
Trace("rewrite-engine-inst-debug") << " Got match to complete..." << std::endl;
qi->debugPrintMatch( "rewrite-engine-inst-debug" );
std::vector< int > assigned;
@@ -137,7 +133,7 @@ int RewriteEngine::checkRewriteRule( Node f, Theory::Effort e ) {
bool doContinue = false;
bool success = true;
int tempAddedLemmas = 0;
- while( tempAddedLemmas==0 && success && ( addedLemmas==0 || !options::rrOneInstPerRound() ) ){
+ while( !d_quantEngine->inConflict() && tempAddedLemmas==0 && success && ( addedLemmas==0 || !options::rrOneInstPerRound() ) ){
success = qi->completeMatch( qcf, assigned, doContinue );
doContinue = true;
if( success ){
@@ -158,7 +154,7 @@ int RewriteEngine::checkRewriteRule( Node f, Theory::Effort e ) {
if( inst.size()>f[0].getNumChildren() ){
inst.resize( f[0].getNumChildren() );
}
- if( d_quantEngine->addInstantiation( f, inst, false ) ){
+ if( d_quantEngine->addInstantiation( f, inst ) ){
addedLemmas++;
tempAddedLemmas++;
/*
@@ -289,7 +285,7 @@ void RewriteEngine::registerQuantifier( Node f ) {
//make the quantified formula
d_qinfo_n[f] = NodeManager::currentNM()->mkNode( FORALL, qcfn_c );
Trace("rr-register") << " qcf formula is : " << d_qinfo_n[f] << std::endl;
- d_qinfo[f].initialize( d_qinfo_n[f], d_qinfo_n[f][1] );
+ d_qinfo[f].initialize( qcf, d_qinfo_n[f], d_qinfo_n[f][1] );
}
}
}
diff --git a/src/theory/quantifiers/rewrite_engine.h b/src/theory/quantifiers/rewrite_engine.h
index 6ad76c541..424530696 100644
--- a/src/theory/quantifiers/rewrite_engine.h
+++ b/src/theory/quantifiers/rewrite_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rewrite_engine.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/quantifiers/symmetry_breaking.cpp b/src/theory/quantifiers/symmetry_breaking.cpp
index 4c8e24d08..2a2b13583 100644
--- a/src/theory/quantifiers/symmetry_breaking.cpp
+++ b/src/theory/quantifiers/symmetry_breaking.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file symmetry_breaking.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief symmetry breaking module
**
diff --git a/src/theory/quantifiers/symmetry_breaking.h b/src/theory/quantifiers/symmetry_breaking.h
index 43e5ec765..38fea4f45 100644
--- a/src/theory/quantifiers/symmetry_breaking.h
+++ b/src/theory/quantifiers/symmetry_breaking.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file symmetry_breaking.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Pre-process step for first-order reasoning
**/
diff --git a/src/theory/quantifiers/term_database.cpp b/src/theory/quantifiers/term_database.cpp
index 560f68810..8b09d8e5d 100644
--- a/src/theory/quantifiers/term_database.cpp
+++ b/src/theory/quantifiers/term_database.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file term_database.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Francois Bobot
- ** Minor contributors (to current version): Kshitij Bansal, Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Francois Bobot, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of term databse class
**/
@@ -59,23 +59,27 @@ TNode TermArgTrie::existsTerm( std::vector< TNode >& reps, int argIndex ) {
}
bool TermArgTrie::addTerm( TNode n, std::vector< TNode >& reps, int argIndex ){
+ return addOrGetTerm( n, reps, argIndex )==n;
+}
+
+TNode TermArgTrie::addOrGetTerm( TNode n, std::vector< TNode >& reps, int argIndex ) {
if( argIndex==(int)reps.size() ){
if( d_data.empty() ){
//store n in d_data (this should be interpretted as the "data" and not as a reference to a child)
d_data[n].clear();
- return true;
+ return n;
}else{
- return false;
+ return d_data.begin()->first;
}
}else{
- return d_data[reps[argIndex]].addTerm( n, reps, argIndex+1 );
+ return d_data[reps[argIndex]].addOrGetTerm( n, reps, argIndex+1 );
}
}
void TermArgTrie::debugPrint( const char * c, Node n, unsigned depth ) {
for( std::map< TNode, TermArgTrie >::iterator it = d_data.begin(); it != d_data.end(); ++it ){
- for( unsigned i=0; i<depth; i++ ){ Debug(c) << " "; }
- Debug(c) << it->first << std::endl;
+ for( unsigned i=0; i<depth; i++ ){ Trace(c) << " "; }
+ Trace(c) << it->first << std::endl;
it->second.debugPrint( c, n, depth+1 );
}
}
@@ -107,10 +111,25 @@ Node TermDb::getGroundTerm( Node f, unsigned i ) {
return d_op_map[f][i];
}
-Node TermDb::getOperator( Node n ) {
- //return n.getOperator();
+unsigned TermDb::getNumTypeGroundTerms( TypeNode tn ) {
+ std::map< TypeNode, std::vector< Node > >::iterator it = d_type_map.find( tn );
+ if( it!=d_type_map.end() ){
+ return it->second.size();
+ }else{
+ return 0;
+ }
+}
+
+Node TermDb::getTypeGroundTerm( TypeNode tn, unsigned i ) {
+ Assert( i<d_type_map[tn].size() );
+ return d_type_map[tn][i];
+}
+
+Node TermDb::getMatchOperator( Node n ) {
Kind k = n.getKind();
- if( k==SELECT || k==STORE || k==UNION || k==INTERSECTION || k==SUBSET || k==SETMINUS || k==MEMBER || k==SINGLETON ){
+ //datatype operators may be parametric, always assume they are
+ if( k==SELECT || k==STORE || k==UNION || k==INTERSECTION || k==SUBSET || k==SETMINUS || k==MEMBER || k==SINGLETON ||
+ k==APPLY_SELECTOR_TOTAL || k==APPLY_TESTER ){
//since it is parametric, use a particular one as op
TypeNode tn = n[0].getType();
Node op = n.getOperator();
@@ -144,7 +163,7 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant, bool wi
//if this is an atomic trigger, consider adding it
if( inst::Trigger::isAtomicTrigger( n ) ){
Trace("term-db") << "register term in db " << n << std::endl;
- Node op = getOperator( n );
+ Node op = getMatchOperator( n );
d_op_map[op].push_back( n );
added.insert( n );
@@ -201,116 +220,192 @@ void TermDb::computeUfEqcTerms( TNode f ) {
}
}
-TNode TermDb::evaluateTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep ) {
- Trace("term-db-eval") << "evaluate term : " << n << std::endl;
- eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
- if( ee->hasTerm( n ) ){
- Trace("term-db-eval") << "...exists in ee, return rep " << std::endl;
- return ee->getRepresentative( n );
- }else if( n.getKind()==BOUND_VARIABLE ){
- Assert( subs.find( n )!=subs.end() );
- Trace("term-db-eval") << "...substitution is : " << subs[n] << std::endl;
- if( subsRep ){
- Assert( ee->hasTerm( subs[n] ) );
- Assert( ee->getRepresentative( subs[n] )==subs[n] );
- return subs[n];
+bool TermDb::inRelevantDomain( TNode f, unsigned i, TNode r ) {
+ Assert( d_quantEngine->getTheoryEngine()->getMasterEqualityEngine()->getRepresentative( r )==r );
+ std::map< Node, std::map< unsigned, std::vector< Node > > >::iterator it = d_func_map_rel_dom.find( f );
+ if( it != d_func_map_rel_dom.end() ){
+ std::map< unsigned, std::vector< Node > >::iterator it2 = it->second.find( i );
+ if( it2!=it->second.end() ){
+ return std::find( it2->second.begin(), it2->second.end(), r )!=it2->second.end();
}else{
- return evaluateTerm( subs[n], subs, subsRep );
+ return false;
}
}else{
- if( n.hasOperator() ){
- TNode f = getOperator( n );
- if( !f.isNull() ){
- std::vector< TNode > args;
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- TNode c = evaluateTerm( n[i], subs, subsRep );
- if( c.isNull() ){
- return TNode::null();
+ return false;
+ }
+}
+
+//return a term n' equivalent to n
+// maximal subterms of n' are representatives in the equality engine qy
+Node TermDb::evaluateTerm2( TNode n, std::map< TNode, Node >& visited, EqualityQuery * qy ) {
+ std::map< TNode, Node >::iterator itv = visited.find( n );
+ if( itv != visited.end() ){
+ return itv->second;
+ }
+ Trace("term-db-eval") << "evaluate term : " << n << std::endl;
+ Node ret;
+ if( n.getKind()==BOUND_VARIABLE ){
+ return n;
+ }else if( !qy->hasTerm( n ) ){
+ //term is not known to be equal to a representative in equality engine, evaluate it
+ if( n.getKind()==FORALL ){
+ ret = Node::null();
+ }else if( n.hasOperator() ){
+ TNode f = getMatchOperator( n );
+ std::vector< TNode > args;
+ bool ret_set = false;
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ TNode c = evaluateTerm2( n[i], visited, qy );
+ if( c.isNull() ){
+ ret = Node::null();
+ ret_set = true;
+ break;
+ }else if( c==d_true || c==d_false ){
+ //short-circuiting
+ if( ( n.getKind()==kind::AND && c==d_false ) || ( n.getKind()==kind::OR && c==d_true ) ){
+ ret = c;
+ ret_set = true;
+ break;
+ }else if( n.getKind()==kind::ITE && i==0 ){
+ ret = evaluateTerm2( n[ c==d_true ? 1 : 2], visited, qy );
+ ret_set = true;
+ break;
}
- Trace("term-db-eval") << "Got child : " << c << std::endl;
- args.push_back( c );
}
- Trace("term-db-eval") << "Get term from DB" << std::endl;
- TNode nn = d_func_map_trie[f].existsTerm( args );
- Trace("term-db-eval") << "Got term " << nn << std::endl;
- if( !nn.isNull() ){
- if( ee->hasTerm( nn ) ){
- Trace("term-db-eval") << "return rep " << std::endl;
- return ee->getRepresentative( nn );
- }else{
- //Assert( false );
+ Trace("term-db-eval") << " child " << i << " : " << c << std::endl;
+ args.push_back( c );
+ }
+ if( !ret_set ){
+ //if it is an indexed term, return the congruent term
+ if( !f.isNull() ){
+ TNode nn = qy->getCongruentTerm( f, args );
+ Trace("term-db-eval") << " got congruent term " << nn << " from DB for " << n << std::endl;
+ if( !nn.isNull() ){
+ ret = qy->getRepresentative( nn );
+ Trace("term-db-eval") << "return rep" << std::endl;
+ ret_set = true;
+ Assert( !ret.isNull() );
}
}
+ if( !ret_set ){
+ Trace("term-db-eval") << "return rewrite" << std::endl;
+ //a theory symbol or a new UF term
+ if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
+ args.insert( args.begin(), n.getOperator() );
+ }
+ ret = NodeManager::currentNM()->mkNode( n.getKind(), args );
+ ret = Rewriter::rewrite( ret );
+ }
}
}
- return TNode::null();
+ }else{
+ Trace("term-db-eval") << "...exists in ee, return rep" << std::endl;
+ ret = qy->getRepresentative( n );
}
+ Trace("term-db-eval") << "evaluated term : " << n << ", got : " << ret << std::endl;
+ visited[n] = ret;
+ return ret;
}
-TNode TermDb::evaluateTerm( TNode n ) {
- eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
- if( ee->hasTerm( n ) ){
- return ee->getRepresentative( n );
- }else if( n.getKind()!=BOUND_VARIABLE ){
+
+TNode TermDb::getEntailedTerm2( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool hasSubs, EqualityQuery * qy ) {
+ Assert( !qy->extendsEngine() );
+ Trace("term-db-entail") << "get entailed term : " << n << std::endl;
+ if( qy->getEngine()->hasTerm( n ) ){
+ Trace("term-db-entail") << "...exists in ee, return rep " << std::endl;
+ return n;
+ }else if( n.getKind()==BOUND_VARIABLE ){
+ if( hasSubs ){
+ Assert( subs.find( n )!=subs.end() );
+ Trace("term-db-entail") << "...substitution is : " << subs[n] << std::endl;
+ if( subsRep ){
+ Assert( qy->getEngine()->hasTerm( subs[n] ) );
+ Assert( qy->getEngine()->getRepresentative( subs[n] )==subs[n] );
+ return subs[n];
+ }else{
+ return getEntailedTerm2( subs[n], subs, subsRep, hasSubs, qy );
+ }
+ }
+ }else if( n.getKind()==ITE ){
+ for( unsigned i=0; i<2; i++ ){
+ if( isEntailed2( n[0], subs, subsRep, hasSubs, i==0, qy ) ){
+ return getEntailedTerm2( n[ i==0 ? 1 : 2 ], subs, subsRep, hasSubs, qy );
+ }
+ }
+ }else{
if( n.hasOperator() ){
- TNode f = getOperator( n );
+ TNode f = getMatchOperator( n );
if( !f.isNull() ){
std::vector< TNode > args;
for( unsigned i=0; i<n.getNumChildren(); i++ ){
- TNode c = evaluateTerm( n[i] );
+ TNode c = getEntailedTerm2( n[i], subs, subsRep, hasSubs, qy );
if( c.isNull() ){
return TNode::null();
}
+ c = qy->getEngine()->getRepresentative( c );
+ Trace("term-db-entail") << " child " << i << " : " << c << std::endl;
args.push_back( c );
}
- TNode nn = d_func_map_trie[f].existsTerm( args );
- if( !nn.isNull() ){
- if( ee->hasTerm( nn ) ){
- return ee->getRepresentative( nn );
- }else{
- //Assert( false );
- }
- }
+ TNode nn = qy->getCongruentTerm( f, args );
+ Trace("term-db-entail") << " got congruent term " << nn << " for " << n << std::endl;
+ return nn;
}
}
}
return TNode::null();
}
-bool TermDb::isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol ) {
- Trace("term-db-eval") << "Check entailed : " << n << ", pol = " << pol << std::endl;
+Node TermDb::evaluateTerm( TNode n, EqualityQuery * qy ) {
+ if( qy==NULL ){
+ qy = d_quantEngine->getEqualityQuery();
+ }
+ std::map< TNode, Node > visited;
+ return evaluateTerm2( n, visited, qy );
+}
+
+TNode TermDb::getEntailedTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep, EqualityQuery * qy ) {
+ if( qy==NULL ){
+ qy = d_quantEngine->getEqualityQuery();
+ }
+ return getEntailedTerm2( n, subs, subsRep, true, qy );
+}
+
+TNode TermDb::getEntailedTerm( TNode n, EqualityQuery * qy ) {
+ if( qy==NULL ){
+ qy = d_quantEngine->getEqualityQuery();
+ }
+ std::map< TNode, TNode > subs;
+ return getEntailedTerm2( n, subs, false, false, qy );
+}
+
+bool TermDb::isEntailed2( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool hasSubs, bool pol, EqualityQuery * qy ) {
+ Assert( !qy->extendsEngine() );
+ Trace("term-db-entail") << "Check entailed : " << n << ", pol = " << pol << std::endl;
Assert( n.getType().isBoolean() );
if( n.getKind()==EQUAL ){
- TNode n1 = evaluateTerm( n[0], subs, subsRep );
+ TNode n1 = getEntailedTerm2( n[0], subs, subsRep, hasSubs, qy );
if( !n1.isNull() ){
- TNode n2 = evaluateTerm( n[1], subs, subsRep );
+ TNode n2 = getEntailedTerm2( n[1], subs, subsRep, hasSubs, qy );
if( !n2.isNull() ){
- eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
- Assert( ee->hasTerm( n1 ) );
- Assert( ee->hasTerm( n2 ) );
- if( pol ){
- return n1==n2 || ee->areEqual( n1, n2 );
+ if( n1==n2 ){
+ return pol;
}else{
- return n1!=n2 && ee->areDisequal( n1, n2, false );
+ Assert( qy->getEngine()->hasTerm( n1 ) );
+ Assert( qy->getEngine()->hasTerm( n2 ) );
+ if( pol ){
+ return qy->getEngine()->areEqual( n1, n2 );
+ }else{
+ return qy->getEngine()->areDisequal( n1, n2, false );
+ }
}
}
}
- }else if( n.getKind()==APPLY_UF ){
- TNode n1 = evaluateTerm( n, subs, subsRep );
- if( !n1.isNull() ){
- eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
- Assert( ee->hasTerm( n1 ) );
- TNode n2 = pol ? d_true : d_false;
- if( ee->hasTerm( n2 ) ){
- return ee->areEqual( n1, n2 );
- }
- }
}else if( n.getKind()==NOT ){
- return isEntailed( n[0], subs, subsRep, !pol );
+ return isEntailed2( n[0], subs, subsRep, hasSubs, !pol, qy );
}else if( n.getKind()==OR || n.getKind()==AND ){
bool simPol = ( pol && n.getKind()==OR ) || ( !pol && n.getKind()==AND );
for( unsigned i=0; i<n.getNumChildren(); i++ ){
- if( isEntailed( n[i], subs, subsRep, pol ) ){
+ if( isEntailed2( n[i], subs, subsRep, hasSubs, pol, qy ) ){
if( simPol ){
return true;
}
@@ -323,16 +418,45 @@ bool TermDb::isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep,
return !simPol;
}else if( n.getKind()==IFF || n.getKind()==ITE ){
for( unsigned i=0; i<2; i++ ){
- if( isEntailed( n[0], subs, subsRep, i==0 ) ){
+ if( isEntailed2( n[0], subs, subsRep, hasSubs, i==0, qy ) ){
unsigned ch = ( n.getKind()==IFF || i==0 ) ? 1 : 2;
bool reqPol = ( n.getKind()==ITE || i==0 ) ? pol : !pol;
- return isEntailed( n[ch], subs, subsRep, reqPol );
+ return isEntailed2( n[ch], subs, subsRep, hasSubs, reqPol, qy );
+ }
+ }
+ }else if( n.getKind()==APPLY_UF ){
+ TNode n1 = getEntailedTerm2( n, subs, subsRep, hasSubs, qy );
+ if( !n1.isNull() ){
+ Assert( qy->hasTerm( n1 ) );
+ if( n1==d_true ){
+ return pol;
+ }else if( n1==d_false ){
+ return !pol;
+ }else{
+ return qy->getEngine()->getRepresentative( n1 ) == ( pol ? d_true : d_false );
}
}
}
return false;
}
+bool TermDb::isEntailed( TNode n, bool pol, EqualityQuery * qy ) {
+ if( qy==NULL ){
+ Assert( d_consistent_ee );
+ qy = d_quantEngine->getEqualityQuery();
+ }
+ std::map< TNode, TNode > subs;
+ return isEntailed2( n, subs, false, false, pol, qy );
+}
+
+bool TermDb::isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol, EqualityQuery * qy ) {
+ if( qy==NULL ){
+ Assert( d_consistent_ee );
+ qy = d_quantEngine->getEqualityQuery();
+ }
+ return isEntailed2( n, subs, subsRep, true, pol, qy );
+}
+
bool TermDb::hasTermCurrent( Node n, bool useMode ) {
if( !useMode ){
return d_has_map.find( n )!=d_has_map.end();
@@ -431,7 +555,7 @@ void TermDb::presolve() {
}
}
-void TermDb::reset( Theory::Effort effort ){
+bool TermDb::reset( Theory::Effort effort ){
int nonCongruentCount = 0;
int congruentCount = 0;
int alreadyCongruentCount = 0;
@@ -440,6 +564,8 @@ void TermDb::reset( Theory::Effort effort ){
d_arg_reps.clear();
d_func_map_trie.clear();
d_func_map_eqc_trie.clear();
+ d_func_map_rel_dom.clear();
+ d_consistent_ee = true;
eq::EqualityEngine* ee = d_quantEngine->getMasterEqualityEngine();
//compute has map
@@ -480,7 +606,13 @@ void TermDb::reset( Theory::Effort effort ){
}
}
}
-
+ //explicitly add inst closure terms to the equality engine to ensure only EE terms are indexed
+ for( std::hash_set< Node, NodeHashFunction >::iterator it = d_iclosure_processed.begin(); it !=d_iclosure_processed.end(); ++it ){
+ Node n = *it;
+ if( !ee->hasTerm( n ) ){
+ ee->addTerm( n );
+ }
+ }
//rebuild d_func/pred_map_trie for each operation, this will calculate all congruent terms
for( std::map< Node, std::vector< Node > >::iterator it = d_op_map.begin(); it != d_op_map.end(); ++it ){
@@ -488,32 +620,58 @@ void TermDb::reset( Theory::Effort effort ){
Trace("term-db-debug") << "Adding terms for operator " << it->first << std::endl;
for( unsigned i=0; i<it->second.size(); i++ ){
Node n = it->second[i];
- //to be added to term index, term must be relevant, and either exist in EE or be an inst closure term
- if( hasTermCurrent( n ) && ( ee->hasTerm( n ) || d_iclosure_processed.find( n )!=d_iclosure_processed.end() ) ){
+ //to be added to term index, term must be relevant, and exist in EE
+ if( hasTermCurrent( n ) && ee->hasTerm( n ) ){
if( !n.getAttribute(NoMatchAttribute()) ){
if( options::finiteModelFind() ){
computeModelBasisArgAttribute( n );
}
computeArgReps( n );
- if( Trace.isOn("term-db-debug") ){
- Trace("term-db-debug") << "Adding term " << n << " with arg reps : ";
- for( unsigned i=0; i<d_arg_reps[n].size(); i++ ){
- Trace("term-db-debug") << d_arg_reps[n] << " ";
+ Trace("term-db-debug") << "Adding term " << n << " with arg reps : ";
+ for( unsigned i=0; i<d_arg_reps[n].size(); i++ ){
+ Trace("term-db-debug") << d_arg_reps[n][i] << " ";
+ if( std::find( d_func_map_rel_dom[it->first][i].begin(),
+ d_func_map_rel_dom[it->first][i].end(), d_arg_reps[n][i] ) == d_func_map_rel_dom[it->first][i].end() ){
+ d_func_map_rel_dom[it->first][i].push_back( d_arg_reps[n][i] );
}
- Trace("term-db-debug") << std::endl;
}
-
- if( !d_func_map_trie[ it->first ].addTerm( n, d_arg_reps[n] ) ){
+ Trace("term-db-debug") << std::endl;
+ if( ee->hasTerm( n ) ){
+ Trace("term-db-debug") << " and value : " << ee->getRepresentative( n ) << std::endl;
+ }
+ Node at = d_func_map_trie[ it->first ].addOrGetTerm( n, d_arg_reps[n] );
+ if( at!=n && ee->areEqual( at, n ) ){
NoMatchAttribute nma;
n.setAttribute(nma,true);
Trace("term-db-debug") << n << " is redundant." << std::endl;
congruentCount++;
}else{
+ if( at!=n && ee->areDisequal( at, n, false ) ){
+ std::vector< Node > lits;
+ lits.push_back( NodeManager::currentNM()->mkNode( at.getType().isBoolean() ? IFF : EQUAL, at, n ) );
+ for( unsigned i=0; i<at.getNumChildren(); i++ ){
+ if( at[i]!=n[i] ){
+ lits.push_back( NodeManager::currentNM()->mkNode( at[i].getType().isBoolean() ? IFF : EQUAL, at[i], n[i] ).negate() );
+ }
+ }
+ Node lem = lits.size()==1 ? lits[0] : NodeManager::currentNM()->mkNode( OR, lits );
+ if( Trace.isOn("term-db-lemma") ){
+ Trace("term-db-lemma") << "Disequal congruent terms : " << at << " " << n << "!!!!" << std::endl;
+ if( !d_quantEngine->getTheoryEngine()->needCheck() ){
+ Trace("term-db-lemma") << " all theories passed with no lemmas." << std::endl;
+ }
+ Trace("term-db-lemma") << " add lemma : " << lem << std::endl;
+ }
+ d_quantEngine->addLemma( lem );
+ d_consistent_ee = false;
+ return false;
+ }
nonCongruentCount++;
d_op_nonred_count[ it->first ]++;
}
}else{
+ Trace("term-db-debug") << n << " is already redundant." << std::endl;
congruentCount++;
alreadyCongruentCount++;
}
@@ -526,15 +684,16 @@ void TermDb::reset( Theory::Effort effort ){
Trace("term-db-stats") << "TermDb: Reset" << std::endl;
Trace("term-db-stats") << "Non-Congruent/Congruent/Non-Relevant = ";
Trace("term-db-stats") << nonCongruentCount << " / " << congruentCount << " (" << alreadyCongruentCount << ") / " << nonRelevantCount << std::endl;
- if( Debug.isOn("term-db") ){
- Debug("term-db") << "functions : " << std::endl;
+ if( Trace.isOn("term-db-index") ){
+ Trace("term-db-index") << "functions : " << std::endl;
for( std::map< Node, std::vector< Node > >::iterator it = d_op_map.begin(); it != d_op_map.end(); ++it ){
if( it->second.size()>0 ){
- Debug("term-db") << "- " << it->first << std::endl;
- d_func_map_trie[ it->first ].debugPrint("term-db", it->second[0]);
+ Trace("term-db-index") << "- " << it->first << std::endl;
+ d_func_map_trie[ it->first ].debugPrint("term-db-index", it->second[0]);
}
}
}
+ return true;
}
TermArgTrie * TermDb::getTermArgTrie( Node f ) {
@@ -565,11 +724,15 @@ TermArgTrie * TermDb::getTermArgTrie( Node eqc, Node f ) {
}
}
-TNode TermDb::existsTerm( Node f, Node n ) {
+TNode TermDb::getCongruentTerm( Node f, Node n ) {
computeArgReps( n );
return d_func_map_trie[f].existsTerm( d_arg_reps[n] );
}
+TNode TermDb::getCongruentTerm( Node f, std::vector< TNode >& args ) {
+ return d_func_map_trie[f].existsTerm( args );
+}
+
Node TermDb::getModelBasisTerm( TypeNode tn, int i ){
if( d_model_basis_term.find( tn )==d_model_basis_term.end() ){
Node mbt;
@@ -800,10 +963,10 @@ Node TermDb::getInstantiationConstant( Node q, int i ) const {
}
/** get number of instantiation constants for q */
-int TermDb::getNumInstantiationConstants( Node q ) const {
+unsigned TermDb::getNumInstantiationConstants( Node q ) const {
std::map< Node, std::vector< Node > >::const_iterator it = d_inst_constants.find( q );
if( it!=d_inst_constants.end() ){
- return (int)it->second.size();
+ return it->second.size();
}else{
return 0;
}
@@ -853,14 +1016,29 @@ Node TermDb::getInstantiatedNode( Node n, Node q, std::vector< Node >& terms ) {
}
-void getSelfSel( const DatatypeConstructor& dc, Node n, TypeNode ntn, std::vector< Node >& selfSel ){
+void getSelfSel( const Datatype& dt, const DatatypeConstructor& dc, Node n, TypeNode ntn, std::vector< Node >& selfSel ){
+ TypeNode tspec;
+ if( dt.isParametric() ){
+ tspec = TypeNode::fromType( dc.getSpecializedConstructorType(n.getType().toType()) );
+ Trace("sk-ind-debug") << "Specialized constructor type : " << tspec << std::endl;
+ Assert( tspec.getNumChildren()==dc.getNumArgs() );
+ }
+ Trace("sk-ind-debug") << "Check self sel " << dc.getName() << " " << dt.getName() << std::endl;
for( unsigned j=0; j<dc.getNumArgs(); j++ ){
- TypeNode tn = TypeNode::fromType( ((SelectorType)dc[j].getSelector().getType()).getRangeType() );
std::vector< Node > ssc;
- if( tn==ntn ){
- ssc.push_back( n );
+ if( dt.isParametric() ){
+ Trace("sk-ind-debug") << "Compare " << tspec[j] << " " << ntn << std::endl;
+ if( tspec[j]==ntn ){
+ ssc.push_back( n );
+ }
+ }else{
+ TypeNode tn = TypeNode::fromType( dc[j].getRangeType() );
+ Trace("sk-ind-debug") << "Compare " << tn << " " << ntn << std::endl;
+ if( tn==ntn ){
+ ssc.push_back( n );
+ }
}
- /* TODO
+ /* TODO: more than weak structural induction
else if( datatypes::DatatypesRewriter::isTypeDatatype( tn ) && std::find( visited.begin(), visited.end(), tn )==visited.end() ){
visited.push_back( tn );
const Datatype& dt = ((DatatypeType)(subs[0].getType()).toType()).getDatatype();
@@ -938,7 +1116,7 @@ Node TermDb::mkSkolemizedBody( Node f, Node n, std::vector< TypeNode >& argTypes
std::vector< Node > disj;
for( unsigned i=0; i<dt.getNumConstructors(); i++ ){
std::vector< Node > selfSel;
- getSelfSel( dt[i], k, tn, selfSel );
+ getSelfSel( dt, dt[i], k, tn, selfSel );
std::vector< Node > conj;
conj.push_back( NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[i].getTester() ), k ).negate() );
for( unsigned j=0; j<selfSel.size(); j++ ){
@@ -1050,7 +1228,7 @@ bool TermDb::isClosedEnumerableType( TypeNode tn ) {
const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
for( unsigned i=0; i<dt.getNumConstructors(); i++ ){
for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){
- TypeNode ctn = TypeNode::fromType( ((SelectorType)dt[i][j].getSelector().getType()).getRangeType() );
+ TypeNode ctn = TypeNode::fromType( dt[i][j].getRangeType() );
if( tn!=ctn && !isClosedEnumerableType( ctn ) ){
ret = false;
break;
@@ -1585,7 +1763,7 @@ bool TermDb::containsVtsInfinity( Node n, bool isFree ) {
return containsTerms( n, t );
}
-Node TermDb::mkNodeType( Node n, TypeNode tn ) {
+Node TermDb::ensureType( Node n, TypeNode tn ) {
TypeNode ntn = n.getType();
Assert( ntn.isComparableTo( tn ) );
if( ntn.isSubtypeOf( tn ) ){
@@ -1598,6 +1776,20 @@ Node TermDb::mkNodeType( Node n, TypeNode tn ) {
}
}
+bool TermDb::getEnsureTypeCondition( Node n, TypeNode tn, std::vector< Node >& cond ) {
+ TypeNode ntn = n.getType();
+ Assert( ntn.isComparableTo( tn ) );
+ if( !ntn.isSubtypeOf( tn ) ){
+ if( tn.isInteger() ){
+ cond.push_back( NodeManager::currentNM()->mkNode( IS_INTEGER, n ) );
+ return true;
+ }
+ return false;
+ }else{
+ return true;
+ }
+}
+
bool TermDb::containsTerm2( Node n, Node t, std::map< Node, bool >& visited ) {
if( n==t ){
return true;
@@ -1630,20 +1822,6 @@ bool TermDb::containsTerms2( Node n, std::vector< Node >& t, std::map< Node, boo
return false;
}
-bool TermDb::containsUninterpretedConstant2( Node n, std::map< Node, bool >& visited ) {
- if( n.getKind()==UNINTERPRETED_CONSTANT ){
- return true;
- }else if( visited.find( n )==visited.end() ){
- visited[n] = true;
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- if( containsUninterpretedConstant2( n[i], visited ) ){
- return true;
- }
- }
- }
- return false;
-}
-
bool TermDb::containsTerm( Node n, Node t ) {
std::map< Node, bool > visited;
return containsTerm2( n, t, visited );
@@ -1658,9 +1836,38 @@ bool TermDb::containsTerms( Node n, std::vector< Node >& t ) {
}
}
+int TermDb::getTermDepth( Node n ) {
+ if (!n.hasAttribute(TermDepthAttribute()) ){
+ int maxDepth = -1;
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ int depth = getTermDepth( n[i] );
+ if( depth>maxDepth ){
+ maxDepth = depth;
+ }
+ }
+ TermDepthAttribute tda;
+ n.setAttribute(tda,1+maxDepth);
+ }
+ return n.getAttribute(TermDepthAttribute());
+}
+
bool TermDb::containsUninterpretedConstant( Node n ) {
- std::map< Node, bool > visited;
- return containsUninterpretedConstant2( n, visited );
+ if (!n.hasAttribute(ContainsUConstAttribute()) ){
+ bool ret = false;
+ if( n.getKind()==UNINTERPRETED_CONSTANT ){
+ ret = true;
+ }else{
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ if( containsUninterpretedConstant( n[i] ) ){
+ ret = true;
+ break;
+ }
+ }
+ }
+ ContainsUConstAttribute cuca;
+ n.setAttribute(cuca, ret ? 1 : 0);
+ }
+ return n.getAttribute(ContainsUConstAttribute())!=0;
}
Node TermDb::simpleNegate( Node n ){
@@ -1787,69 +1994,109 @@ bool TermDb::isSygusConjectureAnnotation( Node ipl ){
return false;
}
+bool TermDb::isQuantElimAnnotation( Node ipl ) {
+ if( !ipl.isNull() ){
+ for( unsigned i=0; i<ipl.getNumChildren(); i++ ){
+ if( ipl[i].getKind()==INST_ATTRIBUTE ){
+ Node avar = ipl[i][0];
+ if( avar.getAttribute(QuantElimAttribute()) ){
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
void TermDb::computeAttributes( Node q ) {
+ computeQuantAttributes( q, d_qattr[q] );
+ if( !d_qattr[q].d_rr.isNull() ){
+ if( d_quantEngine->getRewriteEngine()==NULL ){
+ Trace("quant-warn") << "WARNING : rewrite engine is null, and we have : " << q << std::endl;
+ }
+ //set rewrite engine as owner
+ d_quantEngine->setOwner( q, d_quantEngine->getRewriteEngine(), 2 );
+ }
+ if( d_qattr[q].isFunDef() ){
+ Node f = d_qattr[q].d_fundef_f;
+ if( d_fun_defs.find( f )!=d_fun_defs.end() ){
+ Message() << "Cannot define function " << f << " more than once." << std::endl;
+ exit( 1 );
+ }
+ d_fun_defs[f] = true;
+ d_quantEngine->setOwner( q, d_quantEngine->getFunDefEngine(), 2 );
+ }
+ if( d_qattr[q].d_sygus ){
+ if( d_quantEngine->getCegInstantiation()==NULL ){
+ Trace("quant-warn") << "WARNING : ceg instantiation is null, and we have : " << q << std::endl;
+ }
+ d_quantEngine->setOwner( q, d_quantEngine->getCegInstantiation(), 2 );
+ }
+ if( d_qattr[q].d_synthesis ){
+ if( d_quantEngine->getCegInstantiation()==NULL ){
+ Trace("quant-warn") << "WARNING : ceg instantiation is null, and we have : " << q << std::endl;
+ }
+ d_quantEngine->setOwner( q, d_quantEngine->getCegInstantiation(), 2 );
+ }
+}
+
+void TermDb::computeQuantAttributes( Node q, QAttributes& qa ){
Trace("quant-attr-debug") << "Compute attributes for " << q << std::endl;
if( q.getNumChildren()==3 ){
+ qa.d_ipl = q[2];
for( unsigned i=0; i<q[2].getNumChildren(); i++ ){
Trace("quant-attr-debug") << "Check : " << q[2][i] << " " << q[2][i].getKind() << std::endl;
- if( q[2][i].getKind()==INST_ATTRIBUTE ){
+ if( q[2][i].getKind()==INST_PATTERN || q[2][i].getKind()==INST_NO_PATTERN ){
+ qa.d_hasPattern = true;
+ }else if( q[2][i].getKind()==INST_ATTRIBUTE ){
Node avar = q[2][i][0];
if( avar.getAttribute(AxiomAttribute()) ){
Trace("quant-attr") << "Attribute : axiom : " << q << std::endl;
- d_qattr_axiom[q] = true;
+ qa.d_axiom = true;
}
if( avar.getAttribute(ConjectureAttribute()) ){
Trace("quant-attr") << "Attribute : conjecture : " << q << std::endl;
- d_qattr_conjecture[q] = true;
+ qa.d_conjecture = true;
}
if( avar.getAttribute(FunDefAttribute()) ){
Trace("quant-attr") << "Attribute : function definition : " << q << std::endl;
- d_qattr_fundef[q] = true;
//get operator directly from pattern
- Node f = q[2][i][0].getOperator();
- if( d_fun_defs.find( f )!=d_fun_defs.end() ){
- Message() << "Cannot define function " << f << " more than once." << std::endl;
- exit( 0 );
- }
- d_fun_defs[f] = true;
- d_quantEngine->setOwner( q, d_quantEngine->getFunDefEngine() );
+ qa.d_fundef_f = q[2][i][0].getOperator();
}
if( avar.getAttribute(SygusAttribute()) ){
//not necessarily nested existential
//Assert( q[1].getKind()==NOT );
//Assert( q[1][0].getKind()==FORALL );
-
Trace("quant-attr") << "Attribute : sygus : " << q << std::endl;
- d_qattr_sygus[q] = true;
- if( d_quantEngine->getCegInstantiation()==NULL ){
- Trace("quant-warn") << "WARNING : ceg instantiation is null, and we have : " << q << std::endl;
- }
- d_quantEngine->setOwner( q, d_quantEngine->getCegInstantiation() );
+ qa.d_sygus = true;
}
if( avar.getAttribute(SynthesisAttribute()) ){
Trace("quant-attr") << "Attribute : synthesis : " << q << std::endl;
- d_qattr_synthesis[q] = true;
- if( d_quantEngine->getCegInstantiation()==NULL ){
- Trace("quant-warn") << "WARNING : ceg instantiation is null, and we have : " << q << std::endl;
- }
- d_quantEngine->setOwner( q, d_quantEngine->getCegInstantiation() );
+ qa.d_synthesis = true;
}
if( avar.hasAttribute(QuantInstLevelAttribute()) ){
- d_qattr_qinstLevel[q] = avar.getAttribute(QuantInstLevelAttribute());
- Trace("quant-attr") << "Attribute : quant inst level " << d_qattr_qinstLevel[q] << " : " << q << std::endl;
+ qa.d_qinstLevel = avar.getAttribute(QuantInstLevelAttribute());
+ Trace("quant-attr") << "Attribute : quant inst level " << qa.d_qinstLevel << " : " << q << std::endl;
}
if( avar.hasAttribute(RrPriorityAttribute()) ){
- d_qattr_rr_priority[q] = avar.getAttribute(RrPriorityAttribute());
- Trace("quant-attr") << "Attribute : rr priority " << d_qattr_rr_priority[q] << " : " << q << std::endl;
+ qa.d_rr_priority = avar.getAttribute(RrPriorityAttribute());
+ Trace("quant-attr") << "Attribute : rr priority " << qa.d_rr_priority << " : " << q << std::endl;
+ }
+ if( avar.getAttribute(QuantElimAttribute()) ){
+ Trace("quant-attr") << "Attribute : quantifier elimination : " << q << std::endl;
+ qa.d_quant_elim = true;
+ //don't set owner, should happen naturally
+ }
+ if( avar.getAttribute(QuantElimPartialAttribute()) ){
+ Trace("quant-attr") << "Attribute : quantifier elimination partial : " << q << std::endl;
+ qa.d_quant_elim = true;
+ qa.d_quant_elim_partial = true;
+ //don't set owner, should happen naturally
}
if( avar.getKind()==REWRITE_RULE ){
Trace("quant-attr") << "Attribute : rewrite rule : " << q << std::endl;
Assert( i==0 );
- if( d_quantEngine->getRewriteEngine()==NULL ){
- Trace("quant-warn") << "WARNING : rewrite engine is null, and we have : " << q << std::endl;
- }
- //set rewrite engine as owner
- d_quantEngine->setOwner( q, d_quantEngine->getRewriteEngine() );
+ qa.d_rr = avar;
}
}
}
@@ -1857,69 +2104,85 @@ void TermDb::computeAttributes( Node q ) {
}
bool TermDb::isQAttrConjecture( Node q ) {
- std::map< Node, bool >::iterator it = d_qattr_conjecture.find( q );
- if( it==d_qattr_conjecture.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return false;
}else{
- return it->second;
+ return it->second.d_conjecture;
}
}
bool TermDb::isQAttrAxiom( Node q ) {
- std::map< Node, bool >::iterator it = d_qattr_axiom.find( q );
- if( it==d_qattr_axiom.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return false;
}else{
- return it->second;
+ return it->second.d_axiom;
}
}
bool TermDb::isQAttrFunDef( Node q ) {
- std::map< Node, bool >::iterator it = d_qattr_fundef.find( q );
- if( it==d_qattr_fundef.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return false;
}else{
- return it->second;
+ return it->second.isFunDef();
}
}
bool TermDb::isQAttrSygus( Node q ) {
- std::map< Node, bool >::iterator it = d_qattr_sygus.find( q );
- if( it==d_qattr_sygus.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return false;
}else{
- return it->second;
+ return it->second.d_sygus;
}
}
bool TermDb::isQAttrSynthesis( Node q ) {
- std::map< Node, bool >::iterator it = d_qattr_synthesis.find( q );
- if( it==d_qattr_synthesis.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return false;
}else{
- return it->second;
+ return it->second.d_synthesis;
}
}
int TermDb::getQAttrQuantInstLevel( Node q ) {
- std::map< Node, int >::iterator it = d_qattr_qinstLevel.find( q );
- if( it==d_qattr_qinstLevel.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return -1;
}else{
- return it->second;
+ return it->second.d_qinstLevel;
}
}
int TermDb::getQAttrRewriteRulePriority( Node q ) {
- std::map< Node, int >::iterator it = d_qattr_rr_priority.find( q );
- if( it==d_qattr_rr_priority.end() ){
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
return -1;
}else{
- return it->second;
+ return it->second.d_rr_priority;
}
}
+bool TermDb::isQAttrQuantElim( Node q ) {
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
+ return false;
+ }else{
+ return it->second.d_quant_elim;
+ }
+}
+bool TermDb::isQAttrQuantElimPartial( Node q ) {
+ std::map< Node, QAttributes >::iterator it = d_qattr.find( q );
+ if( it==d_qattr.end() ){
+ return false;
+ }else{
+ return it->second.d_quant_elim_partial;
+ }
+}
TermDbSygus::TermDbSygus(){
d_true = NodeManager::currentNM()->mkConst( true );
diff --git a/src/theory/quantifiers/term_database.h b/src/theory/quantifiers/term_database.h
index 0c4e94517..a62b343a2 100644
--- a/src/theory/quantifiers/term_database.h
+++ b/src/theory/quantifiers/term_database.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file term_database.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief term database class
**/
@@ -20,6 +20,7 @@
#include "expr/attribute.h"
#include "theory/theory.h"
#include "theory/type_enumerator.h"
+#include "theory/quantifiers/quant_util.h"
#include <map>
@@ -68,6 +69,12 @@ typedef expr::Attribute<InstLevelAttributeId, uint64_t> InstLevelAttribute;
struct InstVarNumAttributeId {};
typedef expr::Attribute<InstVarNumAttributeId, uint64_t> InstVarNumAttribute;
+struct TermDepthAttributeId {};
+typedef expr::Attribute<TermDepthAttributeId, uint64_t> TermDepthAttribute;
+
+struct ContainsUConstAttributeId {};
+typedef expr::Attribute<ContainsUConstAttributeId, uint64_t> ContainsUConstAttribute;
+
struct ModelBasisAttributeId {};
typedef expr::Attribute<ModelBasisAttributeId, bool> ModelBasisAttribute;
//for APPLY_UF terms, 1 : term has direct child with model basis attribute,
@@ -99,6 +106,14 @@ typedef expr::Attribute<SygusProxyAttributeId, Node> SygusProxyAttribute;
struct AbsTypeFunDefAttributeId {};
typedef expr::Attribute<AbsTypeFunDefAttributeId, bool> AbsTypeFunDefAttribute;
+/** Attribute true for quantifiers that we are doing quantifier elimination on */
+struct QuantElimAttributeId {};
+typedef expr::Attribute< QuantElimAttributeId, bool > QuantElimAttribute;
+
+/** Attribute true for quantifiers that we are doing partial quantifier elimination on */
+struct QuantElimPartialAttributeId {};
+typedef expr::Attribute< QuantElimPartialAttributeId, bool > QuantElimPartialAttribute;
+
class QuantifiersEngine;
namespace inst{
@@ -112,23 +127,57 @@ public:
/** the data */
std::map< TNode, TermArgTrie > d_data;
public:
+ bool hasNodeData() { return !d_data.empty(); }
+ TNode getNodeData() { return d_data.begin()->first; }
TNode existsTerm( std::vector< TNode >& reps, int argIndex = 0 );
+ TNode addOrGetTerm( TNode n, std::vector< TNode >& reps, int argIndex = 0 );
bool addTerm( TNode n, std::vector< TNode >& reps, int argIndex = 0 );
void debugPrint( const char * c, Node n, unsigned depth = 0 );
void clear() { d_data.clear(); }
};/* class TermArgTrie */
+class QAttributes{
+public:
+ QAttributes() : d_hasPattern(false), d_conjecture(false), d_axiom(false), d_sygus(false),
+ d_synthesis(false), d_rr_priority(-1), d_qinstLevel(-1), d_quant_elim(false), d_quant_elim_partial(false){}
+ ~QAttributes(){}
+ bool d_hasPattern;
+ Node d_rr;
+ bool d_conjecture;
+ bool d_axiom;
+ Node d_fundef_f;
+ bool d_sygus;
+ bool d_synthesis;
+ int d_rr_priority;
+ int d_qinstLevel;
+ bool d_quant_elim;
+ bool d_quant_elim_partial;
+ Node d_ipl;
+ bool isRewriteRule() { return !d_rr.isNull(); }
+ bool isFunDef() { return !d_fundef_f.isNull(); }
+};
+
namespace fmcheck {
class FullModelChecker;
}
class TermDbSygus;
+class QuantConflictFind;
+class RelevantDomain;
+class ConjectureGenerator;
+class TermGenerator;
+class TermGenEnv;
-class TermDb {
+class TermDb : public QuantifiersUtil {
friend class ::CVC4::theory::QuantifiersEngine;
+ //TODO: eliminate most of these
friend class ::CVC4::theory::inst::Trigger;
friend class ::CVC4::theory::quantifiers::fmcheck::FullModelChecker;
+ friend class ::CVC4::theory::quantifiers::QuantConflictFind;
+ friend class ::CVC4::theory::quantifiers::RelevantDomain;
+ friend class ::CVC4::theory::quantifiers::ConjectureGenerator;
+ friend class ::CVC4::theory::quantifiers::TermGenEnv;
typedef context::CDHashMap<Node, int, NodeHashFunction> NodeIntMap;
private:
/** reference to the quantifiers engine */
@@ -139,8 +188,8 @@ private:
std::hash_set< Node, NodeHashFunction > d_iclosure_processed;
/** select op map */
std::map< Node, std::map< TypeNode, Node > > d_par_op_map;
- /** set has term */
- void setHasTerm( Node n );
+ /** whether master equality engine is UF-inconsistent */
+ bool d_consistent_ee;
public:
TermDb( context::Context* c, context::UserContext* u, QuantifiersEngine* qe );
~TermDb(){}
@@ -150,13 +199,19 @@ public:
/** constants */
Node d_zero;
Node d_one;
-
+public:
+ /** presolve (called once per user check-sat) */
+ void presolve();
+ /** reset (calculate which terms are active) */
+ bool reset( Theory::Effort effort );
+ /** identify */
+ std::string identify() const { return "TermDb"; }
+private:
/** map from operators to ground terms for that operator */
std::map< Node, std::vector< Node > > d_op_map;
/** map from type nodes to terms of that type */
std::map< TypeNode, std::vector< Node > > d_type_map;
-
/** count number of non-redundant ground terms per operator */
std::map< Node, int > d_op_nonred_count;
/**mapping from UF terms to representatives of their arguments */
@@ -164,41 +219,53 @@ public:
/** map from operators to trie */
std::map< Node, TermArgTrie > d_func_map_trie;
std::map< Node, TermArgTrie > d_func_map_eqc_trie;
+ /** mapping from operators to their representative relevant domains */
+ std::map< Node, std::map< unsigned, std::vector< Node > > > d_func_map_rel_dom;
/** has map */
std::map< Node, bool > d_has_map;
/** map from reps to a term in eqc in d_has_map */
- std::map< Node, Node > d_term_elig_eqc;
-
+ std::map< Node, Node > d_term_elig_eqc;
+ /** set has term */
+ void setHasTerm( Node n );
+ /** evaluate term */
+ Node evaluateTerm2( TNode n, std::map< TNode, Node >& visited, EqualityQuery * qy );
+ TNode getEntailedTerm2( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool hasSubs, EqualityQuery * qy );
+ bool isEntailed2( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool hasSubs, bool pol, EqualityQuery * qy );
public:
/** ground terms for operator */
unsigned getNumGroundTerms( Node f );
/** get ground term for operator */
Node getGroundTerm( Node f, unsigned i );
+ /** get num type terms */
+ unsigned getNumTypeGroundTerms( TypeNode tn );
+ /** get type ground term */
+ Node getTypeGroundTerm( TypeNode tn, unsigned i );
/** add a term to the database */
void addTerm( Node n, std::set< Node >& added, bool withinQuant = false, bool withinInstClosure = false );
- /** presolve (called once per user check-sat) */
- void presolve();
- /** reset (calculate which terms are active) */
- void reset( Theory::Effort effort );
- /** get operator*/
- Node getOperator( Node n );
+ /** get match operator */
+ Node getMatchOperator( Node n );
/** get term arg index */
TermArgTrie * getTermArgTrie( Node f );
TermArgTrie * getTermArgTrie( Node eqc, Node f );
/** exists term */
- TNode existsTerm( Node f, Node n );
+ TNode getCongruentTerm( Node f, Node n );
+ TNode getCongruentTerm( Node f, std::vector< TNode >& args );
/** compute arg reps */
void computeArgReps( TNode n );
/** compute uf eqc terms */
void computeUfEqcTerms( TNode f );
+ /** in relevant domain */
+ bool inRelevantDomain( TNode f, unsigned i, TNode r );
/** evaluate a term under a substitution. Return representative in EE if possible.
* subsRep is whether subs contains only representatives
*/
- TNode evaluateTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep );
- /** same as above, but without substitution */
- TNode evaluateTerm( TNode n );
+ Node evaluateTerm( TNode n, EqualityQuery * qy = NULL );
+ /** get entailed term, does not construct new terms, less aggressive */
+ TNode getEntailedTerm( TNode n, EqualityQuery * qy = NULL );
+ TNode getEntailedTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep, EqualityQuery * qy = NULL );
/** is entailed (incomplete check) */
- bool isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol );
+ bool isEntailed( TNode n, bool pol, EqualityQuery * qy = NULL );
+ bool isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol, EqualityQuery * qy = NULL );
/** has term */
bool hasTermCurrent( Node n, bool useMode = true );
/** is term eligble for instantiation? */
@@ -248,7 +315,7 @@ public:
/** get the i^th instantiation constant of q */
Node getInstantiationConstant( Node q, int i ) const;
/** get number of instantiation constants for q */
- int getNumInstantiationConstants( Node q ) const;
+ unsigned getNumInstantiationConstants( Node q ) const;
/** get the ce body q[e/x] */
Node getInstConstantBody( Node q );
/** get counterexample literal (for cbqi) */
@@ -318,26 +385,26 @@ public:
//for triggers
private:
/** helper function for compute var contains */
- void computeVarContains2( Node n, std::vector< Node >& varContains, std::map< Node, bool >& visited );
+ static void computeVarContains2( Node n, std::vector< Node >& varContains, std::map< Node, bool >& visited );
/** triggers for each operator */
std::map< Node, std::vector< inst::Trigger* > > d_op_triggers;
/** helper for is instance of */
- bool isUnifiableInstanceOf( Node n1, Node n2, std::map< Node, Node >& subs );
+ static bool isUnifiableInstanceOf( Node n1, Node n2, std::map< Node, Node >& subs );
/** -1: n1 is an instance of n2, 1: n1 is an instance of n2 */
- int isInstanceOf2( Node n1, Node n2, std::vector< Node >& varContains1, std::vector< Node >& varContains2 );
+ static int isInstanceOf2( Node n1, Node n2, std::vector< Node >& varContains1, std::vector< Node >& varContains2 );
public:
/** compute var contains */
- void computeVarContains( Node n, std::vector< Node >& varContains );
+ static void computeVarContains( Node n, std::vector< Node >& varContains );
/** get var contains for each of the patterns in pats */
- void getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains );
+ static void getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains );
/** get var contains for node n */
- void getVarContainsNode( Node f, Node n, std::vector< Node >& varContains );
- /** register trigger (for eager quantifier instantiation) */
- void registerTrigger( inst::Trigger* tr, Node op );
+ static void getVarContainsNode( Node f, Node n, std::vector< Node >& varContains );
/** -1: n1 is an instance of n2, 1: n1 is an instance of n2 */
- int isInstanceOf( Node n1, Node n2 );
+ static int isInstanceOf( Node n1, Node n2 );
/** filter all nodes that have instances */
- void filterInstances( std::vector< Node >& nodes );
+ static void filterInstances( std::vector< Node >& nodes );
+ /** register trigger (for eager quantifier instantiation) */
+ void registerTrigger( inst::Trigger* tr, Node op );
//for term ordering
private:
@@ -390,14 +457,14 @@ public:
bool containsVtsTerm( std::vector< Node >& n, bool isFree = false );
/** simple check for contains term */
bool containsVtsInfinity( Node n, bool isFree = false );
- /** make type */
- static Node mkNodeType( Node n, TypeNode tn );
-
+ /** ensure type */
+ static Node ensureType( Node n, TypeNode tn );
+ /** get ensure type condition */
+ static bool getEnsureTypeCondition( Node n, TypeNode tn, std::vector< Node >& cond );
private:
//helper for contains term
static bool containsTerm2( Node n, Node t, std::map< Node, bool >& visited );
static bool containsTerms2( Node n, std::vector< Node >& t, std::map< Node, bool >& visited );
- static bool containsUninterpretedConstant2( Node n, std::map< Node, bool >& visited );
//general utilities
public:
/** simple check for whether n contains t as subterm */
@@ -406,6 +473,8 @@ public:
static bool containsTerms( Node n, std::vector< Node >& t );
/** contains uninterpreted constant */
static bool containsUninterpretedConstant( Node n );
+ /** get the term depth of n */
+ static int getTermDepth( Node n );
/** simple negate */
static Node simpleNegate( Node n );
/** is assoc */
@@ -440,15 +509,11 @@ public: //general queries concerning quantified formulas wrt modules
static Node getFunDefHead( Node q );
/** get fun def body */
static Node getFunDefBody( Node q );
+ /** is quant elim annotation */
+ static bool isQuantElimAnnotation( Node ipl );
//attributes
private:
- std::map< Node, bool > d_qattr_conjecture;
- std::map< Node, bool > d_qattr_axiom;
- std::map< Node, bool > d_qattr_fundef;
- std::map< Node, bool > d_qattr_sygus;
- std::map< Node, bool > d_qattr_synthesis;
- std::map< Node, int > d_qattr_rr_priority;
- std::map< Node, int > d_qattr_qinstLevel;
+ std::map< Node, QAttributes > d_qattr;
//record attributes
void computeAttributes( Node q );
public:
@@ -466,7 +531,12 @@ public:
int getQAttrQuantInstLevel( Node q );
/** get rewrite rule priority */
int getQAttrRewriteRulePriority( Node q );
-
+ /** is quant elim */
+ bool isQAttrQuantElim( Node q );
+ /** is quant elim partial */
+ bool isQAttrQuantElimPartial( Node q );
+ /** compute quantifier attributes */
+ static void computeQuantAttributes( Node q, QAttributes& qa );
};/* class TermDb */
class TermDbSygus {
diff --git a/src/theory/quantifiers/theory_quantifiers.cpp b/src/theory/quantifiers/theory_quantifiers.cpp
index 86fc057ea..efe40aaa8 100644
--- a/src/theory/quantifiers/theory_quantifiers.cpp
+++ b/src/theory/quantifiers/theory_quantifiers.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_quantifiers.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the theory of quantifiers
**
@@ -47,6 +47,8 @@ TheoryQuantifiers::TheoryQuantifiers(Context* c, context::UserContext* u, Output
out.handleUserAttribute( "synthesis", this );
out.handleUserAttribute( "quant-inst-max-level", this );
out.handleUserAttribute( "rr-priority", this );
+ out.handleUserAttribute( "quant-elim", this );
+ out.handleUserAttribute( "quant-elim-partial", this );
}
TheoryQuantifiers::~TheoryQuantifiers() {
diff --git a/src/theory/quantifiers/theory_quantifiers.h b/src/theory/quantifiers/theory_quantifiers.h
index 6335349b1..6775e0536 100644
--- a/src/theory/quantifiers/theory_quantifiers.h
+++ b/src/theory/quantifiers/theory_quantifiers.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_quantifiers.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Francois Bobot, Dejan Jovanovic, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory of quantifiers.
**
diff --git a/src/theory/quantifiers/theory_quantifiers_type_rules.h b/src/theory/quantifiers/theory_quantifiers_type_rules.h
index 1fb8ddaf9..6ba57afb4 100644
--- a/src/theory/quantifiers/theory_quantifiers_type_rules.h
+++ b/src/theory/quantifiers/theory_quantifiers_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_quantifiers_type_rules.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory of quantifiers
**
diff --git a/src/theory/quantifiers/trigger.cpp b/src/theory/quantifiers/trigger.cpp
index 9aee18317..38635b37b 100644
--- a/src/theory/quantifiers/trigger.cpp
+++ b/src/theory/quantifiers/trigger.cpp
@@ -1,60 +1,67 @@
/********************* */
/*! \file trigger.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot, Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of trigger class
**/
#include "theory/quantifiers/trigger.h"
-
-#include "options/quantifiers_options.h"
#include "theory/quantifiers/candidate_generator.h"
#include "theory/quantifiers/inst_match_generator.h"
#include "theory/quantifiers/term_database.h"
#include "theory/quantifiers_engine.h"
#include "theory/theory_engine.h"
#include "theory/uf/equality_engine.h"
+#include "util/hash.h"
+
using namespace std;
-using namespace CVC4;
using namespace CVC4::kind;
using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::inst;
+
+namespace CVC4 {
+namespace theory {
+namespace inst {
+
+void TriggerTermInfo::init( Node q, Node n, int reqPol, Node reqPolEq ){
+ if( d_fv.empty() ){
+ quantifiers::TermDb::getVarContainsNode( q, n, d_fv );
+ }
+ if( d_reqPol==0 ){
+ d_reqPol = reqPol;
+ d_reqPolEq = reqPolEq;
+ }else{
+ //determined a ground (dis)equality must hold or else q is a tautology?
+ }
+}
/** trigger class constructor */
-Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool smartTriggers ) :
-d_quantEngine( qe ), d_f( f ){
+Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption )
+ : d_quantEngine( qe ), d_f( f )
+{
d_nodes.insert( d_nodes.begin(), nodes.begin(), nodes.end() );
Trace("trigger") << "Trigger for " << f << ": " << std::endl;
- for( int i=0; i<(int)d_nodes.size(); i++ ){
+ for( unsigned i=0; i<d_nodes.size(); i++ ){
Trace("trigger") << " " << d_nodes[i] << std::endl;
}
- Trace("trigger-debug") << ", smart triggers = " << smartTriggers;
- Trace("trigger") << std::endl;
- if( smartTriggers ){
- if( d_nodes.size()==1 ){
- if( isSimpleTrigger( d_nodes[0] ) ){
- d_mg = new InstMatchGeneratorSimple( f, d_nodes[0] );
- }else{
- d_mg = InstMatchGenerator::mkInstMatchGenerator( f, d_nodes[0], qe );
- d_mg->setActiveAdd(true);
- }
+ if( d_nodes.size()==1 ){
+ if( isSimpleTrigger( d_nodes[0] ) ){
+ d_mg = new InstMatchGeneratorSimple( f, d_nodes[0] );
}else{
- d_mg = new InstMatchGeneratorMulti( f, d_nodes, qe );
- //d_mg = InstMatchGenerator::mkInstMatchGenerator( d_nodes, qe );
- //d_mg->setActiveAdd();
+ d_mg = InstMatchGenerator::mkInstMatchGenerator( f, d_nodes[0], qe );
+ d_mg->setActiveAdd(true);
}
}else{
- d_mg = InstMatchGenerator::mkInstMatchGenerator( f, d_nodes, qe );
- d_mg->setActiveAdd(true);
+ d_mg = new InstMatchGeneratorMulti( f, d_nodes, qe );
+ //d_mg = InstMatchGenerator::mkInstMatchGenerator( d_nodes, qe );
+ //d_mg->setActiveAdd();
}
if( d_nodes.size()==1 ){
if( isSimpleTrigger( d_nodes[0] ) ){
@@ -63,23 +70,26 @@ d_quantEngine( qe ), d_f( f ){
++(qe->d_statistics.d_simple_triggers);
}
}else{
- Trace("multi-trigger") << "Multi-trigger ";
- debugPrint("multi-trigger");
- Trace("multi-trigger") << " for " << f << std::endl;
- //Notice() << "Multi-trigger for " << f << " : " << std::endl;
- //Notice() << " " << (*this) << std::endl;
+ Trace("multi-trigger") << "Trigger for " << f << ": " << std::endl;
+ for( unsigned i=0; i<d_nodes.size(); i++ ){
+ Trace("multi-trigger") << " " << d_nodes[i] << std::endl;
+ }
++(qe->d_statistics.d_multi_triggers);
}
//Notice() << "Trigger : " << (*this) << " for " << f << std::endl;
if( options::eagerInstQuant() ){
for( int i=0; i<(int)d_nodes.size(); i++ ){
- Node op = qe->getTermDatabase()->getOperator( d_nodes[i] );
+ Node op = qe->getTermDatabase()->getMatchOperator( d_nodes[i] );
qe->getTermDatabase()->registerTrigger( this, op );
}
}
Trace("trigger-debug") << "Finished making trigger." << std::endl;
}
+Trigger::~Trigger() {
+ if(d_mg != NULL) { delete d_mg; }
+}
+
void Trigger::resetInstantiationRound(){
d_mg->resetInstantiationRound( d_quantEngine );
}
@@ -114,8 +124,7 @@ int Trigger::addInstantiations( InstMatch& baseMatch ){
return addedLemmas;
}
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption,
- bool smartTriggers ){
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption ){
std::vector< Node > trNodes;
if( !keepAll ){
//only take nodes that contribute variables to the trigger when added
@@ -125,7 +134,7 @@ Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >&
std::map< Node, std::vector< Node > > patterns;
size_t varCount = 0;
std::map< Node, std::vector< Node > > varContains;
- qe->getTermDatabase()->getVarContains( f, temp, varContains );
+ quantifiers::TermDb::getVarContains( f, temp, varContains );
for( unsigned i=0; i<temp.size(); i++ ){
bool foundVar = false;
for( unsigned j=0; j<varContains[ temp[i] ].size(); j++ ){
@@ -202,21 +211,21 @@ Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >&
}
}
}
- Trigger* t = new Trigger( qe, f, trNodes, matchOption, smartTriggers );
+ Trigger* t = new Trigger( qe, f, trNodes, matchOption );
qe->getTriggerDatabase()->addTrigger( trNodes, t );
return t;
}
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption, bool smartTriggers ){
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption ){
std::vector< Node > nodes;
nodes.push_back( n );
- return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption, smartTriggers );
+ return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption );
}
bool Trigger::isUsable( Node n, Node q ){
if( quantifiers::TermDb::getInstConstAttr(n)==q ){
if( isAtomicTrigger( n ) ){
- for( int i=0; i<(int)n.getNumChildren(); i++ ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
if( !isUsable( n[i], q ) ){
return false;
}
@@ -241,67 +250,91 @@ bool Trigger::isUsable( Node n, Node q ){
}
}
-Node Trigger::getIsUsableTrigger( Node n, Node f, bool pol, bool hasPol ) {
+Node Trigger::getIsUsableEq( Node q, Node n ) {
+ Assert( isRelationalTrigger( n ) );
+ for( unsigned i=0; i<2; i++) {
+ if( isUsableEqTerms( q, n[i], n[1-i] ) ){
+ if( i==1 && ( n.getKind()==EQUAL || n.getKind()==IFF ) && !quantifiers::TermDb::hasInstConstAttr(n[0]) ){
+ return NodeManager::currentNM()->mkNode( n.getKind(), n[1], n[0] );
+ }else{
+ return n;
+ }
+ }
+ }
+ return Node::null();
+}
+
+bool Trigger::isUsableEqTerms( Node q, Node n1, Node n2 ) {
+ if( n1.getKind()==INST_CONSTANT ){
+ if( options::relationalTriggers() ){
+ if( !quantifiers::TermDb::hasInstConstAttr(n2) ){
+ return true;
+ }else if( n2.getKind()==INST_CONSTANT ){
+ return true;
+ }
+ }
+ }else if( isAtomicTrigger( n1 ) && isUsable( n1, q ) ){
+ if( options::relationalTriggers() && n2.getKind()==INST_CONSTANT && !quantifiers::TermDb::containsTerm( n1, n2 ) ){
+ return true;
+ }else if( !quantifiers::TermDb::hasInstConstAttr(n2) ){
+ return true;
+ }
+ }
+ return false;
+}
+
+Node Trigger::getIsUsableTrigger( Node n, Node q ) {
+ bool pol = true;
Trace("trigger-debug") << "Is " << n << " a usable trigger?" << std::endl;
if( n.getKind()==NOT ){
pol = !pol;
n = n[0];
}
- if( options::relationalTriggers() ){
- if( n.getKind()==EQUAL || n.getKind()==IFF || n.getKind()==GEQ ){
- Node rtr;
- bool do_negate = hasPol && pol;
- bool is_arith = n[0].getType().isReal();
- for( unsigned i=0; i<2; i++) {
- if( n[1-i].getKind()==INST_CONSTANT ){
- if( isUsableTrigger( n[i], f ) && !quantifiers::TermDb::containsTerm( n[i], n[1-i] ) && ( !do_negate || is_arith ) ){
- rtr = n;
- break;
- }
- if( n[i].getKind()==INST_CONSTANT && ( !hasPol || pol ) ){
- do_negate = true;
- rtr = n;
- break;
+ if( n.getKind()==INST_CONSTANT ){
+ return pol ? n : NodeManager::currentNM()->mkNode( IFF, n, NodeManager::currentNM()->mkConst( true ) ).notNode();
+ }else if( isRelationalTrigger( n ) ){
+ Node rtr = getIsUsableEq( q, n );
+ if( rtr.isNull() && n[0].getType().isReal() ){
+ //try to solve relation
+ std::map< Node, Node > m;
+ if( QuantArith::getMonomialSumLit(n, m) ){
+ for( std::map< Node, Node >::iterator it = m.begin(); it!=m.end(); ++it ){
+ bool trySolve = false;
+ if( !it->first.isNull() ){
+ if( it->first.getKind()==INST_CONSTANT ){
+ trySolve = options::relationalTriggers();
+ }else if( isUsableTrigger( it->first, q ) ){
+ trySolve = true;
+ }
}
- }
- }
- if( is_arith ){
- //try to rearrange?
- std::map< Node, Node > m;
- if( QuantArith::getMonomialSumLit(n, m) ){
- for( std::map< Node, Node >::iterator it = m.begin(); it!=m.end(); ++it ){
- if( !it->first.isNull() && it->first.getKind()==INST_CONSTANT ){
- Node veq;
- if( QuantArith::isolate( it->first, m, veq, n.getKind() )!=0 ){
- int vti = veq[0]==it->first ? 1 : 0;
- if( isUsableTrigger( veq[vti], f ) && !quantifiers::TermDb::containsTerm( veq[vti], veq[1-vti] ) ){
- rtr = veq;
- }
- }
+ if( trySolve ){
+ Trace("trigger-debug") << "Try to solve for " << it->first << std::endl;
+ Node veq;
+ if( QuantArith::isolate( it->first, m, veq, n.getKind() )!=0 ){
+ rtr = getIsUsableEq( q, veq );
}
+ //either all solves will succeed or all solves will fail
+ break;
}
}
}
- if( !rtr.isNull() ){
- Trace("relational-trigger") << "Relational trigger : " << std::endl;
- Trace("relational-trigger") << " " << rtr << " (from " << n << ")" << std::endl;
- Trace("relational-trigger") << " in quantifier " << f << std::endl;
- if( hasPol ){
- Trace("relational-trigger") << " polarity : " << pol << std::endl;
- }
- Node rtr2 = do_negate ? rtr.negate() : rtr;
- Trace("relational-trigger") << " return : " << rtr2 << std::endl;
- return rtr2;
- }
}
- }
- bool usable = quantifiers::TermDb::getInstConstAttr(n)==f && isAtomicTrigger( n ) && isUsable( n, f );
- Trace("trigger-debug") << n << " usable : " << (quantifiers::TermDb::getInstConstAttr(n)==f) << " " << isAtomicTrigger( n ) << " " << isUsable( n, f ) << std::endl;
- if( usable ){
- return n;
+ if( !rtr.isNull() ){
+ Trace("relational-trigger") << "Relational trigger : " << std::endl;
+ Trace("relational-trigger") << " " << rtr << " (from " << n << ")" << std::endl;
+ Trace("relational-trigger") << " in quantifier " << q << std::endl;
+ Node rtr2 = pol ? rtr : rtr.negate();
+ Trace("relational-trigger") << " return : " << rtr2 << std::endl;
+ return rtr2;
+ }
}else{
- return Node::null();
+ bool usable = quantifiers::TermDb::getInstConstAttr(n)==q && isAtomicTrigger( n ) && isUsable( n, q );
+ Trace("trigger-debug") << n << " usable : " << (quantifiers::TermDb::getInstConstAttr(n)==q) << " " << isAtomicTrigger( n ) << " " << isUsable( n, q ) << std::endl;
+ if( usable ){
+ return pol ? n : NodeManager::currentNM()->mkNode( IFF, n, NodeManager::currentNM()->mkConst( true ) ).notNode();
+ }
}
+ return Node::null();
}
bool Trigger::isUsableTrigger( Node n, Node q ){
@@ -321,19 +354,33 @@ bool Trigger::isAtomicTriggerKind( Kind k ) {
k==UNION || k==INTERSECTION || k==SUBSET || k==SETMINUS || k==MEMBER || k==SINGLETON;
}
+bool Trigger::isRelationalTrigger( Node n ) {
+ return isRelationalTriggerKind( n.getKind() );
+}
+
+bool Trigger::isRelationalTriggerKind( Kind k ) {
+ return k==EQUAL || k==IFF || k==GEQ;
+}
+
bool Trigger::isCbqiKind( Kind k ) {
return quantifiers::TermDb::isBoolConnective( k ) || k==PLUS || k==GEQ || k==EQUAL || k==MULT ||
k==APPLY_CONSTRUCTOR || k==APPLY_SELECTOR_TOTAL || k==APPLY_TESTER;
}
bool Trigger::isSimpleTrigger( Node n ){
- if( isAtomicTrigger( n ) ){
- for( int i=0; i<(int)n.getNumChildren(); i++ ){
- if( n[i].getKind()!=INST_CONSTANT && quantifiers::TermDb::hasInstConstAttr(n[i]) ){
+ Node t = n.getKind()==NOT ? n[0] : n;
+ if( n.getKind()==IFF || n.getKind()==EQUAL ){
+ if( !quantifiers::TermDb::hasInstConstAttr( n[1] ) ){
+ t = n[0];
+ }
+ }
+ if( isAtomicTrigger( t ) ){
+ for( unsigned i=0; i<t.getNumChildren(); i++ ){
+ if( t[i].getKind()!=INST_CONSTANT && quantifiers::TermDb::hasInstConstAttr(t[i]) ){
return false;
}
}
- if( options::purifyDtTriggers() && n.getKind()==APPLY_SELECTOR_TOTAL ){
+ if( options::purifyDtTriggers() && t.getKind()==APPLY_SELECTOR_TOTAL ){
return false;
}
return true;
@@ -342,69 +389,101 @@ bool Trigger::isSimpleTrigger( Node n ){
}
}
-
-bool Trigger::collectPatTerms2( Node f, Node n, std::map< Node, bool >& patMap, int tstrt, std::vector< Node >& exclude, bool pol, bool hasPol ){
- if( patMap.find( n )==patMap.end() ){
- patMap[ n ] = false;
- if( tstrt==TS_MIN_TRIGGER ){
- if( n.getKind()==FORALL ){
- return false;
- }else{
- bool retVal = false;
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- bool newHasPol, newPol;
- QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );
- if( collectPatTerms2( f, n[i], patMap, tstrt, exclude, newPol, newHasPol ) ){
- retVal = true;
+//store triggers in reqPol, indicating their polarity (if any) they must appear to falsify the quantified formula
+bool Trigger::collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, std::map< Node, TriggerTermInfo >& tinfo,
+ quantifiers::TriggerSelMode tstrt, std::vector< Node >& exclude, std::vector< Node >& added,
+ bool pol, bool hasPol, bool epol, bool hasEPol ){
+ std::map< Node, Node >::iterator itv = visited.find( n );
+ if( itv==visited.end() ){
+ visited[ n ] = Node::null();
+ Trace("auto-gen-trigger-debug2") << "Collect pat terms " << n << " " << pol << " " << hasPol << " " << epol << " " << hasEPol << std::endl;
+ bool retVal = false;
+ if( n.getKind()!=FORALL && n.getKind()!=INST_CONSTANT ){
+ bool rec = true;
+ Node nu;
+ bool nu_single = false;
+ if( n.getKind()!=NOT && std::find( exclude.begin(), exclude.end(), n )==exclude.end() ){
+ nu = getIsUsableTrigger( n, q );
+ if( !nu.isNull() ){
+ Assert( nu.getKind()!=NOT );
+ Trace("auto-gen-trigger-debug2") << "...found usable trigger : " << nu << std::endl;
+ Node reqEq;
+ if( nu.getKind()==IFF || nu.getKind()==EQUAL ){
+ if( isAtomicTrigger( nu[0] ) && !quantifiers::TermDb::hasInstConstAttr(nu[1]) ){
+ if( hasPol ){
+ reqEq = nu[1];
+ }
+ nu = nu[0];
+ }
}
- }
- if( retVal ){
- return true;
- }else{
- Node nu;
- if( std::find( exclude.begin(), exclude.end(), n )==exclude.end() ){
- nu = getIsUsableTrigger( n, f, pol, hasPol );
+ Assert( reqEq.isNull() || !quantifiers::TermDb::hasInstConstAttr( reqEq ) );
+ Assert( isUsableTrigger( nu, q ) );
+ //do not add if already excluded
+ bool add = true;
+ if( n!=nu ){
+ std::map< Node, Node >::iterator itvu = visited.find( nu );
+ if( itvu!=visited.end() && itvu->second.isNull() ){
+ add = false;
+ }
}
- if( !nu.isNull() ){
- patMap[ nu ] = true;
- return true;
- }else{
- return false;
+ if( add ){
+ Trace("auto-gen-trigger-debug2") << "...add usable trigger : " << nu << std::endl;
+ visited[ nu ] = nu;
+ tinfo[ nu ].init( q, nu, hasEPol ? ( epol ? 1 : -1 ) : 0, reqEq );
+ nu_single = tinfo[ nu ].d_fv.size()==q[0].getNumChildren();
+ retVal = true;
+ if( tstrt==quantifiers::TRIGGER_SEL_MAX || ( tstrt==quantifiers::TRIGGER_SEL_MIN_SINGLE_MAX && !nu_single ) ){
+ rec = false;
+ }
}
}
}
- }else{
- bool retVal = false;
- Node nu;
- if( std::find( exclude.begin(), exclude.end(), n )==exclude.end() ){
- nu = getIsUsableTrigger( n, f, pol, hasPol );
- }
- if( !nu.isNull() ){
- patMap[ nu ] = true;
- if( tstrt==TS_MAX_TRIGGER ){
- return true;
- }else{
- retVal = true;
- }
- }
- if( n.getKind()!=FORALL ){
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ if( rec ){
+ Node nrec = nu.isNull() ? n : nu;
+ std::vector< Node > added2;
+ for( unsigned i=0; i<nrec.getNumChildren(); i++ ){
bool newHasPol, newPol;
- QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );
- if( collectPatTerms2( f, n[i], patMap, tstrt, exclude, newPol, newHasPol ) ){
+ bool newHasEPol, newEPol;
+ QuantPhaseReq::getPolarity( nrec, i, hasPol, pol, newHasPol, newPol );
+ QuantPhaseReq::getEntailPolarity( nrec, i, hasEPol, epol, newHasEPol, newEPol );
+ if( collectPatTerms2( q, nrec[i], visited, tinfo, tstrt, exclude, added2, newPol, newHasPol, newEPol, newHasEPol ) ){
retVal = true;
}
}
+ if( !nu.isNull() ){
+ bool rm_nu = false;
+ //discard if we added a subterm as a trigger with all variables that nu has
+ for( unsigned i=0; i<added2.size(); i++ ){
+ Assert( tinfo.find( added2[i] )!=tinfo.end() );
+ if( added2[i]!=nu ){
+ if( tinfo[ nu ].d_fv.size()==tinfo[ added2[i] ].d_fv.size() ){
+ rm_nu = true;
+ }
+ added.push_back( added2[i] );
+ }else{
+ Assert( false );
+ }
+ }
+ if( rm_nu && ( tstrt==quantifiers::TRIGGER_SEL_MIN || ( tstrt==quantifiers::TRIGGER_SEL_MIN_SINGLE_ALL && nu_single ) ) ){
+ visited[nu] = Node::null();
+ tinfo.erase( nu );
+ }else{
+ added.push_back( nu );
+ }
+ }
}
- return retVal;
}
+ return retVal;
}else{
- return patMap[ n ];
+ if( itv->second.isNull() ){
+ return false;
+ }else{
+ added.push_back( itv->second );
+ return true;
+ }
}
}
-
-
bool Trigger::isBooleanTermTrigger( Node n ) {
if( n.getKind()==ITE ){
//check for boolean term converted to ITE
@@ -434,6 +513,23 @@ bool Trigger::isPureTheoryTrigger( Node n ) {
}
}
+int Trigger::getTriggerWeight( Node n ) {
+ if( isAtomicTrigger( n ) ){
+ return 0;
+ }else{
+ if( options::relationalTriggers() ){
+ if( isRelationalTrigger( n ) ){
+ for( unsigned i=0; i<2; i++ ){
+ if( n[i].getKind()==INST_CONSTANT && !quantifiers::TermDb::hasInstConstAttr( n[1-i] ) ){
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+ }
+}
+
bool Trigger::isLocalTheoryExt( Node n, std::vector< Node >& vars, std::vector< Node >& patTerms ) {
if( !n.getType().isBoolean() && n.getKind()==APPLY_UF ){
if( std::find( patTerms.begin(), patTerms.end(), n )==patTerms.end() ){
@@ -466,42 +562,51 @@ bool Trigger::isLocalTheoryExt( Node n, std::vector< Node >& vars, std::vector<
return true;
}
-void Trigger::collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, std::vector< Node >& exclude, bool filterInst ){
- std::map< Node, bool > patMap;
+void Trigger::collectPatTerms( Node q, Node n, std::vector< Node >& patTerms, quantifiers::TriggerSelMode tstrt, std::vector< Node >& exclude,
+ std::map< Node, TriggerTermInfo >& tinfo, bool filterInst ){
+ std::map< Node, Node > visited;
if( filterInst ){
//immediately do not consider any term t for which another term is an instance of t
std::vector< Node > patTerms2;
- collectPatTerms( qe, f, n, patTerms2, TS_ALL, exclude, false );
+ std::map< Node, TriggerTermInfo > tinfo2;
+ collectPatTerms( q, n, patTerms2, quantifiers::TRIGGER_SEL_ALL, exclude, tinfo2, false );
std::vector< Node > temp;
temp.insert( temp.begin(), patTerms2.begin(), patTerms2.end() );
- qe->getTermDatabase()->filterInstances( temp );
+ quantifiers::TermDb::filterInstances( temp );
if( temp.size()!=patTerms2.size() ){
Trace("trigger-filter-instance") << "Filtered an instance: " << std::endl;
Trace("trigger-filter-instance") << "Old: ";
- for( int i=0; i<(int)patTerms2.size(); i++ ){
+ for( unsigned i=0; i<patTerms2.size(); i++ ){
Trace("trigger-filter-instance") << patTerms2[i] << " ";
}
Trace("trigger-filter-instance") << std::endl << "New: ";
- for( int i=0; i<(int)temp.size(); i++ ){
+ for( unsigned i=0; i<temp.size(); i++ ){
Trace("trigger-filter-instance") << temp[i] << " ";
}
Trace("trigger-filter-instance") << std::endl;
}
- if( tstrt==TS_ALL ){
- patTerms.insert( patTerms.begin(), temp.begin(), temp.end() );
+ if( tstrt==quantifiers::TRIGGER_SEL_ALL ){
+ for( unsigned i=0; i<temp.size(); i++ ){
+ //copy information
+ tinfo[temp[i]].d_fv.insert( tinfo[temp[i]].d_fv.end(), tinfo2[temp[i]].d_fv.begin(), tinfo2[temp[i]].d_fv.end() );
+ tinfo[temp[i]].d_reqPol = tinfo2[temp[i]].d_reqPol;
+ tinfo[temp[i]].d_reqPolEq = tinfo2[temp[i]].d_reqPolEq;
+ patTerms.push_back( temp[i] );
+ }
return;
}else{
//do not consider terms that have instances
- for( int i=0; i<(int)patTerms2.size(); i++ ){
+ for( unsigned i=0; i<patTerms2.size(); i++ ){
if( std::find( temp.begin(), temp.end(), patTerms2[i] )==temp.end() ){
- patMap[ patTerms2[i] ] = false;
+ visited[ patTerms2[i] ] = Node::null();
}
}
}
}
- collectPatTerms2( f, n, patMap, tstrt, exclude, true, true );
- for( std::map< Node, bool >::iterator it = patMap.begin(); it != patMap.end(); ++it ){
- if( it->second ){
+ std::vector< Node > added;
+ collectPatTerms2( q, n, visited, tinfo, tstrt, exclude, added, true, true, false, true );
+ for( std::map< Node, TriggerTermInfo >::iterator it = tinfo.begin(); it != tinfo.end(); ++it ){
+ if( !visited[it->first].isNull() ){
patTerms.push_back( it->first );
}
}
@@ -582,14 +687,15 @@ Node Trigger::getInversion( Node n, Node x ) {
return Node::null();
}
-void Trigger::getTriggerVariables( QuantifiersEngine* qe, Node icn, Node f, std::vector< Node >& t_vars ) {
+void Trigger::getTriggerVariables( Node icn, Node q, std::vector< Node >& t_vars ) {
std::vector< Node > patTerms;
+ std::map< Node, TriggerTermInfo > tinfo;
//collect all patterns from icn
std::vector< Node > exclude;
- collectPatTerms( qe, f, icn, patTerms, TS_ALL, exclude );
+ collectPatTerms( q, icn, patTerms, quantifiers::TRIGGER_SEL_ALL, exclude, tinfo );
//collect all variables from all patterns in patTerms, add to t_vars
for( unsigned i=0; i<patTerms.size(); i++ ){
- qe->getTermDatabase()->getVarContainsNode( f, patTerms[i], t_vars );
+ quantifiers::TermDb::getVarContainsNode( q, patTerms[i], t_vars );
}
}
@@ -621,7 +727,7 @@ InstMatchGenerator* Trigger::getInstMatchGenerator( Node q, Node n ) {
Trigger* TriggerTrie::getTrigger2( std::vector< Node >& nodes ){
if( nodes.empty() ){
- return d_tr;
+ return d_tr.empty() ? NULL : d_tr[0];
}else{
Node n = nodes.back();
nodes.pop_back();
@@ -635,7 +741,7 @@ Trigger* TriggerTrie::getTrigger2( std::vector< Node >& nodes ){
void TriggerTrie::addTrigger2( std::vector< Node >& nodes, Trigger* t ){
if( nodes.empty() ){
- d_tr = t;
+ d_tr.push_back( t );
}else{
Node n = nodes.back();
nodes.pop_back();
@@ -645,3 +751,24 @@ void TriggerTrie::addTrigger2( std::vector< Node >& nodes, Trigger* t ){
d_children[n]->addTrigger2( nodes, t );
}
}
+
+
+TriggerTrie::TriggerTrie()
+{}
+
+TriggerTrie::~TriggerTrie() {
+ for(std::map< TNode, TriggerTrie* >::iterator i = d_children.begin(), iend = d_children.end();
+ i != iend; ++i) {
+ TriggerTrie* current = (*i).second;
+ delete current;
+ }
+ d_children.clear();
+
+ for( unsigned i=0; i<d_tr.size(); i++ ){
+ delete d_tr[i];
+ }
+}
+
+}/* CVC4::theory::inst namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
diff --git a/src/theory/quantifiers/trigger.h b/src/theory/quantifiers/trigger.h
index 11962008e..41f2a1c38 100644
--- a/src/theory/quantifiers/trigger.h
+++ b/src/theory/quantifiers/trigger.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file trigger.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief trigger class
**/
@@ -17,11 +17,13 @@
#ifndef __CVC4__THEORY__QUANTIFIERS__TRIGGER_H
#define __CVC4__THEORY__QUANTIFIERS__TRIGGER_H
-#include "theory/quantifiers/inst_match.h"
-#include "expr/node.h"
-#include "util/hash.h"
#include <map>
+#include "expr/node.h"
+#include "theory/quantifiers/inst_match.h"
+#include "options/quantifiers_options.h"
+
+// Forward declarations for defining the Trigger and TriggerTrie.
namespace CVC4 {
namespace theory {
@@ -31,29 +33,37 @@ namespace inst {
class IMGenerator;
class InstMatchGenerator;
+}/* CVC4::theory::inst namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
-//a collect of nodes representing a trigger
-class Trigger {
-private:
- /** the quantifiers engine */
- QuantifiersEngine* d_quantEngine;
- /** the quantifier this trigger is for */
- Node d_f;
- /** match generators */
- IMGenerator* d_mg;
-private:
- /** trigger constructor */
- Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0, bool smartTriggers = false );
-public:
- ~Trigger(){}
-public:
- std::vector< Node > d_nodes;
+
+namespace CVC4 {
+namespace theory {
+namespace inst {
+
+class TriggerTermInfo {
public:
+ TriggerTermInfo() : d_reqPol(0){}
+ ~TriggerTermInfo(){}
+ std::vector< Node > d_fv;
+ int d_reqPol;
+ Node d_reqPolEq;
+ void init( Node q, Node n, int reqPol = 0, Node reqPolEq = Node::null() );
+};
+
+/** A collect of nodes representing a trigger. */
+class Trigger {
+ public:
+ ~Trigger();
+
IMGenerator* getGenerator() { return d_mg; }
-public:
- /** reset instantiation round (call this whenever equivalence classes have changed) */
+
+ /** reset instantiation round (call this whenever equivalence
+ * classes have changed) */
void resetInstantiationRound();
- /** reset, eqc is the equivalence class to search in (search in any if eqc=null) */
+ /** reset, eqc is the equivalence class to search in (search in any
+ * if eqc=null) */
void reset( Node eqc );
/** get next match. must call reset( eqc ) once before this function. */
bool getNextMatch( Node f, InstMatch& m );
@@ -66,7 +76,7 @@ public:
int addTerm( Node t );
/** return whether this is a multi-trigger */
bool isMultiTrigger() { return d_nodes.size()>1; }
-public:
+
/** add all available instantiations exhaustively, in any equivalence class
if limitInst>0, limitInst is the max # of instantiations to try */
int addInstantiations( InstMatch& baseMatch );
@@ -74,51 +84,46 @@ public:
ie : quantifier engine;
f : forall something ....
nodes : (multi-)trigger
- matchOption : which policy to use for creating matches (one of InstMatchGenerator::MATCH_GEN_* )
+ matchOption : which policy to use for creating matches
+ (one of InstMatchGenerator::MATCH_GEN_* )
keepAll: don't remove unneeded patterns;
- trOption : policy for dealing with triggers that already existed (see below)
+ trOption : policy for dealing with triggers that already existed
+ (see below)
*/
enum{
TR_MAKE_NEW, //make new trigger even if it already may exist
TR_GET_OLD, //return a previous trigger if it had already been created
TR_RETURN_NULL //return null if a duplicate is found
};
- static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes,
- int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
- bool smartTriggers = false );
+ static Trigger* mkTrigger( QuantifiersEngine* qe, Node f,
+ std::vector< Node >& nodes, int matchOption = 0,
+ bool keepAll = true, int trOption = TR_MAKE_NEW );
static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n,
- int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
- bool smartTriggers = false );
-private:
- /** is subterm of trigger usable */
- static bool isUsable( Node n, Node q );
- static Node getIsUsableTrigger( Node n, Node f, bool pol = true, bool hasPol = false );
- /** collect all APPLY_UF pattern terms for f in n */
- static bool collectPatTerms2( Node f, Node n, std::map< Node, bool >& patMap, int tstrt, std::vector< Node >& exclude, bool pol, bool hasPol );
-public:
- //different strategies for choosing trigger terms
- enum {
- TS_MAX_TRIGGER = 0,
- TS_MIN_TRIGGER,
- TS_ALL,
- };
- static void collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, std::vector< Node >& exclude, bool filterInst = false );
-public:
+ int matchOption = 0, bool keepAll = true,
+ int trOption = TR_MAKE_NEW );
+ static void collectPatTerms( Node q, Node n, std::vector< Node >& patTerms, quantifiers::TriggerSelMode tstrt,
+ std::vector< Node >& exclude, std::map< Node, TriggerTermInfo >& tinfo,
+ bool filterInst = false );
/** is usable trigger */
static bool isUsableTrigger( Node n, Node q );
+ static Node getIsUsableTrigger( Node n, Node q );
static bool isAtomicTrigger( Node n );
static bool isAtomicTriggerKind( Kind k );
+ static bool isRelationalTrigger( Node n );
+ static bool isRelationalTriggerKind( Kind k );
static bool isCbqiKind( Kind k );
static bool isSimpleTrigger( Node n );
static bool isBooleanTermTrigger( Node n );
static bool isPureTheoryTrigger( Node n );
- static bool isLocalTheoryExt( Node n, std::vector< Node >& vars, std::vector< Node >& patTerms );
+ static int getTriggerWeight( Node n );
+ static bool isLocalTheoryExt( Node n, std::vector< Node >& vars,
+ std::vector< Node >& patTerms );
/** return data structure for producing matches for this trigger. */
static InstMatchGenerator* getInstMatchGenerator( Node q, Node n );
static Node getInversionVariable( Node n );
static Node getInversion( Node n, Node x );
/** get all variables that E-matching can possibly handle */
- static void getTriggerVariables( QuantifiersEngine* qe, Node icn, Node f, std::vector< Node >& t_vars );
+ static void getTriggerVariables( Node icn, Node f, std::vector< Node >& t_vars );
void debugPrint( const char * c ) {
Trace(c) << "TRIGGER( ";
@@ -128,17 +133,35 @@ public:
}
Trace(c) << " )";
}
-};
+private:
+ /** trigger constructor */
+ Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0 );
+
+ /** is subterm of trigger usable */
+ static bool isUsable( Node n, Node q );
+ static Node getIsUsableEq( Node q, Node eq );
+ static bool isUsableEqTerms( Node q, Node n1, Node n2 );
+ /** collect all APPLY_UF pattern terms for f in n */
+ static bool collectPatTerms2( Node q, Node n, std::map< Node, Node >& visited, std::map< Node, TriggerTermInfo >& tinfo,
+ quantifiers::TriggerSelMode tstrt, std::vector< Node >& exclude, std::vector< Node >& added,
+ bool pol, bool hasPol, bool epol, bool hasEPol );
+
+ std::vector< Node > d_nodes;
+
+ /** the quantifiers engine */
+ QuantifiersEngine* d_quantEngine;
+ /** the quantifier this trigger is for */
+ Node d_f;
+ /** match generators */
+ IMGenerator* d_mg;
+}; /* class Trigger */
/** a trie of triggers */
class TriggerTrie {
-private:
- inst::Trigger* getTrigger2( std::vector< Node >& nodes );
- void addTrigger2( std::vector< Node >& nodes, inst::Trigger* t );
public:
- TriggerTrie() : d_tr( NULL ){}
- inst::Trigger* d_tr;
- std::map< TNode, TriggerTrie* > d_children;
+ TriggerTrie();
+ ~TriggerTrie();
+
inst::Trigger* getTrigger( std::vector< Node >& nodes ){
std::vector< Node > temp;
temp.insert( temp.begin(), nodes.begin(), nodes.end() );
@@ -151,7 +174,13 @@ public:
std::sort( temp.begin(), temp.end() );
return addTrigger2( temp, t );
}
-};/* class inst::Trigger::Trigger */
+private:
+ inst::Trigger* getTrigger2( std::vector< Node >& nodes );
+ void addTrigger2( std::vector< Node >& nodes, inst::Trigger* t );
+
+ std::vector< inst::Trigger* > d_tr;
+ std::map< TNode, TriggerTrie* > d_children;
+};/* class inst::Trigger::TriggerTrie */
}/* CVC4::theory::inst namespace */
}/* CVC4::theory namespace */
diff --git a/src/theory/quantifiers_engine.cpp b/src/theory/quantifiers_engine.cpp
index 6fedc14f0..6d3b17254 100644
--- a/src/theory/quantifiers_engine.cpp
+++ b/src/theory/quantifiers_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_engine.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of quantifiers engine class
**/
@@ -39,6 +39,10 @@
#include "theory/quantifiers/rewrite_engine.h"
#include "theory/quantifiers/term_database.h"
#include "theory/quantifiers/trigger.h"
+#include "theory/quantifiers/quant_split.h"
+#include "theory/quantifiers/anti_skolem.h"
+#include "theory/quantifiers/equality_infer.h"
+#include "theory/quantifiers/inst_propagator.h"
#include "theory/theory_engine.h"
#include "theory/uf/equality_engine.h"
#include "theory/uf/theory_uf.h"
@@ -51,49 +55,40 @@ using namespace CVC4::context;
using namespace CVC4::theory;
using namespace CVC4::theory::inst;
-unsigned QuantifiersModule::needsModel( Theory::Effort e ) {
- return QuantifiersEngine::QEFFORT_NONE;
-}
-
-eq::EqualityEngine * QuantifiersModule::getEqualityEngine() {
- return d_quantEngine->getMasterEqualityEngine();
-}
-
-bool QuantifiersModule::areEqual( TNode n1, TNode n2 ) {
- eq::EqualityEngine * ee = getEqualityEngine();
- return n1==n2 || ( ee->hasTerm( n1 ) && ee->hasTerm( n2 ) && ee->areEqual( n1, n2 ) );
-}
-
-bool QuantifiersModule::areDisequal( TNode n1, TNode n2 ) {
- eq::EqualityEngine * ee = getEqualityEngine();
- return n1!=n2 && ee->hasTerm( n1 ) && ee->hasTerm( n2 ) && ee->areDisequal( n1, n2, false );
-}
-
-TNode QuantifiersModule::getRepresentative( TNode n ) {
- eq::EqualityEngine * ee = getEqualityEngine();
- if( ee->hasTerm( n ) ){
- return ee->getRepresentative( n );
- }else{
- return n;
- }
-}
-
-quantifiers::TermDb * QuantifiersModule::getTermDatabase() {
- return d_quantEngine->getTermDatabase();
-}
-
QuantifiersEngine::QuantifiersEngine(context::Context* c, context::UserContext* u, TheoryEngine* te):
d_te( te ),
+ //d_quants(u),
+ d_quants_red(u),
d_lemmas_produced_c(u),
d_skolemized(u),
+ d_ierCounter_c(c),
+ //d_ierCounter(c),
+ //d_ierCounter_lc(c),
+ //d_ierCounterLastLc(c),
d_presolve(u, true),
d_presolve_in(u),
d_presolve_cache(u),
d_presolve_cache_wq(u),
d_presolve_cache_wic(u){
- d_eq_query = new EqualityQueryQuantifiersEngine( this );
+ //utilities
+ d_eq_query = new EqualityQueryQuantifiersEngine( c, this );
+ d_util.push_back( d_eq_query );
+
d_term_db = new quantifiers::TermDb( c, u, this );
+ d_util.push_back( d_term_db );
+
+ if( options::instPropagate() ){
+ d_inst_prop = new quantifiers::InstPropagator( this );
+ d_util.push_back( d_inst_prop );
+ d_inst_notify.push_back( d_inst_prop->getInstantiationNotify() );
+ }else{
+ d_inst_prop = NULL;
+ }
+
d_tr_trie = new inst::TriggerTrie;
+ d_curr_effort_level = QEFFORT_NONE;
+ d_conflict = false;
+ d_num_added_lemmas_round = 0;
d_hasAddedLemma = false;
//don't add true lemma
d_lemmas_produced_c[d_term_db->d_true] = true;
@@ -121,6 +116,8 @@ QuantifiersEngine::QuantifiersEngine(context::Context* c, context::UserContext*
d_sg_gen = NULL;
d_inst_engine = NULL;
d_i_cbqi = NULL;
+ d_qsplit = NULL;
+ d_anti_skolem = NULL;
d_model_engine = NULL;
d_bint = NULL;
d_rr_engine = NULL;
@@ -134,13 +131,23 @@ QuantifiersEngine::QuantifiersEngine(context::Context* c, context::UserContext*
d_builder = NULL;
d_total_inst_count_debug = 0;
- d_ierCounter = 0;
+ //allow theory combination to go first, once initially
+ d_ierCounter = options::instWhenTcFirst() ? 0 : 1;
+ d_ierCounter_c = d_ierCounter;
d_ierCounter_lc = 0;
- //if any strategy called only on last call, use phase 3
- d_inst_when_phase = options::cbqi() ? 3 : 2;
+ d_ierCounterLastLc = 0;
+ d_inst_when_phase = 1 + ( options::instWhenPhase()<1 ? 1 : options::instWhenPhase() );
}
QuantifiersEngine::~QuantifiersEngine(){
+ for(std::map< Node, inst::CDInstMatchTrie* >::iterator
+ i = d_c_inst_match_trie.begin(), iend = d_c_inst_match_trie.end();
+ i != iend; ++i)
+ {
+ delete (*i).second;
+ }
+ d_c_inst_match_trie.clear();
+
delete d_alpha_equiv;
delete d_builder;
delete d_rr_engine;
@@ -161,6 +168,9 @@ QuantifiersEngine::~QuantifiersEngine(){
delete d_uee;
delete d_fs;
delete d_i_cbqi;
+ delete d_qsplit;
+ delete d_anti_skolem;
+ delete d_inst_prop;
}
EqualityQueryQuantifiersEngine* QuantifiersEngine::getEqualityQuery() {
@@ -237,6 +247,15 @@ void QuantifiersEngine::finishInit(){
d_lte_part_inst = new quantifiers::LtePartialInst( this, c );
d_modules.push_back( d_lte_part_inst );
}
+ if( ( options::finiteModelFind() && options::quantDynamicSplit()!=quantifiers::QUANT_DSPLIT_MODE_NONE ) ||
+ options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_AGG ){
+ d_qsplit = new quantifiers::QuantDSplit( this, c );
+ d_modules.push_back( d_qsplit );
+ }
+ if( options::quantAntiSkolem() ){
+ d_anti_skolem = new quantifiers::QuantAntiSkolem( this );
+ d_modules.push_back( d_anti_skolem );
+ }
if( options::quantAlphaEquiv() ){
d_alpha_equiv = new quantifiers::AlphaEquivalence( this );
}
@@ -257,6 +276,7 @@ void QuantifiersEngine::finishInit(){
if( needsRelDom ){
d_rel_dom = new quantifiers::RelevantDomain( this, d_model );
+ d_util.push_back( d_rel_dom );
}
if( needsBuilder ){
@@ -285,13 +305,17 @@ QuantifiersModule * QuantifiersEngine::getOwner( Node q ) {
}
}
-void QuantifiersEngine::setOwner( Node q, QuantifiersModule * m ) {
+void QuantifiersEngine::setOwner( Node q, QuantifiersModule * m, int priority ) {
QuantifiersModule * mo = getOwner( q );
if( mo!=m ){
if( mo!=NULL ){
- Trace("quant-warn") << "WARNING: setting owner of " << q << " to " << ( m ? m->identify() : "null" ) << ", but already has owner " << mo->identify() << "!" << std::endl;
+ if( priority<=d_owner_priority[q] ){
+ Trace("quant-warn") << "WARNING: setting owner of " << q << " to " << ( m ? m->identify() : "null" ) << ", but already has owner " << mo->identify() << " with higher priority!" << std::endl;
+ return;
+ }
}
d_owner[q] = m;
+ d_owner_priority[q] = priority;
}
}
@@ -323,11 +347,6 @@ void QuantifiersEngine::check( Theory::Effort e ){
Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
return;
}
- if( e==Theory::EFFORT_FULL ){
- d_ierCounter++;
- }else if( e==Theory::EFFORT_LAST_CALL ){
- d_ierCounter_lc++;
- }
bool needsCheck = !d_lemmas_waiting.empty();
unsigned needsModelE = QEFFORT_NONE;
std::vector< QuantifiersModule* > qm;
@@ -346,6 +365,8 @@ void QuantifiersEngine::check( Theory::Effort e ){
}
}
+ d_conflict = false;
+ d_num_added_lemmas_round = 0;
d_hasAddedLemma = false;
bool setIncomplete = false;
if( e==Theory::EFFORT_LAST_CALL ){
@@ -357,50 +378,72 @@ void QuantifiersEngine::check( Theory::Effort e ){
}
bool usedModelBuilder = false;
- Trace("quant-engine-debug") << "Quantifiers Engine call to check, level = " << e << std::endl;
+ Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
if( needsCheck ){
- Trace("quant-engine") << "Quantifiers Engine check, level = " << e << std::endl;
+ //flush previous lemmas (for instance, if was interupted), or other lemmas to process
+ flushLemmas();
+ if( d_hasAddedLemma ){
+ return;
+ }
+ if( !d_recorded_inst.empty() ){
+ Trace("quant-engine-debug") << "Removing " << d_recorded_inst.size() << " instantiations..." << std::endl;
+ //remove explicitly recorded instantiations
+ for( unsigned i=0; i<d_recorded_inst.size(); i++ ){
+ removeInstantiationInternal( d_recorded_inst[i].first, d_recorded_inst[i].second );
+ }
+ d_recorded_inst.clear();
+ }
+
if( Trace.isOn("quant-engine-debug") ){
+ Trace("quant-engine-debug") << "Quantifiers Engine check, level = " << e << std::endl;
+ Trace("quant-engine-debug") << " depth : " << d_ierCounter_c << std::endl;
Trace("quant-engine-debug") << " modules to check : ";
for( unsigned i=0; i<qm.size(); i++ ){
Trace("quant-engine-debug") << qm[i]->identify() << " ";
}
Trace("quant-engine-debug") << std::endl;
Trace("quant-engine-debug") << " # quantified formulas = " << d_model->getNumAssertedQuantifiers() << std::endl;
- if( d_model->getNumToReduceQuantifiers()>0 ){
- Trace("quant-engine-debug") << " # quantified formulas to reduce = " << d_model->getNumToReduceQuantifiers() << std::endl;
- }
if( !d_lemmas_waiting.empty() ){
Trace("quant-engine-debug") << " lemmas waiting = " << d_lemmas_waiting.size() << std::endl;
}
Trace("quant-engine-debug") << " Theory engine finished : " << !d_te->needCheck() << std::endl;
Trace("quant-engine-debug") << " Needs model effort : " << needsModelE << std::endl;
- Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
}
- if( Trace.isOn("quant-engine-ee") ){
- Trace("quant-engine-ee") << "Equality engine : " << std::endl;
- debugPrintEqualityEngine( "quant-engine-ee" );
+ if( Trace.isOn("quant-engine-ee-pre") ){
+ Trace("quant-engine-ee-pre") << "Equality engine (pre-inference): " << std::endl;
+ debugPrintEqualityEngine( "quant-engine-ee-pre" );
}
if( Trace.isOn("quant-engine-assert") ){
Trace("quant-engine-assert") << "Assertions : " << std::endl;
getTheoryEngine()->printAssertions("quant-engine-assert");
}
- //reset relevant information
-
- //flush previous lemmas (for instance, if was interupted), or other lemmas to process
- flushLemmas();
- if( d_hasAddedLemma ){
- return;
+ //reset utilities
+ Trace("quant-engine-debug") << "Resetting all utilities..." << std::endl;
+ for( unsigned i=0; i<d_util.size(); i++ ){
+ Trace("quant-engine-debug2") << "Reset " << d_util[i]->identify().c_str() << "..." << std::endl;
+ if( !d_util[i]->reset( e ) ){
+ flushLemmas();
+ if( d_hasAddedLemma ){
+ return;
+ }else{
+ //should only fail reset if added a lemma
+ Assert( false );
+ }
+ }
}
- Trace("quant-engine-debug2") << "Reset term db..." << std::endl;
- d_term_db->reset( e );
- d_eq_query->reset();
- if( d_rel_dom ){
- d_rel_dom->reset();
+ if( Trace.isOn("quant-engine-ee") ){
+ Trace("quant-engine-ee") << "Equality engine : " << std::endl;
+ debugPrintEqualityEngine( "quant-engine-ee" );
}
+
+ //reset the model
+ Trace("quant-engine-debug") << "Reset model..." << std::endl;
d_model->reset_round();
+
+ //reset the modules
+ Trace("quant-engine-debug") << "Resetting all modules..." << std::endl;
for( unsigned i=0; i<d_modules.size(); i++ ){
Trace("quant-engine-debug2") << "Reset " << d_modules[i]->identify().c_str() << std::endl;
d_modules[i]->reset_round( e );
@@ -410,6 +453,7 @@ void QuantifiersEngine::check( Theory::Effort e ){
flushLemmas();
if( d_hasAddedLemma ){
return;
+
}
if( e==Theory::EFFORT_LAST_CALL ){
@@ -422,6 +466,7 @@ void QuantifiersEngine::check( Theory::Effort e ){
}
Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
for( unsigned quant_e = QEFFORT_CONFLICT; quant_e<=QEFFORT_LAST_CALL; quant_e++ ){
+ d_curr_effort_level = quant_e;
bool success = true;
//build the model if any module requested it
if( needsModelE==quant_e ){
@@ -440,6 +485,10 @@ void QuantifiersEngine::check( Theory::Effort e ){
for( unsigned i=0; i<qm.size(); i++ ){
Trace("quant-engine-debug") << "Check " << qm[i]->identify().c_str() << " at effort " << quant_e << "..." << std::endl;
qm[i]->check( e, quant_e );
+ if( d_conflict ){
+ Trace("quant-engine-debug") << "...conflict!" << std::endl;
+ break;
+ }
}
}
//flush all current lemmas
@@ -447,25 +496,45 @@ void QuantifiersEngine::check( Theory::Effort e ){
//if we have added one, stop
if( d_hasAddedLemma ){
break;
- }else if( e==Theory::EFFORT_LAST_CALL && quant_e==QEFFORT_MODEL ){
- //if we have a chance not to set incomplete
- if( !setIncomplete ){
- setIncomplete = false;
- //check if we should set the incomplete flag
- for( unsigned i=0; i<qm.size(); i++ ){
- if( !qm[i]->checkComplete() ){
- Trace("quant-engine-debug") << "Set incomplete because " << qm[i]->identify().c_str() << " was incomplete." << std::endl;
+ }else{
+ Assert( !d_conflict );
+ if( quant_e==QEFFORT_CONFLICT ){
+ if( e==Theory::EFFORT_FULL ){
+ //increment if a last call happened, we are not strictly enforcing interleaving, or already were in phase
+ if( d_ierCounterLastLc!=d_ierCounter_lc || !options::instWhenStrictInterleave() || d_ierCounter%d_inst_when_phase!=0 ){
+ d_ierCounter = d_ierCounter + 1;
+ d_ierCounterLastLc = d_ierCounter_lc;
+ d_ierCounter_c = d_ierCounter_c.get() + 1;
+ }
+ }else if( e==Theory::EFFORT_LAST_CALL ){
+ d_ierCounter_lc = d_ierCounter_lc + 1;
+ }
+ }else if( quant_e==QEFFORT_MODEL ){
+ if( e==Theory::EFFORT_LAST_CALL ){
+ if( !d_recorded_inst.empty() ){
setIncomplete = true;
+ }
+ //if we have a chance not to set incomplete
+ if( !setIncomplete ){
+ setIncomplete = false;
+ //check if we should set the incomplete flag
+ for( unsigned i=0; i<qm.size(); i++ ){
+ if( !qm[i]->checkComplete() ){
+ Trace("quant-engine-debug") << "Set incomplete because " << qm[i]->identify().c_str() << " was incomplete." << std::endl;
+ setIncomplete = true;
+ break;
+ }
+ }
+ }
+ //if setIncomplete = false, we will answer SAT, otherwise we will run at quant_e QEFFORT_LAST_CALL
+ if( !setIncomplete ){
break;
}
}
}
- //if setIncomplete = false, we will answer SAT, otherwise we will run at quant_e QEFFORT_LAST_CALL
- if( !setIncomplete ){
- break;
- }
}
}
+ d_curr_effort_level = QEFFORT_NONE;
Trace("quant-engine-debug") << "Done check modules that needed check." << std::endl;
if( d_hasAddedLemma ){
//debug information
@@ -476,9 +545,9 @@ void QuantifiersEngine::check( Theory::Effort e ){
}
}
}
- Trace("quant-engine") << "Finished quantifiers engine check." << std::endl;
+ Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
}else{
- Trace("quant-engine") << "Quantifiers Engine does not need check." << std::endl;
+ Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
}
//SAT case
@@ -507,35 +576,38 @@ void QuantifiersEngine::check( Theory::Effort e ){
}
}
+void QuantifiersEngine::notifyCombineTheories() {
+ //if allowing theory combination to happen at most once between instantiation rounds
+ //d_ierCounter = 1;
+ //d_ierCounterLastLc = -1;
+}
+
bool QuantifiersEngine::reduceQuantifier( Node q ) {
- std::map< Node, bool >::iterator it = d_quants_red.find( q );
+ BoolMap::const_iterator it = d_quants_red.find( q );
if( it==d_quants_red.end() ){
- if( d_alpha_equiv ){
- Trace("quant-engine-red") << "Alpha equivalence " << q << "?" << std::endl;
- //add equivalence with another quantified formula
- if( !d_alpha_equiv->registerQuantifier( q ) ){
- Trace("quant-engine-red") << "...alpha equivalence success." << std::endl;
- ++(d_statistics.d_red_alpha_equiv);
- d_quants_red[q] = true;
- return true;
+ Node lem;
+ std::map< Node, Node >::iterator itr = d_quants_red_lem.find( q );
+ if( itr==d_quants_red_lem.end() ){
+ if( d_alpha_equiv ){
+ Trace("quant-engine-red") << "Alpha equivalence " << q << "?" << std::endl;
+ //add equivalence with another quantified formula
+ lem = d_alpha_equiv->reduceQuantifier( q );
+ if( !lem.isNull() ){
+ Trace("quant-engine-red") << "...alpha equivalence success." << std::endl;
+ ++(d_statistics.d_red_alpha_equiv);
+ }
}
+ d_quants_red_lem[q] = lem;
+ }else{
+ lem = itr->second;
}
- if( d_lte_part_inst && !q.getAttribute(LtePartialInstAttribute()) ){
- //will partially instantiate
- Trace("quant-engine-red") << "LTE: Partially instantiate " << q << "?" << std::endl;
- if( d_lte_part_inst->addQuantifier( q ) ){
- Trace("quant-engine-red") << "...LTE partially instantiate success." << std::endl;
- //delayed reduction : assert to model
- d_model->assertQuantifier( q, true );
- ++(d_statistics.d_red_lte_partial_inst);
- d_quants_red[q] = true;
- return true;
- }
+ if( !lem.isNull() ){
+ getOutputChannel().lemma( lem );
}
- d_quants_red[q] = false;
- return false;
+ d_quants_red[q] = !lem.isNull();
+ return !lem.isNull();
}else{
- return it->second;
+ return (*it).second;
}
}
@@ -581,7 +653,7 @@ bool QuantifiersEngine::registerQuantifier( Node f ){
return true;
}
}else{
- return it->second;
+ return (*it).second;
}
}
@@ -673,6 +745,29 @@ void QuantifiersEngine::addTermToDatabase( Node n, bool withinQuant, bool within
}
}
+void QuantifiersEngine::eqNotifyNewClass(TNode t) {
+ addTermToDatabase( t );
+ if( d_eq_query->getEqualityInference() ){
+ d_eq_query->getEqualityInference()->eqNotifyNewClass( t );
+ }
+}
+
+void QuantifiersEngine::eqNotifyPreMerge(TNode t1, TNode t2) {
+ if( d_eq_query->getEqualityInference() ){
+ d_eq_query->getEqualityInference()->eqNotifyMerge( t1, t2 );
+ }
+}
+
+void QuantifiersEngine::eqNotifyPostMerge(TNode t1, TNode t2) {
+
+}
+
+void QuantifiersEngine::eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {
+ //if( d_qcf ){
+ // d_qcf->assertDisequal( t1, t2 );
+ //}
+}
+
void QuantifiersEngine::computeTermVector( Node f, InstMatch& m, std::vector< Node >& vars, std::vector< Node >& terms ){
for( size_t i=0; i<f[0].getNumChildren(); i++ ){
Node n = m.get( i );
@@ -683,73 +778,39 @@ void QuantifiersEngine::computeTermVector( Node f, InstMatch& m, std::vector< No
}
}
-bool QuantifiersEngine::addInstantiationInternal( Node f, std::vector< Node >& vars, std::vector< Node >& terms, bool doVts ){
- Assert( f.getKind()==FORALL );
- Assert( vars.size()==terms.size() );
- Node body = getInstantiation( f, vars, terms );
- //do virtual term substitution
- if( doVts ){
- body = Rewriter::rewrite( body );
- Trace("quant-vts-debug") << "Rewrite vts symbols in " << body << std::endl;
- Node body_r = d_term_db->rewriteVtsSymbols( body );
- Trace("quant-vts-debug") << " ...result: " << body_r << std::endl;
- body = body_r;
+
+bool QuantifiersEngine::recordInstantiationInternal( Node q, std::vector< Node >& terms, bool modEq, bool addedLem ) {
+ if( !addedLem ){
+ //record the instantiation for deletion later
+ d_recorded_inst.push_back( std::pair< Node, std::vector< Node > >( q, terms ) );
}
- body = quantifiers::QuantifiersRewriter::preprocess( body, true );
- Trace("inst-debug") << "...preprocess to " << body << std::endl;
- Trace("inst-assert") << "(assert " << body << ")" << std::endl;
- //make the lemma
- Node lem = NodeManager::currentNM()->mkNode( kind::OR, f.negate(), body );
- //check for duplication
- if( addLemma( lem ) ){
- d_total_inst_debug[f]++;
- d_temp_inst_debug[f]++;
- d_total_inst_count_debug++;
- Trace("inst") << "*** Instantiate " << f << " with " << std::endl;
- for( unsigned i=0; i<terms.size(); i++ ){
- if( Trace.isOn("inst") ){
- Trace("inst") << " " << terms[i];
- if( Trace.isOn("inst-debug") ){
- Trace("inst-debug") << ", type=" << terms[i].getType() << ", var_type=" << f[0][i].getType();
- }
- Trace("inst") << std::endl;
- }
- if( options::cbqi() ){
- Node icf = quantifiers::TermDb::getInstConstAttr(terms[i]);
- bool bad_inst = false;
- if( !icf.isNull() ){
- if( icf==f ){
- bad_inst = true;
- }else{
- bad_inst = quantifiers::TermDb::containsTerms( terms[i], d_term_db->d_inst_constants[f] );
- }
- }
- if( bad_inst ){
- Trace("inst")<< "***& Bad Instantiate " << f << " with " << std::endl;
- for( unsigned i=0; i<terms.size(); i++ ){
- Trace("inst") << " " << terms[i] << std::endl;
- }
- Unreachable("Bad instantiation");
- }
- }
- Assert( terms[i].getType().isSubtypeOf( f[0][i].getType() ) );
+ if( options::incrementalSolving() ){
+ Trace("inst-add-debug") << "Adding into context-dependent inst trie, modEq = " << modEq << std::endl;
+ inst::CDInstMatchTrie* imt;
+ std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_c_inst_match_trie.find( q );
+ if( it!=d_c_inst_match_trie.end() ){
+ imt = it->second;
+ }else{
+ imt = new CDInstMatchTrie( getUserContext() );
+ d_c_inst_match_trie[q] = imt;
}
- if( options::instMaxLevel()!=-1 ){
- uint64_t maxInstLevel = 0;
- for( unsigned i=0; i<terms.size(); i++ ){
- if( terms[i].hasAttribute(InstLevelAttribute()) ){
- if( terms[i].getAttribute(InstLevelAttribute())>maxInstLevel ){
- maxInstLevel = terms[i].getAttribute(InstLevelAttribute());
- }
- }
- }
- setInstantiationLevelAttr( body, f[1], maxInstLevel+1 );
+ return imt->addInstMatch( this, q, terms, getUserContext(), modEq );
+ }else{
+ Trace("inst-add-debug") << "Adding into inst trie" << std::endl;
+ return d_inst_match_trie[q].addInstMatch( this, q, terms, modEq );
+ }
+}
+
+bool QuantifiersEngine::removeInstantiationInternal( Node q, std::vector< Node >& terms ) {
+ if( options::incrementalSolving() ){
+ std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_c_inst_match_trie.find( q );
+ if( it!=d_c_inst_match_trie.end() ){
+ return it->second->removeInstMatch( this, q, terms );
+ }else{
+ return false;
}
- ++(d_statistics.d_instantiations);
- return true;
}else{
- ++(d_statistics.d_inst_duplicate);
- return false;
+ return d_inst_match_trie[q].removeInstMatch( this, q, terms );
}
}
@@ -764,7 +825,7 @@ void QuantifiersEngine::setInstantiationLevelAttr( Node n, Node qn, uint64_t lev
Trace("inst-level-debug") << "Set instantiation level " << n << " to " << level << std::endl;
}
Assert( n.getNumChildren()==qn.getNumChildren() );
- for( int i=0; i<(int)n.getNumChildren(); i++ ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
setInstantiationLevelAttr( n[i], qn[i], level );
}
}
@@ -776,7 +837,7 @@ void QuantifiersEngine::setInstantiationLevelAttr( Node n, uint64_t level ){
n.setAttribute(ila,level);
Trace("inst-level-debug") << "Set instantiation level " << n << " to " << level << std::endl;
}
- for( int i=0; i<(int)n.getNumChildren(); i++ ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
setInstantiationLevelAttr( n[i], level );
}
}
@@ -811,7 +872,7 @@ Node QuantifiersEngine::getSubstitute( Node n, std::vector< Node >& terms ){
}
-Node QuantifiersEngine::getInstantiation( Node q, std::vector< Node >& vars, std::vector< Node >& terms ){
+Node QuantifiersEngine::getInstantiation( Node q, std::vector< Node >& vars, std::vector< Node >& terms, bool doVts ){
Node body;
//process partial instantiation if necessary
if( d_term_db->d_vars[q].size()!=vars.size() ){
@@ -842,60 +903,81 @@ Node QuantifiersEngine::getInstantiation( Node q, std::vector< Node >& vars, std
}
}
}
+ if( doVts ){
+ //do virtual term substitution
+ body = Rewriter::rewrite( body );
+ Trace("quant-vts-debug") << "Rewrite vts symbols in " << body << std::endl;
+ Node body_r = d_term_db->rewriteVtsSymbols( body );
+ Trace("quant-vts-debug") << " ...result: " << body_r << std::endl;
+ body = body_r;
+ }
return body;
}
-Node QuantifiersEngine::getInstantiation( Node q, InstMatch& m ){
+Node QuantifiersEngine::getInstantiation( Node q, InstMatch& m, bool doVts ){
std::vector< Node > vars;
std::vector< Node > terms;
computeTermVector( q, m, vars, terms );
- return getInstantiation( q, vars, terms );
+ return getInstantiation( q, vars, terms, doVts );
}
-Node QuantifiersEngine::getInstantiation( Node q, std::vector< Node >& terms ) {
- return getInstantiation( q, d_term_db->d_vars[q], terms );
+Node QuantifiersEngine::getInstantiation( Node q, std::vector< Node >& terms, bool doVts ) {
+ return getInstantiation( q, d_term_db->d_vars[q], terms, doVts );
}
/*
-bool QuantifiersEngine::existsInstantiation( Node f, InstMatch& m, bool modEq, bool modInst ){
+bool QuantifiersEngine::existsInstantiation( Node f, InstMatch& m, bool modEq ){
if( options::incrementalSolving() ){
if( d_c_inst_match_trie.find( f )!=d_c_inst_match_trie.end() ){
- if( d_c_inst_match_trie[f]->existsInstMatch( this, f, m, getUserContext(), modEq, modInst ) ){
+ if( d_c_inst_match_trie[f]->existsInstMatch( this, f, m, getUserContext(), modEq ) ){
return true;
}
}
}else{
if( d_inst_match_trie.find( f )!=d_inst_match_trie.end() ){
- if( d_inst_match_trie[f].existsInstMatch( this, f, m, modEq, modInst ) ){
+ if( d_inst_match_trie[f].existsInstMatch( this, f, m, modEq ) ){
return true;
}
}
}
- //also check model builder (it may contain instantiations internally)
- if( d_builder && d_builder->existsInstantiation( f, m, modEq, modInst ) ){
- return true;
- }
return false;
}
*/
-bool QuantifiersEngine::addLemma( Node lem, bool doCache ){
+bool QuantifiersEngine::addLemma( Node lem, bool doCache, bool doRewrite ){
if( doCache ){
- lem = Rewriter::rewrite(lem);
+ if( doRewrite ){
+ lem = Rewriter::rewrite(lem);
+ }
Trace("inst-add-debug") << "Adding lemma : " << lem << std::endl;
- if( d_lemmas_produced_c.find( lem )==d_lemmas_produced_c.end() ){
+ BoolMap::const_iterator itp = d_lemmas_produced_c.find( lem );
+ if( itp==d_lemmas_produced_c.end() || !(*itp).second ){
//d_curr_out->lemma( lem, false, true );
d_lemmas_produced_c[ lem ] = true;
d_lemmas_waiting.push_back( lem );
Trace("inst-add-debug") << "Added lemma" << std::endl;
+ d_num_added_lemmas_round++;
return true;
}else{
Trace("inst-add-debug") << "Duplicate." << std::endl;
return false;
}
}else{
+ //do not need to rewrite, will be rewritten after sending
d_lemmas_waiting.push_back( lem );
+ d_num_added_lemmas_round++;
+ return true;
+ }
+}
+
+bool QuantifiersEngine::removeLemma( Node lem ) {
+ std::vector< Node >::iterator it = std::find( d_lemmas_waiting.begin(), d_lemmas_waiting.end(), lem );
+ if( it!=d_lemmas_waiting.end() ){
+ d_lemmas_waiting.erase( it, it + 1 );
+ d_lemmas_produced_c[ lem ] = false;
return true;
+ }else{
+ return false;
}
}
@@ -903,16 +985,16 @@ void QuantifiersEngine::addRequirePhase( Node lit, bool req ){
d_phase_req_waiting[lit] = req;
}
-bool QuantifiersEngine::addInstantiation( Node q, InstMatch& m, bool mkRep, bool modEq, bool modInst, bool doVts ){
+bool QuantifiersEngine::addInstantiation( Node q, InstMatch& m, bool mkRep, bool modEq, bool doVts ){
std::vector< Node > terms;
m.getTerms( q, terms );
- return addInstantiation( q, terms, mkRep, modEq, modInst, doVts );
+ return addInstantiation( q, terms, mkRep, modEq, doVts );
}
-bool QuantifiersEngine::addInstantiation( Node q, std::vector< Node >& terms, bool mkRep, bool modEq, bool modInst, bool doVts ) {
+bool QuantifiersEngine::addInstantiation( Node q, std::vector< Node >& terms, bool mkRep, bool modEq, bool doVts ) {
// For resource-limiting (also does a time check).
getOutputChannel().safePoint(options::quantifierStep());
-
+ Assert( !d_conflict );
Assert( terms.size()==q[0].getNumChildren() );
Trace("inst-add-debug") << "For quantified formula " << q << ", add instantiation: " << std::endl;
for( unsigned i=0; i<terms.size(); i++ ){
@@ -921,18 +1003,42 @@ bool QuantifiersEngine::addInstantiation( Node q, std::vector< Node >& terms, bo
if( terms[i].isNull() ){
terms[i] = d_term_db->getModelBasisTerm( q[0][i].getType() );
}
- //make it representative, this is helpful for recognizing duplication
if( mkRep ){
//pick the best possible representative for instantiation, based on past use and simplicity of term
terms[i] = d_eq_query->getInternalRepresentative( terms[i], q, i );
}else{
//ensure the type is correct
- terms[i] = quantifiers::TermDb::mkNodeType( terms[i], q[0][i].getType() );
+ terms[i] = quantifiers::TermDb::ensureType( terms[i], q[0][i].getType() );
}
Trace("inst-add-debug") << " -> " << terms[i] << std::endl;
- Assert( !terms[i].isNull() );
+ if( terms[i].isNull() ){
+ Trace("inst-add-debug") << " --> Failed to make term vector, due to term/type restrictions." << std::endl;
+ return false;
+ }
#ifdef CVC4_ASSERTIONS
- Assert( !quantifiers::TermDb::containsUninterpretedConstant( terms[i] ) );
+ bool bad_inst = false;
+ if( quantifiers::TermDb::containsUninterpretedConstant( terms[i] ) ){
+ bad_inst = true;
+ }else if( !terms[i].getType().isSubtypeOf( q[0][i].getType() ) ){
+ bad_inst = true;
+ }else if( options::cbqi() ){
+ Node icf = quantifiers::TermDb::getInstConstAttr(terms[i]);
+ if( !icf.isNull() ){
+ if( icf==q ){
+ bad_inst = true;
+ }else{
+ bad_inst = quantifiers::TermDb::containsTerms( terms[i], d_term_db->d_inst_constants[q] );
+ }
+ }
+ }
+ //this assertion is critical to soundness
+ if( bad_inst ){
+ Trace("inst")<< "***& Bad Instantiate " << q << " with " << std::endl;
+ for( unsigned j=0; j<terms.size(); j++ ){
+ Trace("inst") << " " << terms[j] << std::endl;
+ }
+ Assert( false );
+ }
#endif
}
@@ -944,55 +1050,101 @@ bool QuantifiersEngine::addInstantiation( Node q, std::vector< Node >& terms, bo
}
}
}
- //check for entailment
+
+ //check for positive entailment
if( options::instNoEntail() ){
+ //TODO: check consistency of equality engine (if not aborting on utility's reset)
std::map< TNode, TNode > subs;
for( unsigned i=0; i<terms.size(); i++ ){
subs[q[0][i]] = terms[i];
}
if( d_term_db->isEntailed( q[1], subs, false, true ) ){
- Trace("inst-add-debug") << " -> Currently entailed." << std::endl;
+ Trace("inst-add-debug") << " --> Currently entailed." << std::endl;
return false;
}
+ //Node eval = d_term_db->evaluateTerm( q[1], subs, false, true );
+ //Trace("ajr-temp") << "Instantiation evaluates to : " << std::endl;
+ //Trace("ajr-temp") << " " << eval << std::endl;
}
- //check for duplication
- bool alreadyExists = false;
- if( options::incrementalSolving() ){
- Trace("inst-add-debug") << "Adding into context-dependent inst trie, modEq = " << modEq << ", modInst = " << modInst << std::endl;
- inst::CDInstMatchTrie* imt;
- std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_c_inst_match_trie.find( q );
- if( it!=d_c_inst_match_trie.end() ){
- imt = it->second;
- }else{
- imt = new CDInstMatchTrie( getUserContext() );
- d_c_inst_match_trie[q] = imt;
- }
- alreadyExists = !imt->addInstMatch( this, q, terms, getUserContext(), modEq, modInst );
- }else{
- Trace("inst-add-debug") << "Adding into inst trie" << std::endl;
- alreadyExists = !d_inst_match_trie[q].addInstMatch( this, q, terms, modEq, modInst );
- }
+ //check for term vector duplication
+ bool alreadyExists = !recordInstantiationInternal( q, terms, modEq );
if( alreadyExists ){
- Trace("inst-add-debug") << " -> Already exists." << std::endl;
+ Trace("inst-add-debug") << " --> Already exists." << std::endl;
++(d_statistics.d_inst_duplicate_eq);
return false;
}
-
- //add the instantiation
+ //construct the instantiation
Trace("inst-add-debug") << "Constructing instantiation..." << std::endl;
- bool addedInst = addInstantiationInternal( q, d_term_db->d_vars[q], terms, doVts );
- //report the result
- if( addedInst ){
- Trace("inst-add-debug") << " -> Success." << std::endl;
+ Assert( d_term_db->d_vars[q].size()==terms.size() );
+ Node body = getInstantiation( q, d_term_db->d_vars[q], terms, doVts ); //do virtual term substitution
+ body = quantifiers::QuantifiersRewriter::preprocess( body, true );
+ Trace("inst-debug") << "...preprocess to " << body << std::endl;
+
+ //construct the lemma
+ Trace("inst-assert") << "(assert " << body << ")" << std::endl;
+ body = Rewriter::rewrite(body);
+ Node lem = NodeManager::currentNM()->mkNode( kind::OR, q.negate(), body );
+ lem = Rewriter::rewrite(lem);
+
+ //check for lemma duplication
+ if( addLemma( lem, true, false ) ){
+ d_total_inst_debug[q]++;
+ d_temp_inst_debug[q]++;
+ d_total_inst_count_debug++;
+ if( Trace.isOn("inst") ){
+ Trace("inst") << "*** Instantiate " << q << " with " << std::endl;
+ for( unsigned i=0; i<terms.size(); i++ ){
+ if( Trace.isOn("inst") ){
+ Trace("inst") << " " << terms[i];
+ if( Trace.isOn("inst-debug") ){
+ Trace("inst-debug") << ", type=" << terms[i].getType() << ", var_type=" << q[0][i].getType();
+ }
+ Trace("inst") << std::endl;
+ }
+ }
+ }
+ if( options::instMaxLevel()!=-1 ){
+ uint64_t maxInstLevel = 0;
+ for( unsigned i=0; i<terms.size(); i++ ){
+ if( terms[i].hasAttribute(InstLevelAttribute()) ){
+ if( terms[i].getAttribute(InstLevelAttribute())>maxInstLevel ){
+ maxInstLevel = terms[i].getAttribute(InstLevelAttribute());
+ }
+ }
+ }
+ setInstantiationLevelAttr( body, q[1], maxInstLevel+1 );
+ }
+ if( d_curr_effort_level>QEFFORT_CONFLICT && d_curr_effort_level<QEFFORT_NONE ){
+ //notify listeners
+ for( unsigned j=0; j<d_inst_notify.size(); j++ ){
+ if( !d_inst_notify[j]->notifyInstantiation( d_curr_effort_level, q, lem, terms, body ) ){
+ Trace("inst-add-debug") << "...we are in conflict." << std::endl;
+ d_conflict = true;
+ Assert( !d_lemmas_waiting.empty() );
+ break;
+ }
+ }
+ }
+ Trace("inst-add-debug") << " --> Success." << std::endl;
+ ++(d_statistics.d_instantiations);
return true;
}else{
- Trace("inst-add-debug") << " -> Lemma already exists." << std::endl;
+ Trace("inst-add-debug") << " --> Lemma already exists." << std::endl;
+ ++(d_statistics.d_inst_duplicate);
return false;
}
}
+bool QuantifiersEngine::removeInstantiation( Node q, Node lem, std::vector< Node >& terms ) {
+ //lem must occur in d_waiting_lemmas
+ if( removeLemma( lem ) ){
+ return removeInstantiationInternal( q, terms );
+ }else{
+ return false;
+ }
+}
bool QuantifiersEngine::addSplit( Node n, bool reqPhase, bool reqPhasePol ){
n = Rewriter::rewrite( n );
@@ -1012,7 +1164,12 @@ bool QuantifiersEngine::addSplitEquality( Node n1, Node n2, bool reqPhase, bool
return addSplit( fm );
}
+void QuantifiersEngine::markRelevant( Node q ) {
+ d_model->markRelevant( q );
+}
+
bool QuantifiersEngine::getInstWhenNeedsCheck( Theory::Effort e ) {
+ Trace("quant-engine-debug2") << "Get inst when needs check, counts=" << d_ierCounter << ", " << d_ierCounter_lc << std::endl;
//determine if we should perform check, based on instWhenMode
bool performCheck = false;
if( options::instWhenMode()==quantifiers::INST_WHEN_FULL ){
@@ -1020,9 +1177,9 @@ bool QuantifiersEngine::getInstWhenNeedsCheck( Theory::Effort e ) {
}else if( options::instWhenMode()==quantifiers::INST_WHEN_FULL_DELAY ){
performCheck = ( e >= Theory::EFFORT_FULL ) && !getTheoryEngine()->needCheck();
}else if( options::instWhenMode()==quantifiers::INST_WHEN_FULL_LAST_CALL ){
- performCheck = ( ( e==Theory::EFFORT_FULL && d_ierCounter%d_inst_when_phase==0 ) || e==Theory::EFFORT_LAST_CALL );
+ performCheck = ( ( e==Theory::EFFORT_FULL && d_ierCounter%d_inst_when_phase!=0 ) || e==Theory::EFFORT_LAST_CALL );
}else if( options::instWhenMode()==quantifiers::INST_WHEN_FULL_DELAY_LAST_CALL ){
- performCheck = ( ( e==Theory::EFFORT_FULL && !getTheoryEngine()->needCheck() && d_ierCounter%d_inst_when_phase==0 ) || e==Theory::EFFORT_LAST_CALL );
+ performCheck = ( ( e==Theory::EFFORT_FULL && !getTheoryEngine()->needCheck() && d_ierCounter%d_inst_when_phase!=0 ) || e==Theory::EFFORT_LAST_CALL );
}else if( options::instWhenMode()==quantifiers::INST_WHEN_LAST_CALL ){
performCheck = ( e >= Theory::EFFORT_LAST_CALL );
}else{
@@ -1106,6 +1263,18 @@ void QuantifiersEngine::printSynthSolution( std::ostream& out ) {
}
}
+void QuantifiersEngine::getInstantiations( std::map< Node, std::vector< Node > >& insts ) {
+ if( options::incrementalSolving() ){
+ for( std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_c_inst_match_trie.begin(); it != d_c_inst_match_trie.end(); ++it ){
+ it->second->getInstantiations( insts[it->first], it->first, this );
+ }
+ }else{
+ for( std::map< Node, inst::InstMatchTrie >::iterator it = d_inst_match_trie.begin(); it != d_inst_match_trie.end(); ++it ){
+ it->second.getInstantiations( insts[it->first], it->first, this );
+ }
+ }
+}
+
QuantifiersEngine::Statistics::Statistics()
: d_time("theory::QuantifiersEngine::time"),
d_num_quant("QuantifiersEngine::Num_Quantifiers", 0),
@@ -1204,9 +1373,57 @@ void QuantifiersEngine::debugPrintEqualityEngine( const char * c ) {
}
}
-void EqualityQueryQuantifiersEngine::reset(){
+
+EqualityQueryQuantifiersEngine::EqualityQueryQuantifiersEngine( context::Context* c, QuantifiersEngine* qe ) : d_qe( qe ), d_eqi_counter( c ), d_reset_count( 0 ){
+ if( options::inferArithTriggerEq() ){
+ d_eq_inference = new quantifiers::EqualityInference( c, options::inferArithTriggerEqExp() );
+ }else{
+ d_eq_inference = NULL;
+ }
+}
+
+EqualityQueryQuantifiersEngine::~EqualityQueryQuantifiersEngine(){
+ delete d_eq_inference;
+}
+
+bool EqualityQueryQuantifiersEngine::reset( Theory::Effort e ){
d_int_rep.clear();
d_reset_count++;
+ return processInferences( e );
+}
+
+bool EqualityQueryQuantifiersEngine::processInferences( Theory::Effort e ) {
+ if( options::inferArithTriggerEq() ){
+ eq::EqualityEngine* ee = getEngine();
+ //updated implementation
+ while( d_eqi_counter.get()<d_eq_inference->getNumPendingMerges() ){
+ Node eq = d_eq_inference->getPendingMerge( d_eqi_counter.get() );
+ Node eq_exp = d_eq_inference->getPendingMergeExplanation( d_eqi_counter.get() );
+ Trace("quant-engine-ee-proc") << "processInferences : Infer : " << eq << std::endl;
+ Trace("quant-engine-ee-proc") << " explanation : " << eq_exp << std::endl;
+ Assert( ee->hasTerm( eq[0] ) );
+ Assert( ee->hasTerm( eq[1] ) );
+ if( ee->areDisequal( eq[0], eq[1], false ) ){
+ Trace("quant-engine-ee-proc") << "processInferences : Conflict : " << eq << std::endl;
+ if( Trace.isOn("term-db-lemma") ){
+ Trace("term-db-lemma") << "Disequal terms, equal by normalization : " << eq[0] << " " << eq[1] << "!!!!" << std::endl;
+ if( !d_qe->getTheoryEngine()->needCheck() ){
+ Trace("term-db-lemma") << " all theories passed with no lemmas." << std::endl;
+ //this should really never happen (implies arithmetic is incomplete when sharing is enabled)
+ Assert( false );
+ }
+ Trace("term-db-lemma") << " add split on : " << eq << std::endl;
+ }
+ d_qe->addSplit( eq );
+ return false;
+ }else{
+ ee->assertEquality( eq, true, eq_exp );
+ d_eqi_counter = d_eqi_counter.get() + 1;
+ }
+ }
+ Assert( ee->consistent() );
+ }
+ return true;
}
bool EqualityQueryQuantifiersEngine::hasTerm( Node a ){
@@ -1237,39 +1454,43 @@ bool EqualityQueryQuantifiersEngine::areEqual( Node a, Node b ){
}
bool EqualityQueryQuantifiersEngine::areDisequal( Node a, Node b ){
- eq::EqualityEngine* ee = getEngine();
- if( ee->hasTerm( a ) && ee->hasTerm( b ) ){
- if( ee->areDisequal( a, b, false ) ){
- return true;
+ if( a==b ){
+ return false;
+ }else{
+ eq::EqualityEngine* ee = getEngine();
+ if( ee->hasTerm( a ) && ee->hasTerm( b ) ){
+ if( ee->areDisequal( a, b, false ) ){
+ return true;
+ }
}
+ return false;
}
- return false;
}
Node EqualityQueryQuantifiersEngine::getInternalRepresentative( Node a, Node f, int index ){
Assert( f.isNull() || f.getKind()==FORALL );
Node r = getRepresentative( a );
- if( !options::internalReps() ){
- return r;
- }else{
- if( options::finiteModelFind() ){
- if( r.isConst() ){
- //map back from values assigned by model, if any
- if( d_qe->getModel() ){
- std::map< Node, Node >::iterator it = d_qe->getModel()->d_rep_set.d_values_to_terms.find( r );
- if( it!=d_qe->getModel()->d_rep_set.d_values_to_terms.end() ){
- r = it->second;
- r = getRepresentative( r );
- }else{
- if( r.getType().isSort() ){
- Trace("internal-rep-warn") << "No representative for UF constant." << std::endl;
- //should never happen : UF constants should never escape model
- Assert( false );
- }
+ if( options::finiteModelFind() ){
+ if( r.isConst() && quantifiers::TermDb::containsUninterpretedConstant( r ) ){
+ //map back from values assigned by model, if any
+ if( d_qe->getModel() ){
+ std::map< Node, Node >::iterator it = d_qe->getModel()->d_rep_set.d_values_to_terms.find( r );
+ if( it!=d_qe->getModel()->d_rep_set.d_values_to_terms.end() ){
+ r = it->second;
+ r = getRepresentative( r );
+ }else{
+ if( r.getType().isSort() ){
+ Trace("internal-rep-warn") << "No representative for UF constant." << std::endl;
+ //should never happen : UF constants should never escape model
+ Assert( false );
}
}
}
}
+ }
+ if( options::quantRepMode()==quantifiers::QUANT_REP_MODE_EE ){
+ return r;
+ }else{
TypeNode v_tn = f.isNull() ? a.getType() : f[0][index].getType();
std::map< Node, Node >::iterator itir = d_int_rep[v_tn].find( r );
if( itir==d_int_rep[v_tn].end() ){
@@ -1309,7 +1530,7 @@ Node EqualityQueryQuantifiersEngine::getInternalRepresentative( Node a, Node f,
if( d_rep_score.find( r_best )==d_rep_score.end() ){
d_rep_score[ r_best ] = d_reset_count;
}
- Trace("internal-rep-select") << "...Choose " << r_best << std::endl;
+ Trace("internal-rep-select") << "...Choose " << r_best << " with score " << r_best_score << std::endl;
Assert( r_best.getType().isSubtypeOf( v_tn ) );
d_int_rep[v_tn][r] = r_best;
if( r_best!=a ){
@@ -1416,6 +1637,10 @@ void EqualityQueryQuantifiersEngine::getEquivalenceClass( Node a, std::vector< N
Assert( std::find( eqc.begin(), eqc.end(), a )!=eqc.end() );
}
+TNode EqualityQueryQuantifiersEngine::getCongruentTerm( Node f, std::vector< TNode >& args ) {
+ return d_qe->getTermDatabase()->getCongruentTerm( f, args );
+}
+
//helper functions
Node EqualityQueryQuantifiersEngine::getInstance( Node n, const std::vector< Node >& eqc, std::hash_map<TNode, Node, TNodeHashFunction>& cache ){
@@ -1435,23 +1660,6 @@ Node EqualityQueryQuantifiersEngine::getInstance( Node n, const std::vector< Nod
}
}
-/*
-int getDepth( Node n ){
- if( n.getNumChildren()==0 ){
- return 0;
- }else{
- int maxDepth = -1;
- for( int i=0; i<(int)n.getNumChildren(); i++ ){
- int depth = getDepth( n[i] );
- if( depth>maxDepth ){
- maxDepth = depth;
- }
- }
- return maxDepth;
- }
-}
-*/
-
//-2 : invalid, -1 : undesired, otherwise : smaller the score, the better
int EqualityQueryQuantifiersEngine::getRepScore( Node n, Node f, int index, TypeNode v_tn ){
if( options::cbqi() && quantifiers::TermDb::hasInstConstAttr(n) ){ //reject
@@ -1468,8 +1676,12 @@ int EqualityQueryQuantifiersEngine::getRepScore( Node n, Node f, int index, Type
return options::instLevelInputOnly() ? -1 : 0;
}
}else{
- //score prefers earliest use of this term as a representative
- return d_rep_score.find( n )==d_rep_score.end() ? -1 : d_rep_score[n];
+ if( options::quantRepMode()==quantifiers::QUANT_REP_MODE_FIRST ){
+ //score prefers earliest use of this term as a representative
+ return d_rep_score.find( n )==d_rep_score.end() ? -1 : d_rep_score[n];
+ }else{
+ Assert( options::quantRepMode()==quantifiers::QUANT_REP_MODE_DEPTH );
+ return quantifiers::TermDb::getTermDepth( n );
+ }
}
- //return ( d_rep_score.find( n )==d_rep_score.end() ? 100 : 0 ) + getDepth( n ); //term depth
}
diff --git a/src/theory/quantifiers_engine.h b/src/theory/quantifiers_engine.h
index aa770ad67..4ee66f9e7 100644
--- a/src/theory/quantifiers_engine.h
+++ b/src/theory/quantifiers_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file quantifiers_engine.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Francois Bobot
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory instantiator, Instantiation Engine classes
**/
@@ -44,42 +44,11 @@ namespace quantifiers {
class TermDbSygus;
}
-class QuantifiersModule {
-protected:
- QuantifiersEngine* d_quantEngine;
+class InstantiationNotify {
public:
- QuantifiersModule( QuantifiersEngine* qe ) : d_quantEngine( qe ){}
- virtual ~QuantifiersModule(){}
- //get quantifiers engine
- QuantifiersEngine* getQuantifiersEngine() { return d_quantEngine; }
- /** presolve */
- virtual void presolve() {}
- /* whether this module needs to check this round */
- virtual bool needsCheck( Theory::Effort e ) { return e>=Theory::EFFORT_LAST_CALL; }
- /* whether this module needs a model built */
- virtual unsigned needsModel( Theory::Effort e );
- /* reset at a round */
- virtual void reset_round( Theory::Effort e ){}
- /* Call during quantifier engine's check */
- virtual void check( Theory::Effort e, unsigned quant_e ) = 0;
- /* check was complete (e.g. no lemmas implies a model) */
- virtual bool checkComplete() { return true; }
- /* Called for new quantifiers */
- virtual void preRegisterQuantifier( Node q ) {}
- /* Called for new quantifiers after owners are finalized */
- virtual void registerQuantifier( Node q ) = 0;
- virtual void assertNode( Node n ) {}
- virtual void propagate( Theory::Effort level ){}
- virtual Node getNextDecisionRequest() { return TNode::null(); }
- /** Identify this module (for debugging, dynamic configuration, etc..) */
- virtual std::string identify() const = 0;
-public:
- eq::EqualityEngine * getEqualityEngine();
- bool areDisequal( TNode n1, TNode n2 );
- bool areEqual( TNode n1, TNode n2 );
- TNode getRepresentative( TNode n );
- quantifiers::TermDb * getTermDatabase();
-};/* class QuantifiersModule */
+ InstantiationNotify(){}
+ virtual bool notifyInstantiation( unsigned quant_e, Node q, Node lem, std::vector< Node >& terms, Node body ) = 0;
+};
namespace quantifiers {
class FirstOrderModel;
@@ -99,6 +68,11 @@ namespace quantifiers {
class QuantEqualityEngine;
class FullSaturation;
class InstStrategyCbqi;
+ class InstStrategyCegqi;
+ class QuantDSplit;
+ class QuantAntiSkolem;
+ class EqualityInference;
+ class InstPropagator;
}/* CVC4::theory::quantifiers */
namespace inst {
@@ -110,6 +84,7 @@ class EqualityQueryQuantifiersEngine;
class QuantifiersEngine {
friend class quantifiers::InstantiationEngine;
+ friend class quantifiers::InstStrategyCegqi;
friend class quantifiers::ModelEngine;
friend class quantifiers::RewriteEngine;
friend class quantifiers::QuantConflictFind;
@@ -121,8 +96,12 @@ class QuantifiersEngine {
private:
/** reference to theory engine object */
TheoryEngine* d_te;
+ /** vector of utilities for quantifiers */
+ std::vector< QuantifiersUtil* > d_util;
/** vector of modules for quantifiers */
std::vector< QuantifiersModule* > d_modules;
+ /** instantiation notify */
+ std::vector< InstantiationNotify* > d_inst_notify;
/** equality query class */
EqualityQueryQuantifiersEngine* d_eq_query;
/** for computing relevance of quantifiers */
@@ -157,6 +136,12 @@ private:
quantifiers::FullSaturation * d_fs;
/** counterexample-based quantifier instantiation */
quantifiers::InstStrategyCbqi * d_i_cbqi;
+ /** quantifiers splitting */
+ quantifiers::QuantDSplit * d_qsplit;
+ /** quantifiers anti-skolemization */
+ quantifiers::QuantAntiSkolem * d_anti_skolem;
+ /** quantifiers instantiation propagtor */
+ quantifiers::InstPropagator * d_inst_prop;
public: //effort levels
enum {
QEFFORT_CONFLICT,
@@ -166,11 +151,21 @@ public: //effort levels
//none
QEFFORT_NONE,
};
+private: //this information is reset during check
+ /** current effort level */
+ unsigned d_curr_effort_level;
+ /** are we in conflict */
+ bool d_conflict;
+ /** number of lemmas we actually added this round (for debugging) */
+ unsigned d_num_added_lemmas_round;
+ /** has added lemma this round */
+ bool d_hasAddedLemma;
private:
/** list of all quantifiers seen */
std::map< Node, bool > d_quants;
/** quantifiers reduced */
- std::map< Node, bool > d_quants_red;
+ BoolMap d_quants_red;
+ std::map< Node, Node > d_quants_red_lem;
/** list of all lemmas produced */
//std::map< Node, bool > d_lemmas_produced;
BoolMap d_lemmas_produced_c;
@@ -178,11 +173,11 @@ private:
std::vector< Node > d_lemmas_waiting;
/** phase requirements waiting */
std::map< Node, bool > d_phase_req_waiting;
- /** has added lemma this round */
- bool d_hasAddedLemma;
/** list of all instantiations produced for each quantifier */
std::map< Node, inst::InstMatchTrie > d_inst_match_trie;
std::map< Node, inst::CDInstMatchTrie* > d_c_inst_match_trie;
+ /** recorded instantiations */
+ std::vector< std::pair< Node, std::vector< Node > > > d_recorded_inst;
/** quantifiers that have been skolemized */
BoolMap d_skolemized;
/** term database */
@@ -195,9 +190,11 @@ private:
std::map< Node, int > d_total_inst_debug;
std::map< Node, int > d_temp_inst_debug;
int d_total_inst_count_debug;
- /** inst round counters */
+ /** inst round counters TODO: make context-dependent? */
+ context::CDO< int > d_ierCounter_c;
int d_ierCounter;
int d_ierCounter_lc;
+ int d_ierCounterLastLc;
int d_inst_when_phase;
/** has presolve been called */
context::CDO< bool > d_presolve;
@@ -253,14 +250,19 @@ public: //modules
quantifiers::FullSaturation * getFullSaturation() { return d_fs; }
/** get inst strategy cbqi */
quantifiers::InstStrategyCbqi * getInstStrategyCbqi() { return d_i_cbqi; }
+ /** get quantifiers splitting */
+ quantifiers::QuantDSplit * getQuantDSplit() { return d_qsplit; }
+ /** get quantifiers anti-skolemization */
+ quantifiers::QuantAntiSkolem * getQuantAntiSkolem() { return d_anti_skolem; }
private:
/** owner of quantified formulas */
std::map< Node, QuantifiersModule * > d_owner;
+ std::map< Node, int > d_owner_priority;
public:
/** get owner */
QuantifiersModule * getOwner( Node q );
/** set owner */
- void setOwner( Node q, QuantifiersModule * m );
+ void setOwner( Node q, QuantifiersModule * m, int priority = 0 );
/** considers */
bool hasOwnership( Node q, QuantifiersModule * m = NULL );
public:
@@ -270,6 +272,8 @@ public:
void presolve();
/** check at level */
void check( Theory::Effort e );
+ /** notify that theories were combined */
+ void notifyCombineTheories();
/** register quantifier */
bool registerQuantifier( Node f );
/** register quantifier */
@@ -281,41 +285,53 @@ public:
/** get next decision request */
Node getNextDecisionRequest();
private:
- /** reduce quantifier */
+ /** reduceQuantifier, return true if reduced */
bool reduceQuantifier( Node q );
/** compute term vector */
void computeTermVector( Node f, InstMatch& m, std::vector< Node >& vars, std::vector< Node >& terms );
- /** instantiate f with arguments terms */
- bool addInstantiationInternal( Node f, std::vector< Node >& vars, std::vector< Node >& terms, bool doVts = false );
+ /** record instantiation, return true if it was non-duplicate */
+ bool recordInstantiationInternal( Node q, std::vector< Node >& terms, bool modEq = false, bool addedLem = true );
+ /** remove instantiation */
+ bool removeInstantiationInternal( Node q, std::vector< Node >& terms );
/** set instantiation level attr */
static void setInstantiationLevelAttr( Node n, Node qn, uint64_t level );
/** flush lemmas */
void flushLemmas();
public:
/** get instantiation */
- Node getInstantiation( Node q, std::vector< Node >& vars, std::vector< Node >& terms );
+ Node getInstantiation( Node q, std::vector< Node >& vars, std::vector< Node >& terms, bool doVts = false );
/** get instantiation */
- Node getInstantiation( Node q, InstMatch& m );
+ Node getInstantiation( Node q, InstMatch& m, bool doVts = false );
/** get instantiation */
- Node getInstantiation( Node q, std::vector< Node >& terms );
+ Node getInstantiation( Node q, std::vector< Node >& terms, bool doVts = false );
/** do substitution */
Node getSubstitute( Node n, std::vector< Node >& terms );
/** add lemma lem */
- bool addLemma( Node lem, bool doCache = true );
+ bool addLemma( Node lem, bool doCache = true, bool doRewrite = true );
+ /** remove pending lemma */
+ bool removeLemma( Node lem );
/** add require phase */
void addRequirePhase( Node lit, bool req );
/** do instantiation specified by m */
- bool addInstantiation( Node q, InstMatch& m, bool mkRep = true, bool modEq = false, bool modInst = false, bool doVts = false );
+ bool addInstantiation( Node q, InstMatch& m, bool mkRep = false, bool modEq = false, bool doVts = false );
/** add instantiation */
- bool addInstantiation( Node q, std::vector< Node >& terms, bool mkRep = true, bool modEq = false, bool modInst = false, bool doVts = false );
+ bool addInstantiation( Node q, std::vector< Node >& terms, bool mkRep = false, bool modEq = false, bool doVts = false );
+ /** remove pending instantiation */
+ bool removeInstantiation( Node q, Node lem, std::vector< Node >& terms );
/** split on node n */
bool addSplit( Node n, bool reqPhase = false, bool reqPhasePol = true );
/** add split equality */
bool addSplitEquality( Node n1, Node n2, bool reqPhase = false, bool reqPhasePol = true );
+ /** mark relevant quantified formula, this will indicate it should be checked before the others */
+ void markRelevant( Node q );
/** has added lemma */
bool hasAddedLemma() { return !d_lemmas_waiting.empty() || d_hasAddedLemma; }
+ /** is in conflict */
+ bool inConflict() { return d_conflict; }
/** get number of waiting lemmas */
unsigned getNumLemmasWaiting() { return d_lemmas_waiting.size(); }
+ /** get number of waiting lemmas */
+ unsigned getNumLemmasAddedThisRound() { return d_num_added_lemmas_round; }
/** get needs check */
bool getInstWhenNeedsCheck( Theory::Effort e );
/** get user pat mode */
@@ -333,6 +349,11 @@ public:
inst::TriggerTrie* getTriggerDatabase() { return d_tr_trie; }
/** add term to database */
void addTermToDatabase( Node n, bool withinQuant = false, bool withinInstClosure = false );
+ /** notification when master equality engine is updated */
+ void eqNotifyNewClass(TNode t);
+ void eqNotifyPreMerge(TNode t1, TNode t2);
+ void eqNotifyPostMerge(TNode t1, TNode t2);
+ void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);
/** get the master equality engine */
eq::EqualityEngine* getMasterEqualityEngine() ;
/** debug print equality engine */
@@ -342,6 +363,8 @@ public:
void printInstantiations( std::ostream& out );
/** print solution for synthesis conjectures */
void printSynthSolution( std::ostream& out );
+ /** get instantiations */
+ void getInstantiations( std::map< Node, std::vector< Node > >& insts );
/** statistics class */
class Statistics {
public:
@@ -376,6 +399,9 @@ class EqualityQueryQuantifiersEngine : public EqualityQuery
private:
/** pointer to theory engine */
QuantifiersEngine* d_qe;
+ /** quantifiers equality inference */
+ quantifiers::EqualityInference * d_eq_inference;
+ context::CDO< unsigned > d_eqi_counter;
/** internal representatives */
std::map< TypeNode, std::map< Node, Node > > d_int_rep;
/** rep score */
@@ -383,15 +409,21 @@ private:
/** reset count */
int d_reset_count;
+ /** processInferences : will merge equivalence classes in master equality engine, if possible */
+ bool processInferences( Theory::Effort e );
/** node contains */
Node getInstance( Node n, const std::vector< Node >& eqc, std::hash_map<TNode, Node, TNodeHashFunction>& cache );
/** get score */
int getRepScore( Node n, Node f, int index, TypeNode v_tn );
+ /** flatten representatives */
+ void flattenRepresentatives( std::map< TypeNode, std::vector< Node > >& reps );
public:
- EqualityQueryQuantifiersEngine( QuantifiersEngine* qe ) : d_qe( qe ), d_reset_count( 0 ){}
- ~EqualityQueryQuantifiersEngine(){}
+ EqualityQueryQuantifiersEngine( context::Context* c, QuantifiersEngine* qe );
+ virtual ~EqualityQueryQuantifiersEngine();
/** reset */
- void reset();
+ bool reset( Theory::Effort e );
+ /** identify */
+ std::string identify() const { return "EqualityQueryQE"; }
/** general queries about equality */
bool hasTerm( Node a );
Node getRepresentative( Node a );
@@ -399,13 +431,14 @@ public:
bool areDisequal( Node a, Node b );
eq::EqualityEngine* getEngine();
void getEquivalenceClass( Node a, std::vector< Node >& eqc );
+ TNode getCongruentTerm( Node f, std::vector< TNode >& args );
/** getInternalRepresentative gets the current best representative in the equivalence class of a, based on some criteria.
If cbqi is active, this will return a term in the equivalence class of "a" that does
not contain instantiation constants, if such a term exists.
*/
Node getInternalRepresentative( Node a, Node f, int index );
- /** flatten representatives */
- void flattenRepresentatives( std::map< TypeNode, std::vector< Node > >& reps );
+ /** get quantifiers equality inference */
+ quantifiers::EqualityInference * getEqualityInference() { return d_eq_inference; }
}; /* EqualityQueryQuantifiersEngine */
}/* CVC4::theory namespace */
diff --git a/src/theory/rep_set.cpp b/src/theory/rep_set.cpp
index a90a4cf17..d7178a8c1 100644
--- a/src/theory/rep_set.cpp
+++ b/src/theory/rep_set.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file rep_set.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of representative set
**/
diff --git a/src/theory/rep_set.h b/src/theory/rep_set.h
index 2df824b5d..08fc7dd52 100644
--- a/src/theory/rep_set.h
+++ b/src/theory/rep_set.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rep_set.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representative set class and utilities
**/
diff --git a/src/theory/rewriter.cpp b/src/theory/rewriter.cpp
index d89724cbd..18ded60a8 100644
--- a/src/theory/rewriter.cpp
+++ b/src/theory/rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file rewriter.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Liana Hadarean, Clark Barrett
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/rewriter.h b/src/theory/rewriter.h
index 5ad6adca8..fc53121e4 100644
--- a/src/theory/rewriter.h
+++ b/src/theory/rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rewriter.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The Rewriter class
**
diff --git a/src/theory/rewriter_attributes.h b/src/theory/rewriter_attributes.h
index d2bbd44ae..5f709de6a 100644
--- a/src/theory/rewriter_attributes.h
+++ b/src/theory/rewriter_attributes.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rewriter_attributes.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter attributes
**
diff --git a/src/theory/rewriter_tables_template.h b/src/theory/rewriter_tables_template.h
index d79f464b5..4d41c023d 100644
--- a/src/theory/rewriter_tables_template.h
+++ b/src/theory/rewriter_tables_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rewriter_tables_template.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters, Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Rewriter tables for various theories
**
diff --git a/src/theory/sets/card_unused_implementation.cpp b/src/theory/sets/card_unused_implementation.cpp
new file mode 100644
index 000000000..488ee1026
--- /dev/null
+++ b/src/theory/sets/card_unused_implementation.cpp
@@ -0,0 +1,312 @@
+// Removing old cardinality implementation, dumping it here.
+
+///////////////////////////////////////////////////////////////
+// Commenting out processCard, creates confusion when writing
+// processCard2
+///////////////////////////////////////////////////////////////
+
+
+// void TheorySetsPrivate::processCard(Theory::Effort level) {
+// if(level != Theory::EFFORT_FULL) return;
+
+
+// Trace("sets-card") << "[sets-card] processCard( " << level << ")" << std::endl;
+// Trace("sets-card") << "[sets-card] # processed terms = " << d_processedCardTerms.size() << std::endl;
+// Trace("sets-card") << "[sets-card] # processed pairs = " << d_processedCardPairs.size() << std::endl;
+// NodeManager* nm = NodeManager::currentNM();
+
+// bool newLemmaGenerated = false;
+
+// // Introduce lemma
+// for(typeof(d_cardTerms.begin()) it = d_cardTerms.begin();
+// it != d_cardTerms.end(); ++it) {
+
+// for(eq::EqClassIterator j(d_equalityEngine.getRepresentative((*it)[0]), &d_equalityEngine);
+// !j.isFinished(); ++j) {
+
+// Node n = nm->mkNode(kind::CARD, (*j));
+
+// if(d_processedCardTerms.find(n) != d_processedCardTerms.end()) {
+// continue;
+// }
+
+// Trace("sets-card") << "[sets-card] Processing " << n << " in eq cl of " << (*it) << std::endl;
+
+// newLemmaGenerated = true;
+// d_processedCardTerms.insert(n);
+
+// Kind k = n[0].getKind();
+
+// if(k == kind::SINGLETON) {
+// d_external.d_out->lemma(nm->mkNode(kind::EQUAL,
+// n,
+// nm->mkConst(Rational(1))));
+// continue;
+// } else {
+// d_external.d_out->lemma(nm->mkNode(kind::GEQ,
+// n,
+// nm->mkConst(Rational(0))));
+// }
+
+// // rest of the processing is for compound terms
+// if(k != kind::UNION && k != kind::INTERSECTION && k != kind::SETMINUS) {
+// continue;
+// }
+
+// Node s = min(n[0][0], n[0][1]);
+// Node t = max(n[0][0], n[0][1]);
+// bool isUnion = (k == kind::UNION);
+// Assert(Rewriter::rewrite(s) == s);
+// Assert(Rewriter::rewrite(t) == t);
+
+// typeof(d_processedCardPairs.begin()) processedInfo = d_processedCardPairs.find(make_pair(s, t));
+
+// if(processedInfo == d_processedCardPairs.end()) {
+
+// Node sNt = nm->mkNode(kind::INTERSECTION, s, t);
+// sNt = Rewriter::rewrite(sNt);
+// Node sMt = nm->mkNode(kind::SETMINUS, s, t);
+// sMt = Rewriter::rewrite(sMt);
+// Node tMs = nm->mkNode(kind::SETMINUS, t, s);
+// tMs = Rewriter::rewrite(tMs);
+
+// Node card_s = nm->mkNode(kind::CARD, s);
+// Node card_t = nm->mkNode(kind::CARD, t);
+// Node card_sNt = nm->mkNode(kind::CARD, sNt);
+// Node card_sMt = nm->mkNode(kind::CARD, sMt);
+// Node card_tMs = nm->mkNode(kind::CARD, tMs);
+
+// Node lem;
+
+// // for s
+// lem = nm->mkNode(kind::EQUAL,
+// card_s,
+// nm->mkNode(kind::PLUS, card_sNt, card_sMt));
+// d_external.d_out->lemma(lem);
+
+// // for t
+// lem = nm->mkNode(kind::EQUAL,
+// card_t,
+// nm->mkNode(kind::PLUS, card_sNt, card_tMs));
+
+// d_external.d_out->lemma(lem);
+
+// // for union
+// if(isUnion) {
+// lem = nm->mkNode(kind::EQUAL,
+// n, // card(s union t)
+// nm->mkNode(kind::PLUS, card_sNt, card_sMt, card_tMs));
+// d_external.d_out->lemma(lem);
+// }
+
+// d_processedCardPairs.insert(make_pair(make_pair(s, t), isUnion));
+
+// } else if(isUnion && processedInfo->second == false) {
+
+// Node sNt = nm->mkNode(kind::INTERSECTION, s, t);
+// sNt = Rewriter::rewrite(sNt);
+// Node sMt = nm->mkNode(kind::SETMINUS, s, t);
+// sMt = Rewriter::rewrite(sMt);
+// Node tMs = nm->mkNode(kind::SETMINUS, t, s);
+// tMs = Rewriter::rewrite(tMs);
+
+// Node card_s = nm->mkNode(kind::CARD, s);
+// Node card_t = nm->mkNode(kind::CARD, t);
+// Node card_sNt = nm->mkNode(kind::CARD, sNt);
+// Node card_sMt = nm->mkNode(kind::CARD, sMt);
+// Node card_tMs = nm->mkNode(kind::CARD, tMs);
+
+// Assert(Rewriter::rewrite(n[0]) == n[0]);
+
+// Node lem = nm->mkNode(kind::EQUAL,
+// n, // card(s union t)
+// nm->mkNode(kind::PLUS, card_sNt, card_sMt, card_tMs));
+// d_external.d_out->lemma(lem);
+
+// processedInfo->second = true;
+// }
+
+// }//equivalence class loop
+
+// }//d_cardTerms loop
+
+// if(newLemmaGenerated) {
+// Trace("sets-card") << "[sets-card] New introduce done. Returning." << std::endl;
+// return;
+// }
+
+
+
+// // Leaves disjoint lemmas
+// buildGraph();
+
+// // Leaves disjoint lemmas
+// for(typeof(leaves.begin()) it = leaves.begin(); it != leaves.end(); ++it) {
+// TNode l1 = (*it);
+// if(d_equalityEngine.getRepresentative(l1).getKind() == kind::EMPTYSET) continue;
+// for(typeof(leaves.begin()) jt = leaves.begin(); jt != leaves.end(); ++jt) {
+// TNode l2 = (*jt);
+
+// if(d_equalityEngine.getRepresentative(l2).getKind() == kind::EMPTYSET) continue;
+
+// if( l1 == l2 ) continue;
+
+// Node l1_inter_l2 = nm->mkNode(kind::INTERSECTION, min(l1, l2), max(l1, l2));
+// l1_inter_l2 = Rewriter::rewrite(l1_inter_l2);
+// Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(l1_inter_l2.getType())));
+// if(d_equalityEngine.hasTerm(l1_inter_l2) &&
+// d_equalityEngine.hasTerm(emptySet) &&
+// d_equalityEngine.areEqual(l1_inter_l2, emptySet)) {
+// Debug("sets-card-graph") << "[sets-card-graph] Disjoint (asserted): " << l1 << " and " << l2 << std::endl;
+// continue; // known to be disjoint
+// }
+
+// std::set<TNode> l1_ancestors = getReachable(edgesBk, l1);
+// std::set<TNode> l2_ancestors = getReachable(edgesBk, l2);
+
+// // have a disjoint edge
+// bool loop = true;
+// bool equality = false;
+// for(typeof(l1_ancestors.begin()) l1_it = l1_ancestors.begin();
+// l1_it != l1_ancestors.end() && loop; ++l1_it) {
+// for(typeof(l2_ancestors.begin()) l2_it = l2_ancestors.begin();
+// l2_it != l2_ancestors.end() && loop; ++l2_it) {
+// TNode n1 = (*l1_it);
+// TNode n2 = (*l2_it);
+// if(disjoint.find(make_pair(n1, n2)) != disjoint.find(make_pair(n2, n1))) {
+// loop = false;
+// }
+// if(n1 == n2) {
+// equality = true;
+// }
+// if(d_equalityEngine.hasTerm(n1) && d_equalityEngine.hasTerm(n2) &&
+// d_equalityEngine.areEqual(n1, n2)) {
+// equality = true;
+// }
+// }
+// }
+// if(loop == false) {
+// Debug("sets-card-graph") << "[sets-card-graph] Disjoint (always): " << l1 << " and " << l2 << std::endl;
+// continue;
+// }
+// if(equality == false) {
+// Debug("sets-card-graph") << "[sets-card-graph] No equality found: " << l1 << " and " << l2 << std::endl;
+// continue;
+// }
+
+// Node lem = nm->mkNode(kind::OR,
+// nm->mkNode(kind::EQUAL, l1_inter_l2, emptySet),
+// nm->mkNode(kind::LT, nm->mkConst(Rational(0)),
+// nm->mkNode(kind::CARD, l1_inter_l2)));
+
+// d_external.d_out->lemma(lem);
+// Trace("sets-card") << "[sets-card] Guessing disjointness of : " << l1 << " and " << l2 << std::endl;
+// if(Debug.isOn("sets-card-disjoint")) {
+// Debug("sets-card-disjoint") << "[sets-card-disjoint] Lemma for " << l1 << " and " << l2 << " generated because:" << std::endl;
+// for(typeof(disjoint.begin()) it = disjoint.begin(); it != disjoint.end(); ++it) {
+// Debug("sets-card-disjoint") << "[sets-card-disjoint] " << it->first << " " << it->second << std::endl;
+// }
+// }
+// newLemmaGenerated = true;
+// Trace("sets-card") << "[sets-card] New intersection being empty lemma generated. Returning." << std::endl;
+// return;
+// }
+// }
+
+// Assert(!newLemmaGenerated);
+
+
+
+// // Elements being either equal or disequal
+
+// for(typeof(leaves.begin()) it = leaves.begin();
+// it != leaves.end(); ++it) {
+// Assert(d_equalityEngine.hasTerm(*it));
+// Node n = d_equalityEngine.getRepresentative(*it);
+// Assert(n.getKind() == kind::EMPTYSET || leaves.find(n) != leaves.end());
+// if(n != *it) continue;
+// const CDTNodeList* l = d_termInfoManager->getMembers(*it);
+// std::set<TNode> elems;
+// for(typeof(l->begin()) l_it = l->begin(); l_it != l->end(); ++l_it) {
+// elems.insert(d_equalityEngine.getRepresentative(*l_it));
+// }
+// for(typeof(elems.begin()) e1_it = elems.begin(); e1_it != elems.end(); ++e1_it) {
+// for(typeof(elems.begin()) e2_it = elems.begin(); e2_it != elems.end(); ++e2_it) {
+// if(*e1_it == *e2_it) continue;
+// if(!d_equalityEngine.areDisequal(*e1_it, *e2_it, false)) {
+// Node lem = nm->mkNode(kind::EQUAL, *e1_it, *e2_it);
+// lem = nm->mkNode(kind::OR, lem, nm->mkNode(kind::NOT, lem));
+// d_external.d_out->lemma(lem);
+// newLemmaGenerated = true;
+// }
+// }
+// }
+// }
+
+// if(newLemmaGenerated) {
+// Trace("sets-card") << "[sets-card] Members arrangments lemmas. Returning." << std::endl;
+// return;
+// }
+
+
+// // Guess leaf nodes being empty or non-empty
+// for(typeof(leaves.begin()) it = leaves.begin(); it != leaves.end(); ++it) {
+// Node n = d_equalityEngine.getRepresentative(*it);
+// if(n.getKind() == kind::EMPTYSET) continue;
+// if(d_termInfoManager->getMembers(n)->size() > 0) continue;
+// Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(n.getType())));
+// if(!d_equalityEngine.hasTerm(emptySet)) {
+// d_equalityEngine.addTerm(emptySet);
+// }
+// if(!d_equalityEngine.areDisequal(n, emptySet, false)) {
+// Node lem = nm->mkNode(kind::EQUAL, n, emptySet);
+// lem = nm->mkNode(kind::OR, lem, nm->mkNode(kind::NOT, lem));
+// Assert(d_cardLowerLemmaCache.find(lem) == d_cardLowerLemmaCache.end());
+// d_cardLowerLemmaCache.insert(lem);
+// d_external.d_out->lemma(lem);
+// newLemmaGenerated = true;
+// break;
+// }
+// }
+
+// if(newLemmaGenerated) {
+// Trace("sets-card") << "[sets-card] New guessing leaves being empty done." << std::endl;
+// return;
+// }
+
+// // Assert Lower bound
+// for(typeof(leaves.begin()) it = leaves.begin();
+// it != leaves.end(); ++it) {
+// Assert(d_equalityEngine.hasTerm(*it));
+// Node n = d_equalityEngine.getRepresentative(*it);
+// Assert(n.getKind() == kind::EMPTYSET || leaves.find(n) != leaves.end());
+// if(n != *it) continue;
+// const CDTNodeList* l = d_termInfoManager->getMembers(n);
+// std::set<TNode> elems;
+// for(typeof(l->begin()) l_it = l->begin(); l_it != l->end(); ++l_it) {
+// elems.insert(d_equalityEngine.getRepresentative(*l_it));
+// }
+// if(elems.size() == 0) continue;
+// NodeBuilder<> nb(kind::OR);
+// nb << ( nm->mkNode(kind::LEQ, nm->mkConst(Rational(elems.size())), nm->mkNode(kind::CARD, n)) );
+// if(elems.size() > 1) {
+// for(typeof(elems.begin()) e1_it = elems.begin(); e1_it != elems.end(); ++e1_it) {
+// for(typeof(elems.begin()) e2_it = elems.begin(); e2_it != elems.end(); ++e2_it) {
+// if(*e1_it == *e2_it) continue;
+// nb << (nm->mkNode(kind::EQUAL, *e1_it, *e2_it));
+// }
+// }
+// }
+// for(typeof(elems.begin()) e_it = elems.begin(); e_it != elems.end(); ++e_it) {
+// nb << nm->mkNode(kind::NOT, nm->mkNode(kind::MEMBER, *e_it, n));
+// }
+// Node lem = Node(nb);
+// if(d_cardLowerLemmaCache.find(lem) == d_cardLowerLemmaCache.end()) {
+// Trace("sets-card") << "[sets-card] Card Lower: " << lem << std::endl;
+// d_external.d_out->lemma(lem);
+// d_cardLowerLemmaCache.insert(lem);
+// newLemmaGenerated = true;
+// }
+// }
+// }
+
diff --git a/src/theory/sets/expr_patterns.h b/src/theory/sets/expr_patterns.h
index f293d0714..32e77d8b8 100644
--- a/src/theory/sets/expr_patterns.h
+++ b/src/theory/sets/expr_patterns.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file expr_patterns.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Expr patterns.
**
@@ -54,6 +54,10 @@ static Node EQUAL(TNode a, TNode b) {
return NodeManager::currentNM()->mkNode(kind::EQUAL, a, b);
}
+static Node CARD(TNode a) {
+ return NodeManager::currentNM()->mkNode(kind::CARD, a);
+}
+
}/* CVC4::expr::pattern namespace */
}/* CVC4::expr namespace */
}/* CVC4 namespace */
diff --git a/src/theory/sets/kinds b/src/theory/sets/kinds
index efd00093a..3fb73749d 100644
--- a/src/theory/sets/kinds
+++ b/src/theory/sets/kinds
@@ -12,7 +12,7 @@ rewriter ::CVC4::theory::sets::TheorySetsRewriter \
"theory/sets/theory_sets_rewriter.h"
properties parametric
-properties check propagate
+properties check propagate presolve
# constants
constant EMPTYSET \
@@ -42,6 +42,7 @@ operator SUBSET 2 "subset predicate; first parameter a subset of second"
operator MEMBER 2 "set membership predicate; first parameter a member of second"
operator SINGLETON 1 "the set of the single element given as a parameter"
operator INSERT 2: "set obtained by inserting elements (first N-1 parameters) into a set (the last parameter)"
+operator CARD 1 "set cardinality operator"
operator JOIN 2 "set join"
operator PRODUCT 2 "set cartesian product"
@@ -56,6 +57,7 @@ typerule MEMBER ::CVC4::theory::sets::MemberTypeRule
typerule SINGLETON ::CVC4::theory::sets::SingletonTypeRule
typerule EMPTYSET ::CVC4::theory::sets::EmptySetTypeRule
typerule INSERT ::CVC4::theory::sets::InsertTypeRule
+typerule CARD ::CVC4::theory::sets::CardTypeRule
typerule JOIN ::CVC4::theory::sets::RelBinaryOperatorTypeRule
typerule PRODUCT ::CVC4::theory::sets::RelBinaryOperatorTypeRule
@@ -67,6 +69,7 @@ construle INTERSECTION ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
construle SETMINUS ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
construle SINGLETON ::CVC4::theory::sets::SingletonTypeRule
construle INSERT ::CVC4::theory::sets::InsertTypeRule
+construle CARD ::CVC4::theory::sets::CardTypeRule
construle JOIN ::CVC4::theory::sets::RelBinaryOperatorTypeRule
construle PRODUCT ::CVC4::theory::sets::RelBinaryOperatorTypeRule
diff --git a/src/theory/sets/normal_form.h b/src/theory/sets/normal_form.h
index 13da6d57e..6da7e9f8f 100644
--- a/src/theory/sets/normal_form.h
+++ b/src/theory/sets/normal_form.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file normal_form.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Normal form for set constants.
**
diff --git a/src/theory/sets/scrutinize.h b/src/theory/sets/scrutinize.h
index dc5feecda..2ada4a3ce 100644
--- a/src/theory/sets/scrutinize.h
+++ b/src/theory/sets/scrutinize.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file scrutinize.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Check consistency of internal data structures.
**
diff --git a/src/theory/sets/term_info.h b/src/theory/sets/term_info.h
index 3168817e2..c7d4b38bc 100644
--- a/src/theory/sets/term_info.h
+++ b/src/theory/sets/term_info.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file term_info.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Term info.
**
diff --git a/src/theory/sets/theory_sets.cpp b/src/theory/sets/theory_sets.cpp
index 1280ad58d..bdbc964c6 100644
--- a/src/theory/sets/theory_sets.cpp
+++ b/src/theory/sets/theory_sets.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory.
**
@@ -70,6 +70,10 @@ void TheorySets::preRegisterTerm(TNode node) {
d_internal->preRegisterTerm(node);
}
+void TheorySets::presolve() {
+ d_internal->presolve();
+}
+
void TheorySets::propagate(Effort e) {
d_internal->propagate(e);
}
diff --git a/src/theory/sets/theory_sets.h b/src/theory/sets/theory_sets.h
index 9e08b597d..840135937 100644
--- a/src/theory/sets/theory_sets.h
+++ b/src/theory/sets/theory_sets.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory.
**
@@ -64,6 +64,8 @@ public:
void preRegisterTerm(TNode node);
+ void presolve();
+
void propagate(Effort);
void setMasterEqualityEngine(eq::EqualityEngine* eq);
diff --git a/src/theory/sets/theory_sets_private.cpp b/src/theory/sets/theory_sets_private.cpp
index fee47e3cb..bc9227e54 100644
--- a/src/theory/sets/theory_sets_private.cpp
+++ b/src/theory/sets/theory_sets_private.cpp
@@ -1,19 +1,20 @@
/********************* */
/*! \file theory_sets_private.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory implementation.
**
** Sets theory implementation.
**/
+#include <algorithm>
#include "theory/sets/theory_sets_private.h"
#include <boost/foreach.hpp>
@@ -36,12 +37,15 @@ namespace sets {
const char* element_of_str = " \u2208 ";
+// Declaration of functions defined later in this CPP file
+const std::set<TNode> getLeaves(map<TNode, set<TNode> >& edges, TNode node);
+
/**************************** TheorySetsPrivate *****************************/
/**************************** TheorySetsPrivate *****************************/
/**************************** TheorySetsPrivate *****************************/
void TheorySetsPrivate::check(Theory::Effort level) {
-
+ d_newLemmaGenerated = false;
while(!d_external.done() && !d_conflict) {
// Get all the assertions
Assertion assertion = d_external.get();
@@ -100,13 +104,17 @@ void TheorySetsPrivate::check(Theory::Effort level) {
d_rels->check(level);
if( (level == Theory::EFFORT_FULL || options::setsEagerLemmas() ) && !isComplete()) {
- d_external.d_out->lemma(getLemma());
+ lemma(getLemma(), SETS_LEMMA_OTHER);
return;
}
+
+ //processCard(level);
+ processCard2(level);
+
// if we are here, there is no conflict and we are complete
if(Debug.isOn("sets-scrutinize")) { d_scrutinize->postCheckInvariants(); }
-
+
return;
}/* TheorySetsPrivate::check() */
@@ -119,31 +127,39 @@ void TheorySetsPrivate::assertEquality(TNode fact, TNode reason, bool learnt)
bool polarity = fact.getKind() != kind::NOT;
TNode atom = polarity ? fact : fact[0];
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** 0" <<std::endl;
// fact already holds
if( holds(atom, polarity) ) {
Debug("sets-assert") << "[sets-assert] already present, skipping" << std::endl;
return;
}
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** 1" <<std::endl;
// assert fact & check for conflict
if(learnt) {
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** 5" <<std::endl;
registerReason(reason, /*save=*/ true);
}
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** 4" <<std::endl;
d_equalityEngine.assertEquality(atom, polarity, reason);
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** 2" <<std::endl;
if(!d_equalityEngine.consistent()) {
Debug("sets-assert") << "[sets-assert] running into a conflict" << std::endl;
d_conflict = true;
return;
}
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** 3" <<std::endl;
+
+ if(atom[0].getKind() == kind::CARD && isCardVar(atom[0])) {
+ NodeManager* nm = NodeManager::currentNM();
+ Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(atom[0].getType())));
+ Node newFact = nm->mkNode(kind::EQUAL, getCardVar(atom[0]), emptySet);
+ if(!polarity) newFact = nm->mkNode(kind::NOT, newFact);
+ learnLiteral(newFact, fact);
+ }
+
+ // disequality lemma
if(!polarity && atom[0].getType().isSet()) {
addToPending(atom);
}
- Debug("sets-assert") << "\n finish assert equality!!!!!!!*************** " <<std::endl;
+
+ // for cardinality
+ if(polarity && atom[0].getType().isSet()) {
+ d_graphMergesPending.push(make_pair(atom[0], atom[1]));
+ }
}/* TheorySetsPrivate::assertEquality() */
@@ -371,11 +387,12 @@ void TheorySetsPrivate::doSettermPropagation(TNode x, TNode S)
addToPending( MEMBER(x, S[0]) );
break;
case kind::SETMINUS: // intentional fallthrough
- case kind::INTERSECTION:
if( holds(MEMBER(x, S[0])) &&
!present( MEMBER(x, S[1]) ))
addToPending( MEMBER(x, S[1]) );
break;
+ case kind::INTERSECTION:
+ return;
default:
Assert(false, "MembershipEngine::doSettermPropagation");
}
@@ -412,6 +429,33 @@ void TheorySetsPrivate::learnLiteral(TNode atom, bool polarity, Node reason) {
}/*TheorySetsPrivate::learnLiteral(...)*/
+/************************ CardVar ************************/
+
+Node TheorySetsPrivate::getCardVar(TNode n) {
+ NodeNodeHashMap::iterator it = d_setTermToCardVar.find(n);
+ if(it == d_setTermToCardVar.end()) {
+ return it->second;
+ } else {
+ NodeManager* nm = NodeManager::currentNM();
+ Node cardVar = nm->mkSkolem("scv_", n.getType());
+ d_setTermToCardVar[n] = cardVar;
+ d_cardVarToSetTerm[cardVar] = n;
+ return cardVar;
+ }
+}
+
+Node TheorySetsPrivate::newCardVar(TNode n) {
+ NodeNodeHashMap::iterator it = d_cardVarToSetTerm.find(n);
+ Assert(it != d_cardVarToSetTerm.end());
+ return it->second;
+}
+
+bool TheorySetsPrivate::isCardVar(TNode n) {
+ NodeNodeHashMap::iterator it = d_cardVarToSetTerm.find(n);
+ return it != d_cardVarToSetTerm.end();
+}
+
+
/************************ Sharing ************************/
/************************ Sharing ************************/
/************************ Sharing ************************/
@@ -840,11 +884,23 @@ Node TheorySetsPrivate::elementsToShape(set<Node> elements, TypeNode setType) co
void TheorySetsPrivate::collectModelInfo(TheoryModel* m, bool fullModel)
{
- Debug("sets-model") << "[sets-model] collectModelInfo(..., fullModel="
+ Trace("sets-model") << "[sets-model] collectModelInfo(..., fullModel="
<< (fullModel ? "true)" : "false)") << std::endl;
set<Node> terms;
+ NodeManager* nm = NodeManager::currentNM();
+
+ // // this is for processCard -- commenting out for now
+ // if(Debug.isOn("sets-card")) {
+ // for(typeof(d_cardTerms.begin()) it = d_cardTerms.begin();
+ // it != d_cardTerms.end(); ++it) {
+ // Debug("sets-card") << "[sets-card] " << *it << " = "
+ // << d_external.d_valuation.getModelValue(*it)
+ // << std::endl;
+ // }
+ // }
+
if(Trace.isOn("sets-assertions")) {
dumpAssertionsHumanified();
}
@@ -852,6 +908,23 @@ void TheorySetsPrivate::collectModelInfo(TheoryModel* m, bool fullModel)
// Compute terms appearing assertions and shared terms
d_external.computeRelevantTerms(terms);
+ //processCard2 begin
+ if(Debug.isOn("sets-card")) {
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it) {
+ Node n = nm->mkNode(kind::CARD, *it);
+ Debug("sets-card") << "[sets-card] " << n << " = ";
+ // if(d_external.d_sharedTerms.find(n) == d_external.d_sharedTerms.end()) continue;
+ if((Rewriter::rewrite(n)).isConst()) {
+ Debug("sets-card") << (Rewriter::rewrite(n))
+ << std::endl;
+ } else {
+ Debug("sets-card") << d_external.d_valuation.getModelValue(n)
+ << std::endl;
+ }
+ }
+ }
+ //processCard2 end
+
// Compute for each setterm elements that it contains
SettermElementsMap settermElementsMap;
for(eq::EqClassIterator it_eqclasses(d_trueNode, &d_equalityEngine);
@@ -864,10 +937,10 @@ void TheorySetsPrivate::collectModelInfo(TheoryModel* m, bool fullModel)
settermElementsMap[S].insert(x);
}
if(Debug.isOn("sets-model-details")) {
- vector<TNode> explanation;
- d_equalityEngine.explainPredicate(n, true, explanation);
Debug("sets-model-details")
<< "[sets-model-details] > node: " << n << ", explanation:" << std::endl;
+ vector<TNode> explanation;
+ d_equalityEngine.explainPredicate(n, true, explanation);
BOOST_FOREACH(TNode m, explanation) {
Debug("sets-model-details") << "[sets-model-details] >> " << m << std::endl;
}
@@ -879,9 +952,9 @@ void TheorySetsPrivate::collectModelInfo(TheoryModel* m, bool fullModel)
! it_eqclasses.isFinished() ; ++it_eqclasses) {
TNode n = (*it_eqclasses);
vector<TNode> explanation;
- d_equalityEngine.explainPredicate(n, false, explanation);
Debug("sets-model-details")
<< "[sets-model-details] > node: not: " << n << ", explanation:" << std::endl;
+ d_equalityEngine.explainPredicate(n, false, explanation);
BOOST_FOREACH(TNode m, explanation) {
Debug("sets-model-details") << "[sets-model-details] >> " << m << std::endl;
}
@@ -913,16 +986,74 @@ void TheorySetsPrivate::collectModelInfo(TheoryModel* m, bool fullModel)
}
}
- BOOST_FOREACH( SettermElementsMap::value_type &it, settermElementsMap ) {
- BOOST_FOREACH( TNode element, it.second /* elements */ ) {
- Debug("sets-model-details") << "[sets-model-details] > " <<
- (it.first /* setterm */) << ": " << element << std::endl;
+ if(Debug.isOn("sets-model-details")) {
+ BOOST_FOREACH( SettermElementsMap::value_type &it, settermElementsMap ) {
+ BOOST_FOREACH( TNode element, it.second /* elements */ ) {
+ Debug("sets-model-details") << "[sets-model-details] > " <<
+ (it.first /* setterm */) << ": " << element << std::endl;
+ }
+ }
+ }
+
+ // build graph, and create sufficient number of skolems
+ // buildGraph(); // this is for processCard
+
+ //processCard2 begin
+ leaves.clear();
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it)
+ if(d_E.find(*it) == d_E.end())
+ leaves.insert(*it);
+ d_statistics.d_numLeaves.setData(leaves.size());
+ d_statistics.d_numLeavesMax.maxAssign(leaves.size());
+ //processCard2 end
+
+ std::hash_map<TNode, std::vector<TNode>, TNodeHashFunction> slackElements;
+ BOOST_FOREACH( TNode setterm, leaves ) {
+ if(setterm.getKind() == kind::EMPTYSET) { continue; }
+ // Assert(d_cardTerms.find(nm->mkNode(kind::CARD,setterm)) != d_cardTerms.end()); // for processCard
+ Assert(d_V.find(setterm) != d_V.end());
+ Node cardValNode = d_external.d_valuation.getModelValue(nm->mkNode(kind::CARD,setterm));
+ Rational cardValRational = cardValNode.getConst<Rational>();
+ Assert(cardValRational.isIntegral());
+ Integer cardValInteger = cardValRational.getNumerator();
+ Assert(cardValInteger.fitsSignedInt(), "Can't build models that big.");
+ int cardValInt = cardValInteger.getSignedInt();
+ Assert(cardValInt >= 0);
+ int numElems = getElements(setterm, settermElementsMap).size();
+ Trace("sets-model-card") << "[sets-model-card] cardValInt = " << cardValInt << std::endl
+ << " numElems = " << numElems << std::endl;
+ Trace("sets-model-card") << "[sets-model-card] Creating " << cardValInt-numElems
+ << " slack variables for " << setterm << std::endl;
+ Assert(cardValInt >= numElems, "Run with -d sets-model-card for details");
+
+ TypeNode elementType = setterm.getType().getSetElementType();
+ std::vector<TNode>& cur = slackElements[setterm];
+ for(int i = numElems; i < cardValInt; ++i) {
+ // slk = slack
+ cur.push_back(nm->mkSkolem("slk_", elementType));
}
}
// assign representatives to equivalence class
BOOST_FOREACH( TNode setterm, settermsModEq ) {
Elements elements = getElements(setterm, settermElementsMap);
+ if(d_E.find(setterm) != d_E.end()) {
+ Trace("sets-model-card") << "[sets-model-card] " << setterm << " (before slacks): " << elements.size() << std::endl;
+ std::set<TNode> leafChildren = get_leaves(setterm);
+ BOOST_FOREACH( TNode leafChild, leafChildren ) {
+ if(leaves.find(leafChild) == leaves.end()) { continue; }
+ BOOST_FOREACH( TNode slackVar, slackElements[leafChild] ) {
+ elements.insert(slackVar);
+ }
+ }
+ Trace("sets-model-card") << "[sets-model-card] " << setterm << " (after slacks): " << elements.size() << std::endl;
+ } else if(d_V.find(setterm) != d_V.end()) {
+ Trace("sets-model-card") << "[sets-model-card] " << setterm << " (before slacks): " << elements.size() << std::endl;
+ BOOST_FOREACH( TNode slackVar, slackElements[setterm] ) {
+ elements.insert(slackVar);
+ }
+ Trace("sets-model-card") << "[sets-model-card] " << setterm << " (after slacks): " << elements.size() << std::endl;
+ }
Node shape = elementsToShape(elements, setterm.getType());
shape = theory::Rewriter::rewrite(shape);
m->assertEquality(shape, setterm, true);
@@ -996,20 +1127,44 @@ Node mkAnd(const std::vector<TNode>& conjunctions) {
TheorySetsPrivate::Statistics::Statistics() :
- d_getModelValueTime("theory::sets::getModelValueTime")
+ d_getModelValueTime("theory::sets::getModelValueTime")
+ , d_mergeTime("theory::sets::merge_nodes::time")
+ , d_processCard2Time("theory::sets::processCard2::time")
, d_memberLemmas("theory::sets::lemmas::member", 0)
, d_disequalityLemmas("theory::sets::lemmas::disequality", 0)
+ , d_numVertices("theory::sets::vertices", 0)
+ , d_numVerticesMax("theory::sets::vertices-max", 0)
+ , d_numMergeEq1or2("theory::sets::merge1or2", 0)
+ , d_numMergeEq3("theory::sets::merge3", 0)
+ , d_numLeaves("theory::sets::leaves", 0)
+ , d_numLeavesMax("theory::sets::leaves-max", 0)
{
smtStatisticsRegistry()->registerStat(&d_getModelValueTime);
+ smtStatisticsRegistry()->registerStat(&d_mergeTime);
+ smtStatisticsRegistry()->registerStat(&d_processCard2Time);
smtStatisticsRegistry()->registerStat(&d_memberLemmas);
smtStatisticsRegistry()->registerStat(&d_disequalityLemmas);
+ smtStatisticsRegistry()->registerStat(&d_numVertices);
+ smtStatisticsRegistry()->registerStat(&d_numVerticesMax);
+ smtStatisticsRegistry()->registerStat(&d_numMergeEq1or2);
+ smtStatisticsRegistry()->registerStat(&d_numMergeEq3);
+ smtStatisticsRegistry()->registerStat(&d_numLeaves);
+ smtStatisticsRegistry()->registerStat(&d_numLeavesMax);
}
TheorySetsPrivate::Statistics::~Statistics() {
smtStatisticsRegistry()->unregisterStat(&d_getModelValueTime);
+ smtStatisticsRegistry()->unregisterStat(&d_mergeTime);
+ smtStatisticsRegistry()->unregisterStat(&d_processCard2Time);
smtStatisticsRegistry()->unregisterStat(&d_memberLemmas);
smtStatisticsRegistry()->unregisterStat(&d_disequalityLemmas);
+ smtStatisticsRegistry()->unregisterStat(&d_numVertices);
+ smtStatisticsRegistry()->unregisterStat(&d_numVerticesMax);
+ smtStatisticsRegistry()->unregisterStat(&d_numMergeEq1or2);
+ smtStatisticsRegistry()->unregisterStat(&d_numMergeEq3);
+ smtStatisticsRegistry()->unregisterStat(&d_numLeaves);
+ smtStatisticsRegistry()->unregisterStat(&d_numLeavesMax);
}
@@ -1036,9 +1191,10 @@ void TheorySetsPrivate::registerReason(TNode reason, bool save)
if(save) d_nodeSaver.insert(reason);
if(reason.getKind() == kind::AND) {
- Assert(reason.getNumChildren() == 2);
- registerReason(reason[0], false);
- registerReason(reason[1], false);
+ //Assert(reason.getNumChildren() == 2);
+ for(unsigned i = 0; i < reason.getNumChildren(); ++i) {
+ registerReason(reason[i], false);
+ }
} else if(reason.getKind() == kind::NOT) {
registerReason(reason[0], false);
} else if(reason.getKind() == kind::MEMBER) {
@@ -1100,7 +1256,8 @@ void TheorySetsPrivate::addToPending(Node n) {
<< std::endl;
++d_statistics.d_memberLemmas;
d_pending.push(n);
- d_external.d_out->splitLemma(getLemma());
+ lemma(getLemma(), SETS_LEMMA_MEMBER);
+ // d_external.d_out->splitLemma();
Assert(isComplete());
} else {
@@ -1110,7 +1267,8 @@ void TheorySetsPrivate::addToPending(Node n) {
Assert(n.getKind() == kind::EQUAL);
++d_statistics.d_disequalityLemmas;
d_pendingDisequal.push(n);
- d_external.d_out->splitLemma(getLemma());
+ lemma(getLemma(), SETS_LEMMA_DISEQUAL);
+ // d_external.d_out->splitLemma();
Assert(isComplete());
}
@@ -1151,7 +1309,13 @@ Node TheorySetsPrivate::getLemma() {
Node x = NodeManager::currentNM()->mkSkolem("sde_", elementType);
Node l1 = MEMBER(x, n[0]), l2 = MEMBER(x, n[1]);
- lemma = OR(n, AND(l1, NOT(l2)), AND(NOT(l1), l2));
+ if(n[0].getKind() == kind::EMPTYSET) {
+ lemma = OR(n, l2);
+ } else if(n[1].getKind() == kind::EMPTYSET) {
+ lemma = OR(n, l1);
+ } else {
+ lemma = OR(n, AND(l1, NOT(l2)), AND(NOT(l1), l2));
+ }
}
Debug("sets-lemma") << "[sets-lemma] Generating for " << n
@@ -1171,6 +1335,8 @@ TheorySetsPrivate::TheorySetsPrivate(TheorySets& external,
d_falseNode(NodeManager::currentNM()->mkConst<bool>(false)),
d_conflict(c),
d_termInfoManager(NULL),
+ d_setTermToCardVar(),
+ d_cardVarToSetTerm(),
d_propagationQueue(c),
d_settermPropagationQueue(c),
d_nodeSaver(c),
@@ -1181,7 +1347,24 @@ TheorySetsPrivate::TheorySetsPrivate(TheorySets& external,
d_ccg_i(c),
d_ccg_j(c),
d_scrutinize(NULL),
- d_rels(NULL)
+ d_rels(NULL),
+ d_cardEnabled(false),
+ d_cardTerms(c),
+ d_typesAdded(),
+ d_processedCardTerms(c),
+ d_processedCardPairs(),
+ d_cardLowerLemmaCache(u),
+ edgesFd(),
+ edgesBk(),
+ disjoint(),
+ leaves(),
+ d_V(c),
+ d_E(c),
+ d_graphMergesPending(c),
+ d_allSetEqualitiesSoFar(c),
+ d_lemmasGenerated(u),
+ d_newLemmaGenerated(false),
+ d_relTerms(u)
{
d_termInfoManager = new TermInfoManager(*this, c, &d_equalityEngine);
d_rels = new TheorySetsRels(c, u, &d_equalityEngine, &d_conflict, external);
@@ -1193,6 +1376,9 @@ TheorySetsPrivate::TheorySetsPrivate(TheorySets& external,
d_equalityEngine.addFunctionKind(kind::MEMBER);
d_equalityEngine.addFunctionKind(kind::SUBSET);
+ // If cardinality is on.
+ d_equalityEngine.addFunctionKind(kind::CARD);
+
if( Debug.isOn("sets-scrutinize") ) {
d_scrutinize = new TheorySetsScrutinize(this);
}
@@ -1308,6 +1494,30 @@ Node TheorySetsPrivate::explain(TNode literal)
return mkAnd(assumptions);
}
+bool TheorySetsPrivate::lemma(Node n, SetsLemmaTag t)
+{
+ if(d_lemmasGenerated.find(n) != d_lemmasGenerated.end()) {
+ return false;
+ }
+ d_lemmasGenerated.insert(n);
+ d_newLemmaGenerated = true;
+ switch(t) {
+ case SETS_LEMMA_DISEQUAL:
+ case SETS_LEMMA_MEMBER: {
+ d_external.d_out->splitLemma(n);
+ break;
+ }
+ case SETS_LEMMA_GRAPH:// {
+ // d_external.d_out->preservedLemma(n, false, false);
+ // break;
+ // }
+ case SETS_LEMMA_OTHER: {
+ d_external.d_out->lemma(n);
+ break;
+ }
+ }
+ return true;
+}
void TheorySetsPrivate::preRegisterTerm(TNode node)
{
@@ -1323,6 +1533,11 @@ void TheorySetsPrivate::preRegisterTerm(TNode node)
// TODO: what's the point of this
d_equalityEngine.addTriggerPredicate(node);
break;
+ case kind::CARD:
+ if(!d_cardEnabled) { enableCard(); }
+ registerCard(node);
+ d_equalityEngine.addTriggerTerm(node, THEORY_SETS);
+ break;
default:
d_termInfoManager->addTerm(node);
d_equalityEngine.addTriggerTerm(node, THEORY_SETS);
@@ -1331,9 +1546,38 @@ void TheorySetsPrivate::preRegisterTerm(TNode node)
if(node.getKind() == kind::SINGLETON) {
learnLiteral(MEMBER(node[0], node), true, d_trueNode);
}
+
+ // ** For cardinality reasoning **
+ if(node.getType().isSet() && d_typesAdded.find(node.getType()) == d_typesAdded.end()) {
+ d_typesAdded.insert(node.getType());
+
+ if(d_cardEnabled) {
+ cardCreateEmptysetSkolem(node.getType());
+ }
+ }
+ if(d_cardEnabled && node.getKind() == kind::SINGLETON) {
+ registerCard(NodeManager::currentNM()->mkNode(kind::CARD, node));
+ }
}
+void TheorySetsPrivate::presolve() {
+
+ for(typeof(d_termInfoManager->d_terms.begin()) it = d_termInfoManager->d_terms.begin();
+ it != d_termInfoManager->d_terms.end(); ++it) {
+ d_relTerms.insert(*it);
+ }
+
+ if(Trace.isOn("sets-relterms")) {
+ Trace("sets-relterms") << "[sets-relterms] ";
+ for(typeof(d_relTerms.begin()) it = d_relTerms.begin();
+ it != d_relTerms.end(); ++it ) {
+ Trace("sets-relterms") << (*it) << ", ";
+ }
+ Trace("sets-relterms") << "\n";
+ }
+
+}
/**************************** eq::NotifyClass *****************************/
/**************************** eq::NotifyClass *****************************/
@@ -1367,7 +1611,7 @@ bool TheorySetsPrivate::NotifyClass::eqNotifyTriggerTermEquality(TheoryId tag, T
{
Debug("sets-eq") << "[sets-eq] eqNotifyTriggerTermEquality: tag = " << tag
<< " t1 = " << t1 << " t2 = " << t2 << " value = " << value << std::endl;
- if(value) {
+ if(value && t1.getKind() != kind::CARD && t2.getKind() != kind::CARD) {
d_theory.d_termInfoManager->mergeTerms(t1, t2);
}
d_theory.propagate( value ? EQUAL(t1, t2) : NOT(EQUAL(t1, t2)) );
@@ -1488,7 +1732,12 @@ void TheorySetsPrivate::TermInfoManager::addTerm(TNode n) {
if(d_terms.contains(n[i])) {
Debug("sets-parent") << "Adding " << n << " to parent list of "
<< n[i] << std::endl;
+
+ // introduce cardinality of this set if a child's cardinality appears
d_info[n[i]]->parents->push_back(n);
+ if(d_theory.d_cardTerms.find(CARD(n[i])) != d_theory.d_cardTerms.end()) {
+ d_theory.registerCard(CARD(n));
+ }
typeof(d_info.begin()) ita = d_info.find(d_eqEngine->getRepresentative(n[i]));
Assert(ita != d_info.end());
@@ -1656,6 +1905,907 @@ Node TheorySetsPrivate::TermInfoManager::getModelValue(TNode n)
return v;
}
+
+
+
+/********************** Cardinality ***************************/
+/********************** Cardinality ***************************/
+/********************** Cardinality ***************************/
+
+void TheorySetsPrivate::enableCard()
+{
+ Assert(!d_cardEnabled);
+ Trace("sets-card") << "[sets-card] Enabling cardinality reasoning" << std::endl;
+ d_cardEnabled = true;
+
+ BOOST_FOREACH( TypeNode t, d_typesAdded ) {
+ cardCreateEmptysetSkolem(t);
+ }
+
+ for(typeof(d_termInfoManager->d_terms.begin()) it = d_termInfoManager->d_terms.begin();
+ it != d_termInfoManager->d_terms.end(); ++it) {
+ Node n = (*it);
+ if(n.getKind() == kind::SINGLETON) {
+ registerCard(NodeManager::currentNM()->mkNode(kind::CARD, n));
+ }
+ }
+}
+
+void TheorySetsPrivate::registerCard(TNode node) {
+ Trace("sets-card") << "[sets-card] registerCard( " << node << ")" << std::endl;
+ if(d_cardTerms.find(node) == d_cardTerms.end()) {
+ d_cardTerms.insert(node);
+
+ // introduce cardinality of any set-term containing this term
+ NodeManager* nm = NodeManager::currentNM();
+ const CDTNodeList* parentList = d_termInfoManager->getParents(node[0]);
+ for(typeof(parentList->begin()) it = parentList->begin();
+ it != parentList->end(); ++it) {
+ registerCard(nm->mkNode(kind::CARD, *it));
+ }
+ }
+}
+
+
+void TheorySetsPrivate::cardCreateEmptysetSkolem(TypeNode t) {
+ // set cardinality zero
+ NodeManager* nm = NodeManager::currentNM();
+ Debug("sets-card") << "Creating skolem for emptyset for type "
+ << t << std::endl;
+ Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(t)));
+ Node sk = nm->mkSkolem("scz_", t);
+ lemma(nm->mkNode(kind::EQUAL, sk, emptySet), SETS_LEMMA_OTHER);
+ lemma(nm->mkNode(kind::EQUAL, nm->mkConst(Rational(0)), nm->mkNode(kind::CARD, sk)), SETS_LEMMA_OTHER);
+}
+
+
+void TheorySetsPrivate::buildGraph() {
+
+ NodeManager* nm = NodeManager::currentNM();
+
+ edgesFd.clear();
+ edgesBk.clear();
+ disjoint.clear();
+
+ for(typeof(d_processedCardPairs.begin()) it = d_processedCardPairs.begin();
+ it != d_processedCardPairs.end(); ++it) {
+ Node s = (it->first).first;
+ Assert(Rewriter::rewrite(s) == s);
+ Node t = (it->first).second;
+ Assert(Rewriter::rewrite(t) == t);
+ bool hasUnion = (it->second);
+
+ Node sNt = nm->mkNode(kind::INTERSECTION, s, t);
+ sNt = Rewriter::rewrite(sNt);
+ Node sMt = nm->mkNode(kind::SETMINUS, s, t);
+ sMt = Rewriter::rewrite(sMt);
+ Node tMs = nm->mkNode(kind::SETMINUS, t, s);
+ tMs = Rewriter::rewrite(tMs);
+
+ edgesFd[s].insert(sNt);
+ edgesFd[s].insert(sMt);
+ edgesBk[sNt].insert(s);
+ edgesBk[sMt].insert(s);
+
+ edgesFd[t].insert(sNt);
+ edgesFd[t].insert(tMs);
+ edgesBk[sNt].insert(t);
+ edgesBk[tMs].insert(t);
+
+ if(hasUnion) {
+ Node sUt = nm->mkNode(kind::UNION, s, t);
+ sUt = Rewriter::rewrite(sUt);
+
+ edgesFd[sUt].insert(sNt);
+ edgesFd[sUt].insert(sMt);
+ edgesFd[sUt].insert(tMs);
+ edgesBk[sNt].insert(sUt);
+ edgesBk[sMt].insert(sUt);
+ edgesBk[tMs].insert(sUt);
+ }
+
+ disjoint.insert(make_pair(sNt, sMt));
+ disjoint.insert(make_pair(sMt, sNt));
+ disjoint.insert(make_pair(sNt, tMs));
+ disjoint.insert(make_pair(tMs, sNt));
+ disjoint.insert(make_pair(tMs, sMt));
+ disjoint.insert(make_pair(sMt, tMs));
+ }
+
+ if(Debug.isOn("sets-card-graph")) {
+ Debug("sets-card-graph") << "[sets-card-graph] Fd:" << std::endl;
+ for(typeof(edgesFd.begin()) it = edgesFd.begin();
+ it != edgesFd.end(); ++it) {
+ Debug("sets-card-graph") << "[sets-card-graph] " << (it->first) << std::endl;
+ for(typeof( (it->second).begin()) jt = (it->second).begin();
+ jt != (it->second).end(); ++jt) {
+ Debug("sets-card-graph") << "[sets-card-graph] " << (*jt) << std::endl;
+ }
+ }
+ Debug("sets-card-graph") << "[sets-card-graph] Bk:" << std::endl;
+ for(typeof(edgesBk.begin()) it = edgesBk.begin();
+ it != edgesBk.end(); ++it) {
+ Debug("sets-card-graph") << "[sets-card-graph] " << (it->first) << std::endl;
+ for(typeof( (it->second).begin()) jt = (it->second).begin();
+ jt != (it->second).end(); ++jt) {
+ Debug("sets-card-graph") << "[sets-card-graph] " << (*jt) << std::endl;
+ }
+ }
+ }
+
+
+
+ leaves.clear();
+
+ for(typeof(d_processedCardTerms.begin()) it = d_processedCardTerms.begin();
+ it != d_processedCardTerms.end(); ++it) {
+ Node n = (*it)[0];
+ if( edgesFd.find(n) == edgesFd.end() ) {
+ leaves.insert(n);
+ Debug("sets-card-graph") << "[sets-card-graph] Leaf: " << n << std::endl;
+ }
+ // if( edgesBk.find(n) != edgesBk.end() ) {
+ // Assert(n.getKind() == kind::INTERSECTION ||
+ // n.getKind() == kind::SETMINUS);
+ // }
+ }
+
+}
+
+const std::set<TNode> getReachable(map<TNode, set<TNode> >& edges, TNode node) {
+ Debug("sets-getreachable-debug") << "[sets-getreachable-debug] " << node << ":" << std::endl;
+ queue<TNode> Q;
+ std::set<TNode> ret;
+ ret.insert(node);
+ if(edges.find(node) != edges.end()) {
+ Debug("sets-getreachable-debug") << "[sets-getreachable-debug] " << node << ":" << std::endl;
+ Q.push(node);
+ }
+ while(!Q.empty()) {
+ TNode n = Q.front();
+ Q.pop();
+ for(set<TNode>::iterator it = edges[n].begin();
+ it != edges[n].end(); ++it) {
+ if(ret.find(*it) == ret.end()) {
+ if(edges.find(*it) != edges.end()) {
+ Debug("sets-getreachable-debug") << "[sets-getreachable-debug] " << *it << ":" << std::endl;
+ Q.push(*it);
+ }
+ ret.insert(*it);
+ }
+ }
+ }
+ return ret;
+}
+
+const std::set<TNode> getLeaves(map<TNode, set<TNode> >& edges, TNode node) {
+ Debug("sets-getreachable-debug") << "[sets-getreachable-debug] " << node << ":" << std::endl;
+ queue<TNode> Q;
+ std::set<TNode> ret;
+ std::set<TNode> visited;
+ visited.insert(node);
+ if(edges.find(node) != edges.end()) {
+ Q.push(node);
+ } else {
+ Debug("sets-getreachable-debug") << "[sets-getreachable-debug] " << node << std::endl;
+ ret.insert(node);
+ }
+ while(!Q.empty()) {
+ TNode n = Q.front();
+ Q.pop();
+ for(set<TNode>::iterator it = edges[n].begin();
+ it != edges[n].end(); ++it) {
+ if(visited.find(*it) == visited.end()) {
+ if(edges.find(*it) != edges.end()) {
+ Q.push(*it);
+ } else {
+ Debug("sets-getreachable-debug") << "[sets-getreachable-debug] " << *it << std::endl;
+ ret.insert(*it);
+ }
+ visited.insert(*it);
+ }
+ }
+ }
+ return ret;
+}
+
+/************ New cardinality implementation **************/
+
+
+/***
+ * Data structures:
+ * d_V : vertices in the graph (context dependent data structure)
+ * d_E : edges between vertices in the graph
+ *
+ * Methods:
+ *
+ * merge(vector<int> a, vector<int> b)
+ * get non empty leaves
+ * of a & b, for each internal node, there will be two parent nodes
+ *
+ * Introduce
+ * <If a node already exists, merge with it>
+ */
+
+void TheorySetsPrivate::add_edges(TNode source, TNode dest) {
+ vector<TNode> V;
+ V.push_back(dest);
+ add_edges(source, V);
+}
+
+void TheorySetsPrivate::add_edges(TNode source, TNode dest1, TNode dest2) {
+ vector<TNode> V;
+ V.push_back(dest1);
+ V.push_back(dest2);
+ add_edges(source, V);
+}
+
+void TheorySetsPrivate::add_edges(TNode source, TNode dest1, TNode dest2, TNode dest3) {
+ vector<TNode> V;
+ V.push_back(dest1);
+ V.push_back(dest2);
+ V.push_back(dest3);
+ add_edges(source, V);
+}
+
+void TheorySetsPrivate::add_edges(TNode source, const std::vector<TNode>& dests) {
+
+ if(Debug.isOn("sets-graph-details")) {
+ Debug("sets-graph-details") << "[sets-graph-details] add_edges " << source
+ << " [";
+ BOOST_FOREACH(TNode v, dests) {
+ Debug("sets-graph-details") << v << ", ";
+ Assert(d_V.find(v) != d_V.end());
+ }
+ Debug("sets-graph-details") << "]" << std::endl;
+ }
+
+ Assert(d_E.find(source) == d_E.end());
+ if(dests.size() == 1 && dests[0] == source) {
+ return;
+ }
+ d_E.insert(source, dests);
+}
+
+
+void TheorySetsPrivate::add_node(TNode vertex) {
+ NodeManager* nm = NodeManager::currentNM();
+ Debug("sets-graph-details") << "[sets-graph-details] add_node " << vertex << std::endl;
+ if(d_V.find(vertex) == d_V.end()) {
+ d_V.insert(vertex);
+ Kind k = vertex.getKind();
+ if(k == kind::SINGLETON) {
+ // newLemmaGenerated = true;
+ lemma(nm->mkNode(kind::EQUAL,
+ nm->mkNode(kind::CARD, vertex),
+ nm->mkConst(Rational(1))),
+ SETS_LEMMA_OTHER);
+ } else if(k != kind::EMPTYSET) {
+ // newLemmaGenerated = true;
+ lemma(nm->mkNode(kind::GEQ,
+ nm->mkNode(kind::CARD, vertex),
+ nm->mkConst(Rational(0))),
+ SETS_LEMMA_OTHER);
+ }
+ d_statistics.d_numVerticesMax.maxAssign(d_V.size());
+ }
+ d_equalityEngine.addTerm(vertex);
+ d_termInfoManager->addTerm(vertex);
+}
+
+std::set<TNode> TheorySetsPrivate::non_empty(std::set<TNode> vertices)
+{
+ std::set<TNode> ret;
+ NodeManager* nm = NodeManager::currentNM();
+ BOOST_FOREACH(TNode vertex, vertices) {
+ Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(vertex.getType())));
+ if(!d_equalityEngine.areEqual(vertex, emptySet)) {
+ ret.insert(vertex);
+ }
+ }
+ return ret;
+}
+
+std::set<TNode> TheorySetsPrivate::get_leaves(Node vertex) {
+ Debug("sets-graph-details") << "[sets-graph-details] get_leaves " << vertex << std::endl;
+ std::set<TNode> a;
+ Assert(d_V.find(vertex) != d_V.end());
+ if(d_E.find(vertex) != d_E.end()) {
+ Assert(d_E[vertex].get().size() > 0);
+ BOOST_FOREACH(TNode v , d_E[vertex].get()) {
+ std::set<TNode> s = get_leaves(v);
+ a.insert(s.begin(), s.end());
+ }
+ } else {
+ a.insert(vertex);
+ }
+ // a = non_empty(a);
+ return a;
+}
+
+std::set<TNode> TheorySetsPrivate::get_leaves(Node vertex1, Node vertex2) {
+ std::set<TNode> s = get_leaves(vertex1);
+ std::set<TNode> t = get_leaves(vertex2);
+ t.insert(s.begin(), s.end());
+ return t;
+}
+
+std::set<TNode> TheorySetsPrivate::get_leaves(Node vertex1, Node vertex2, Node vertex3) {
+ std::set<TNode> s = get_leaves(vertex1);
+ std::set<TNode> t = get_leaves(vertex2);
+ std::set<TNode> u = get_leaves(vertex3);
+ t.insert(s.begin(), s.end());
+ t.insert(u.begin(), u.end());
+ return t;
+}
+
+Node TheorySetsPrivate::eqemptySoFar() {
+ std::vector<Node> V;
+
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it) {
+ Node rep = d_equalityEngine.getRepresentative(*it);
+ if(rep.getKind() == kind::EMPTYSET) {
+ V.push_back(EQUAL(rep, (*it)));
+ }
+ }
+
+ if(V.size() == 0) {
+ return d_trueNode;
+ } else if(V.size() == 1) {
+ return V[0];
+ } else {
+ NodeManager* nm = NodeManager::currentNM();
+ return nm->mkNode(kind::AND, V);
+ }
+}
+
+
+void TheorySetsPrivate::merge_nodes(std::set<TNode> leaves1, std::set<TNode> leaves2, Node reason) {
+ CodeTimer codeTimer(d_statistics.d_mergeTime);
+
+ NodeManager* nm = NodeManager::currentNM();
+
+ // do non-empty reasoning stuff
+ std::vector<TNode> leaves1_nonempty, leaves2_nonempty;
+ BOOST_FOREACH(TNode l, leaves1) {
+ Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(l.getType())));
+ if(d_equalityEngine.getRepresentative(l).getKind() != kind::EMPTYSET) {
+ leaves1_nonempty.push_back(l);
+ } else {
+ // reason = nm->mkNode(kind::AND, reason, EQUAL(l, emptySet));
+ }
+ }
+ BOOST_FOREACH(TNode l, leaves2) {
+ Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType(l.getType())));
+ if(d_equalityEngine.getRepresentative(l).getKind() != kind::EMPTYSET) {
+ leaves2_nonempty.push_back(l);
+ } else {
+ // reason = nm->mkNode(kind::AND, reason, EQUAL(l, emptySet));
+ }
+ }
+
+ // last minute stuff
+ reason = nm->mkNode(kind::AND, reason, eqemptySoFar());
+
+ Trace("sets-graph-merge") << "[sets-graph-merge] merge_nodes(..,.., " << reason << ")"
+ << std::endl;
+ print_graph();
+ Trace("sets-graph") << std::endl;
+
+ std::set<TNode> leaves3, leaves4;
+ std::set_difference(leaves1_nonempty.begin(), leaves1_nonempty.end(),
+ leaves2_nonempty.begin(), leaves2_nonempty.end(),
+ std::inserter(leaves3, leaves3.begin()));
+ std::set_difference(leaves2_nonempty.begin(), leaves2_nonempty.end(),
+ leaves1_nonempty.begin(), leaves1_nonempty.end(),
+ std::inserter(leaves4, leaves4.begin()));
+
+ if(leaves3.size() == 0) {
+ Trace("sets-graph-merge") << "[sets-graph-merge] Merge Equality 1" << std::endl;
+ // make everything in leaves4 empty
+ BOOST_FOREACH(TNode v , leaves4) {
+ Node zero = nm->mkConst(Rational(0));
+ if(!d_equalityEngine.hasTerm(zero)) {
+ d_equalityEngine.addTerm(zero);
+ d_termInfoManager->addTerm(zero);
+ }
+ learnLiteral( /* atom = */ EQUAL(nm->mkNode(kind::CARD, v), zero),
+ /* polarity = */ true,
+ /* reason = */ reason);
+ }
+ ++d_statistics.d_numMergeEq1or2;
+ } else if(leaves4.size() == 0) {
+ Trace("sets-graph-merge") << "[sets-graph-merge] Merge Equality 2" << std::endl;
+ // make everything in leaves3 empty
+ BOOST_FOREACH(TNode v , leaves3) {
+ Node zero = nm->mkConst(Rational(0));
+ if(!d_equalityEngine.hasTerm(zero)) {
+ d_equalityEngine.addTerm(zero);
+ d_termInfoManager->addTerm(zero);
+ }
+ learnLiteral( /* atom = */ EQUAL(nm->mkNode(kind::CARD, v), zero),
+ /* polarity = */ true,
+ /* reason = */ reason);
+ }
+ ++d_statistics.d_numMergeEq1or2;
+ } else {
+ Trace("sets-graph-merge") << "[sets-graph-merge] Merge Equality 3" << std::endl;
+ Trace("sets-graph-merge") << "[sets-graph-merge] #left= " << leaves1.size()
+ << " #right= " << leaves2.size()
+ << " #left non-empty= " << leaves1_nonempty.size()
+ << " #right non-empty= " << leaves2_nonempty.size()
+ << " #left-right= " << leaves3.size()
+ << " #right-left= " << leaves4.size() << std::endl;
+
+ std::map<TNode, vector<TNode> > children;
+
+ // Merge Equality 3
+ BOOST_FOREACH(TNode l1 , leaves3) {
+ BOOST_FOREACH(TNode l2 , leaves4) {
+ Node l1_inter_l2 = nm->mkNode(kind::INTERSECTION, min(l1, l2), max(l1, l2));
+ l1_inter_l2 = Rewriter::rewrite(l1_inter_l2);
+ add_node(l1_inter_l2);
+ children[l1].push_back(l1_inter_l2);
+ children[l2].push_back(l1_inter_l2);
+ // if(d_V.find(l1_inter_l2) != d_V.end()) {
+ // // This case needs to be handled, currently not
+ // Warning() << "This might create a loop. We need to handle this case. Probably merge the two nodes?" << std::endl;
+ // Unhandled();
+ // }
+ }
+ ++d_statistics.d_numMergeEq3;
+ }
+
+ for(std::map<TNode, vector<TNode> >::iterator it = children.begin();
+ it != children.end(); ++it) {
+ add_edges(it->first, it->second);
+ Node rhs;
+ if(it->second.size() == 1) {
+ rhs = nm->mkNode(kind::CARD, it->second[0]);
+ } else {
+ NodeBuilder<> nb(kind::PLUS);
+ BOOST_FOREACH(TNode n , it->second) {
+ Node card_n = nm->mkNode(kind::CARD, n);
+ nb << card_n;
+ }
+ rhs = Node(nb);
+ }
+ Node lem;
+ lem = nm->mkNode(kind::EQUAL,
+ nm->mkNode(kind::CARD, it->first),
+ rhs);
+ lem = nm->mkNode(kind::IMPLIES, reason, lem);
+ lem = Rewriter::rewrite(lem);
+ d_external.d_out->lemma(lem);
+ }
+ }
+
+ Trace("sets-graph") << std::endl;
+ print_graph();
+ Trace("sets-graph") << std::endl;
+
+}
+
+void TheorySetsPrivate::print_graph() {
+ std::string tag = "sets-graph";
+ if(Trace.isOn("sets-graph")) {
+ Trace(tag) << "[sets-graph] Graph : " << std::endl;
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it) {
+ TNode v = *it;
+ // BOOST_FOREACH(TNode v, d_V) {
+ Trace(tag) << "[" << tag << "] " << v << " : ";
+ // BOOST_FOREACH(TNode w, d_E[v].get()) {
+ if(d_E.find(v) != d_E.end()) {
+ BOOST_FOREACH(TNode w, d_E[v].get()) {
+ Trace(tag) << w << ", ";
+ }
+ } else {
+ Trace(tag) << " leaf. " ;
+ }
+ Trace(tag) << std::endl;
+ }
+ }
+
+ if(Trace.isOn("sets-graph-dot")) {
+ std::ostringstream oss;
+ oss << "digraph G { ";
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it) {
+ TNode v = *it;
+ if(d_E.find(v) != d_E.end()) {
+ BOOST_FOREACH(TNode w, d_E[v].get()) {
+ //oss << v.getId() << " -> " << w.getId() << "; ";
+ oss << "\"" << v << "\" -> \"" << w << "\"; ";
+ }
+ } else {
+ oss << "\"" << v << "\";";
+ }
+ }
+ oss << "}";
+ Trace("sets-graph-dot") << "[sets-graph-dot] " << oss.str() << std::endl;
+ }
+}
+
+Node TheorySetsPrivate::eqSoFar() {
+ std::vector<Node> V(d_allSetEqualitiesSoFar.begin(), d_allSetEqualitiesSoFar.end());
+ if(V.size() == 0) {
+ return d_trueNode;
+ } else if(V.size() == 1) {
+ return V[0];
+ } else {
+ NodeManager* nm = NodeManager::currentNM();
+ return nm->mkNode(kind::AND, V);
+ }
+}
+
+
+void TheorySetsPrivate::guessLeavesEmptyLemmas() {
+
+ // Guess leaf nodes being empty or non-empty
+ NodeManager* nm = NodeManager::currentNM();
+ leaves.clear();
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it) {
+ TNode v = *it;
+ if(d_E.find(v) == d_E.end()) {
+ leaves.insert(v);
+ }
+ }
+ d_statistics.d_numLeaves.setData(leaves.size());
+ d_statistics.d_numLeavesMax.maxAssign(leaves.size());
+
+ int
+ numLeaves = leaves.size(),
+ numLemmasGenerated = 0,
+ numLeavesIsEmpty = 0,
+ numLeavesIsNonEmpty = 0,
+ numLeavesCurrentlyNonEmpty = 0,
+ numLemmaAlreadyExisted = 0;
+
+ for(typeof(leaves.begin()) it = leaves.begin(); it != leaves.end(); ++it) {
+ bool generateLemma = true;
+ Node emptySet = nm->mkConst<EmptySet>(EmptySet(nm->toType((*it).getType())));
+
+ if(d_equalityEngine.hasTerm(*it)) {
+ Node n = d_equalityEngine.getRepresentative(*it);
+ if(n.getKind() == kind::EMPTYSET) {
+ ++numLeavesIsEmpty;
+ continue;
+ }
+ if(d_termInfoManager->getMembers(n)->size() > 0) {
+ ++numLeavesCurrentlyNonEmpty;
+ continue;
+ }
+ if(!d_equalityEngine.hasTerm(emptySet)) {
+ d_equalityEngine.addTerm(emptySet);
+ }
+ if(d_equalityEngine.areDisequal(n, emptySet, false)) {
+ ++numLeavesIsNonEmpty;
+ generateLemma = false;
+ }
+ }
+
+ if(generateLemma) {
+ Node n = nm->mkNode(kind::EQUAL, (*it), emptySet);
+ Node lem = nm->mkNode(kind::OR, n, nm->mkNode(kind::NOT, n));
+ bool lemmaGenerated =
+ lemma(lem, SETS_LEMMA_GRAPH);
+ if(lemmaGenerated) {
+ ++numLemmasGenerated;
+ } else {
+ ++numLemmaAlreadyExisted;
+ }
+ n = d_external.d_valuation.ensureLiteral(n);
+ d_external.d_out->requirePhase(n, true);
+ }
+
+ }
+ Trace("sets-guess-empty")
+ << "[sets-guess-empty] numLeaves = " << numLeaves << std::endl
+ << " numLemmasGenerated = " << numLemmasGenerated << std::endl
+ << " numLeavesIsEmpty = " << numLeavesIsEmpty << std::endl
+ << " numLeavesIsNonEmpty = " << numLeavesIsNonEmpty << std::endl
+ << " numLeavesCurrentlyNonEmpty = " << numLeavesCurrentlyNonEmpty << std::endl
+ << " numLemmaAlreadyExisted = " << numLemmaAlreadyExisted << std::endl;
+
+}
+
+void TheorySetsPrivate::processCard2(Theory::Effort level) {
+ CodeTimer codeTimer(d_statistics.d_processCard2Time);
+
+ if(level != Theory::EFFORT_FULL) return;
+
+ d_statistics.d_numVertices.setData(d_V.size());
+ d_statistics.d_numVerticesMax.maxAssign(d_V.size());
+
+ Trace("sets-card") << "[sets-card] processCard( " << level << ")" << std::endl;
+ Trace("sets-card") << "[sets-card] # vertices = " << d_V.size() << std::endl;
+
+ NodeManager* nm = NodeManager::currentNM();
+
+ // Introduce
+ for(typeof(d_cardTerms.begin()) it = d_cardTerms.begin();
+ it != d_cardTerms.end(); ++it) {
+
+ for(eq::EqClassIterator j(d_equalityEngine.getRepresentative((*it)[0]), &d_equalityEngine);
+ !j.isFinished(); ++j) {
+
+ Node n = nm->mkNode(kind::CARD, (*j));
+
+ if(d_processedCardTerms.find(n) != d_processedCardTerms.end()) {
+ continue;
+ }
+
+ if(d_relTerms.find(n[0]) == d_relTerms.end()) {
+ // not relevant, skip
+ continue;
+ }
+
+ Trace("sets-graph") << std::endl;
+ print_graph();
+ Trace("sets-graph") << std::endl;
+
+ add_node(n[0]);
+
+ Trace("sets-card") << "[sets-card] Processing " << n << " in eq cl of " << (*it) << std::endl;
+
+ d_processedCardTerms.insert(n);
+
+ Kind k = n[0].getKind();
+
+ if(k == kind::SINGLETON) {
+ Trace("sets-card") << "[sets-card] Introduce Singleton " << n[0] << std::endl;
+ continue;
+ }
+
+ // rest of the processing is for compound terms
+ if(k != kind::UNION && k != kind::INTERSECTION && k != kind::SETMINUS) {
+ continue;
+ }
+
+ Trace("sets-card") << "[sets-card] Introduce Term " << n[0] << std::endl;
+
+ Node s = min(n[0][0], n[0][1]);
+ Node t = max(n[0][0], n[0][1]);
+ bool isUnion = (k == kind::UNION);
+ Assert(Rewriter::rewrite(s) == s);
+ Assert(Rewriter::rewrite(t) == t);
+
+ Node sNt = nm->mkNode(kind::INTERSECTION, s, t);
+ sNt = Rewriter::rewrite(sNt);
+ Node sMt = nm->mkNode(kind::SETMINUS, s, t);
+ sMt = Rewriter::rewrite(sMt);
+ Node tMs = nm->mkNode(kind::SETMINUS, t, s);
+ tMs = Rewriter::rewrite(tMs);
+
+ Node card_s = nm->mkNode(kind::CARD, s);
+ Node card_t = nm->mkNode(kind::CARD, t);
+ Node card_sNt = nm->mkNode(kind::CARD, sNt);
+ Node card_sMt = nm->mkNode(kind::CARD, sMt);
+ Node card_tMs = nm->mkNode(kind::CARD, tMs);
+
+ Node lem;
+
+ add_node(sMt);
+ add_node(sNt);
+ add_node(tMs);
+
+
+ // for union
+ if(isUnion) {
+ if(d_E.find(n[0]) != d_E.end()) {
+ // do a merge of current leaves of d_E with
+ // sNT sMT tMs
+ Trace("sets-card") << "[sets-card] Already found in the graph, merging " << n[0] << std::endl;
+ merge_nodes(get_leaves(n[0]), get_leaves(sMt, sNt, tMs), eqSoFar());
+ } else {
+ add_node(n[0]);
+
+ lem = nm->mkNode(kind::EQUAL,
+ n, // card(s union t)
+ nm->mkNode(kind::PLUS, card_sNt, card_sMt, card_tMs));
+ lemma(lem, SETS_LEMMA_GRAPH);
+
+ Assert(d_E.find(n[0]) == d_E.end());
+ add_edges(n[0], sMt, sNt, tMs);
+ }
+ }
+
+ // for s
+ if(d_E.find(s) == d_E.end()) {
+ add_node(s);
+ add_edges(s, sMt, sNt);
+
+ lem = nm->mkNode(kind::EQUAL,
+ card_s,
+ nm->mkNode(kind::PLUS, card_sNt, card_sMt));
+ lemma(lem, SETS_LEMMA_GRAPH);
+ } else {
+ if(find(d_E[s].get().begin(), d_E[s].get().end(), sMt) != d_E[s].get().end()) {
+ Assert( find(d_E[s].get().begin(), d_E[s].get().end(), sMt) != d_E[s].get().end() );
+ Assert( find(d_E[s].get().begin(), d_E[s].get().end(), sNt) != d_E[s].get().end() );
+ Assert( find(d_E[t].get().begin(), d_E[t].get().end(), tMs) != d_E[t].get().end() );
+ Assert( find(d_E[t].get().begin(), d_E[t].get().end(), sNt) != d_E[t].get().end() );
+ continue;
+ }
+
+ Trace("sets-card") << "[sets-card] Already found in the graph, merging " << s << std::endl;
+ merge_nodes(get_leaves(s), get_leaves(sMt, sNt), eqSoFar());
+ }
+
+ // for t
+ if(d_E.find(t) == d_E.end()) {
+ Assert(d_E.find(t) == d_E.end());
+ add_node(t);
+ add_edges(t, sNt, tMs);
+
+ lem = nm->mkNode(kind::EQUAL,
+ card_t,
+ nm->mkNode(kind::PLUS, card_sNt, card_tMs));
+ lemma(lem, SETS_LEMMA_GRAPH);
+ } else {
+ // Assert( find(d_E[s].get().begin(), d_E[s].get().end(), sMt) == d_E[s].get().end() );
+ // Assert( find(d_E[s].get().begin(), d_E[s].get().end(), sNt) == d_E[s].get().end() );
+ // Assert( find(d_E[t].get().begin(), d_E[t].get().end(), tMs) == d_E[t].get().end() );
+ // Assert( find(d_E[t].get().begin(), d_E[t].get().end(), sNt) == d_E[t].get().end() );
+
+ Trace("sets-card") << "[sets-card] Already found in the graph, merging " << t << std::endl;
+ merge_nodes(get_leaves(t), get_leaves(sNt, tMs), eqSoFar());
+ }
+
+ if(options::setsSlowLemmas()) {
+ if(d_newLemmaGenerated) {
+ break;
+ } else if(options::setsGuessEmpty() == 0) {
+ guessLeavesEmptyLemmas();
+ if(d_newLemmaGenerated) {
+ return;
+ }
+ }
+ }
+
+ }//equivalence class loop
+
+ if(options::setsSlowLemmas() && d_newLemmaGenerated) {
+ break;
+ }
+
+ }//d_cardTerms loop
+
+ print_graph();
+
+ if(d_newLemmaGenerated) {
+ Trace("sets-card") << "[sets-card] New introduce done. Returning." << std::endl;
+ return;
+ }
+
+ if(options::setsGuessEmpty() == 1) {
+ guessLeavesEmptyLemmas();
+ if(d_newLemmaGenerated) {
+ return;
+ }
+ }
+
+ // Merge equalities from input assertions
+
+ while(!d_graphMergesPending.empty()) {
+ std::pair<TNode,TNode> np = d_graphMergesPending.front();
+ d_graphMergesPending.pop();
+
+ Debug("sets-card") << "[sets-card] Equality " << np.first << " " << np.second << std::endl;
+ if(np.first.getKind() == kind::EMPTYSET || np.second.getKind() == kind::EMPTYSET) {
+ Debug("sets-card") << "[sets-card] skipping merge as one side is empty set" << std::endl;
+ continue;
+ }
+
+ if(d_V.find(np.first) == d_V.end() || d_V.find(np.second) == d_V.end()) {
+ Assert((d_V.find(np.first) == d_V.end()));
+ Assert((d_V.find(np.second) == d_V.end()));
+ continue;
+ }
+ d_allSetEqualitiesSoFar.push_back(EQUAL(np.first, np.second));
+ // merge_nodes(get_leaves(np.first), get_leaves(np.second), EQUAL(np.first, np.second));
+ merge_nodes(get_leaves(np.first), get_leaves(np.second), eqSoFar());
+ }
+
+ if(d_newLemmaGenerated) {
+ Trace("sets-card") << "[sets-card] New merge done. Returning." << std::endl;
+ return;
+ }
+
+ leaves.clear();
+ for(typeof(d_V.begin()) it = d_V.begin(); it != d_V.end(); ++it) {
+ TNode v = *it;
+ if(d_E.find(v) == d_E.end()) {
+ leaves.insert(v);
+ }
+ }
+ Trace("sets-card") << "[sets-card] # leaves = " << leaves.size() << std::endl;
+ d_statistics.d_numLeaves.setData(leaves.size());
+ d_statistics.d_numLeavesMax.maxAssign(leaves.size());
+
+ Assert(!d_newLemmaGenerated);
+
+
+ if(options::setsGuessEmpty() == 2) {
+ guessLeavesEmptyLemmas();
+ if(d_newLemmaGenerated) {
+ return;
+ }
+ }
+
+ // Elements being either equal or disequal [Members Arrangement rule]
+ Trace("sets-card") << "[sets-card] Processing elements equality/disequal to each other" << std::endl;
+ for(typeof(leaves.begin()) it = leaves.begin();
+ it != leaves.end(); ++it) {
+ if(!d_equalityEngine.hasTerm(*it)) continue;
+ Node n = d_equalityEngine.getRepresentative(*it);
+ Assert(n.getKind() == kind::EMPTYSET || leaves.find(n) != leaves.end());
+ if(n != *it) continue;
+ const CDTNodeList* l = d_termInfoManager->getMembers(*it);
+ std::set<TNode> elems;
+ for(typeof(l->begin()) l_it = l->begin(); l_it != l->end(); ++l_it) {
+ elems.insert(d_equalityEngine.getRepresentative(*l_it));
+ }
+ for(typeof(elems.begin()) e1_it = elems.begin(); e1_it != elems.end(); ++e1_it) {
+ for(typeof(elems.begin()) e2_it = elems.begin(); e2_it != elems.end(); ++e2_it) {
+ if(*e1_it == *e2_it) continue;
+ if(!d_equalityEngine.areDisequal(*e1_it, *e2_it, false)) {
+ Node lem = nm->mkNode(kind::EQUAL, *e1_it, *e2_it);
+ lem = nm->mkNode(kind::OR, lem, nm->mkNode(kind::NOT, lem));
+ lemma(lem, SETS_LEMMA_GRAPH);
+ }
+ }
+ }
+ }
+
+ if(d_newLemmaGenerated) {
+ Trace("sets-card") << "[sets-card] Members arrangments lemmas. Returning." << std::endl;
+ return;
+ }
+
+ // Assert Lower bound
+ Trace("sets-card") << "[sets-card] Processing assert lower bound" << std::endl;
+ for(typeof(leaves.begin()) it = leaves.begin();
+ it != leaves.end(); ++it) {
+ Trace("sets-cardlower") << "[sets-cardlower] Card Lower: " << *it << std::endl;
+ Assert(d_equalityEngine.hasTerm(*it));
+ Node n = d_equalityEngine.getRepresentative(*it);
+ // Node n = (*it);
+ // if(!d_equalityEngine.hasTerm(n)) {
+ // Trace("sets-cardlower") << "[sets-cardlower] not in EE" << std::endl;
+ // continue;
+ // }
+ // Assert(n.getKind() == kind::EMPTYSET || leaves.find(n) != leaves.end()); // ????
+ // if(n != *it) continue;
+ const CDTNodeList* l = d_termInfoManager->getMembers(n);
+ std::set<TNode> elems;
+ for(typeof(l->begin()) l_it = l->begin(); l_it != l->end(); ++l_it) {
+ elems.insert(d_equalityEngine.getRepresentative(*l_it));
+ }
+ if(elems.size() == 0) continue;
+ NodeBuilder<> nb(kind::OR);
+ nb << ( nm->mkNode(kind::LEQ, nm->mkConst(Rational(elems.size())), nm->mkNode(kind::CARD, *it)) );
+ if(elems.size() > 1) {
+ for(typeof(elems.begin()) e1_it = elems.begin(); e1_it != elems.end(); ++e1_it) {
+ for(typeof(elems.begin()) e2_it = elems.begin(); e2_it != elems.end(); ++e2_it) {
+ if(*e1_it == *e2_it) continue;
+ nb << (nm->mkNode(kind::EQUAL, *e1_it, *e2_it));
+ }
+ }
+ }
+ for(typeof(elems.begin()) e_it = elems.begin(); e_it != elems.end(); ++e_it) {
+ nb << nm->mkNode(kind::NOT, nm->mkNode(kind::MEMBER, *e_it, *it));
+ }
+ Node lem = Node(nb);
+ // if(d_cardLowerLemmaCache.find(lem) == d_cardLowerLemmaCache.end()) {
+ Trace("sets-card") << "[sets-card] Card Lower: " << lem << std::endl;
+ lemma(lem, SETS_LEMMA_GRAPH);
+ // d_cardLowerLemmaCache.insert(lem);
+ // }
+ }
+}
+
+
+
}/* CVC4::theory::sets namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/sets/theory_sets_private.h b/src/theory/sets/theory_sets_private.h
index a01e9a168..217432670 100644
--- a/src/theory/sets/theory_sets_private.h
+++ b/src/theory/sets/theory_sets_private.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets_private.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory implementation.
**
@@ -68,6 +68,8 @@ public:
void preRegisterTerm(TNode node);
+ void presolve();
+
void propagate(Theory::Effort);
private:
@@ -76,8 +78,16 @@ private:
class Statistics {
public:
TimerStat d_getModelValueTime;
+ TimerStat d_mergeTime;
+ TimerStat d_processCard2Time;
IntStat d_memberLemmas;
IntStat d_disequalityLemmas;
+ IntStat d_numVertices;
+ IntStat d_numVerticesMax;
+ IntStat d_numMergeEq1or2;
+ IntStat d_numMergeEq3;
+ IntStat d_numLeaves;
+ IntStat d_numLeavesMax;
Statistics();
~Statistics();
@@ -115,6 +125,20 @@ private:
/** generate and send out conflict node */
void conflict(TNode, TNode);
+ /** send out a lemma */
+ enum SetsLemmaTag {
+ SETS_LEMMA_DISEQUAL,
+ SETS_LEMMA_MEMBER,
+ SETS_LEMMA_GRAPH,
+ SETS_LEMMA_OTHER
+ };
+
+ /**
+ * returns true if a lemmas was generated
+ * returns false otherwise (found in cache)
+ */
+ bool lemma(Node n, SetsLemmaTag t);
+
class TermInfoManager {
TheorySetsPrivate& d_theory;
context::Context* d_context;
@@ -143,6 +167,25 @@ private:
};
TermInfoManager* d_termInfoManager;
+ /******
+ * Card Vars :
+ *
+ * mapping from set terms to correpsonding cardinality variable
+ *
+ * in the ::check function, when we get one of those cardinality
+ * variables to be assigned to 0, we will assert in equality engine
+ * to be equal to empty set.
+ *
+ * if required, we will add more filters so it doesn't leak to
+ * outside world
+ */
+ Node getCardVar(TNode n);
+ Node newCardVar(TNode n);
+ bool isCardVar(TNode n);
+ typedef std::hash_map <Node, Node, NodeHashFunction> NodeNodeHashMap;
+ NodeNodeHashMap d_setTermToCardVar;
+ NodeNodeHashMap d_cardVarToSetTerm;
+
/** Assertions and helper functions */
bool present(TNode atom);
bool holds(TNode lit) {
@@ -205,6 +248,55 @@ private:
// relational solver
TheorySetsRels* d_rels;
+ /***** Cardinality handling *****/
+ bool d_cardEnabled;
+ void enableCard();
+ void cardCreateEmptysetSkolem(TypeNode t);
+
+ CDNodeSet d_cardTerms;
+ std::set<TypeNode> d_typesAdded;
+ CDNodeSet d_processedCardTerms;
+ std::map<std::pair<Node, Node>, bool> d_processedCardPairs;
+ CDNodeSet d_cardLowerLemmaCache;
+ void registerCard(TNode);
+ void processCard(Theory::Effort level);
+
+ /* Graph handling */
+ std::map<TNode, std::set<TNode> > edgesFd;
+ std::map<TNode, std::set<TNode> > edgesBk;
+ std::set< std::pair<TNode, TNode> > disjoint;
+ std::set<TNode> leaves;
+ void buildGraph();
+
+ /* For calculus as in paper */
+ void processCard2(Theory::Effort level);
+ CDNodeSet d_V;
+ context::CDHashMap <TNode, std::vector<TNode>, TNodeHashFunction > d_E;
+ void add_edges(TNode source, TNode dest);
+ void add_edges(TNode source, TNode dest1, TNode dest2);
+ void add_edges(TNode source, TNode dest1, TNode dest2, TNode dest3);
+ void add_edges(TNode source, const std::vector<TNode>& dests);
+ void add_node(TNode vertex);
+ void merge_nodes(std::set<TNode> a, std::set<TNode> b, Node reason);
+ std::set<TNode> get_leaves(Node vertex);
+ std::set<TNode> get_leaves(Node vertex1, Node vertex2);
+ std::set<TNode> get_leaves(Node vertex1, Node vertex2, Node vertex3);
+ std::set<TNode> non_empty(std::set<TNode> vertices);
+ void print_graph();
+ context::CDQueue < std::pair<TNode, TNode> > d_graphMergesPending;
+ context::CDList<Node> d_allSetEqualitiesSoFar;
+ Node eqSoFar();
+ Node eqemptySoFar();
+
+ std::set<TNode> getNonEmptyLeaves(TNode);
+ CDNodeSet d_lemmasGenerated;
+ bool d_newLemmaGenerated;
+
+ void guessLeavesEmptyLemmas();
+
+
+ /** relevant terms */
+ CDNodeSet d_relTerms;
};/* class TheorySetsPrivate */
diff --git a/src/theory/sets/theory_sets_rewriter.cpp b/src/theory/sets/theory_sets_rewriter.cpp
index 9156e3a75..5204dcaed 100644
--- a/src/theory/sets/theory_sets_rewriter.cpp
+++ b/src/theory/sets/theory_sets_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets_rewriter.cpp
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory rewriter.
**
@@ -18,6 +18,8 @@
#include "theory/sets/normal_form.h"
#include "theory/sets/theory_sets_rels.h"
#include "theory/sets/rels_utils.h"
+#include "expr/attribute.h"
+#include "options/sets_options.h"
namespace CVC4 {
namespace theory {
@@ -26,6 +28,101 @@ namespace sets {
typedef std::set<TNode> Elements;
typedef std::hash_map<TNode, Elements, TNodeHashFunction> SettermElementsMap;
+struct FlattenedNodeTag {};
+typedef expr::Attribute<FlattenedNodeTag, bool> flattened;
+
+
+/**
+ * flattenNode looks for children of same kind, and if found merges
+ * them into the parent.
+ *
+ * It simultaneously handles a couple of other optimizations:
+ * - trivialNode - if found during exploration, return that node itself
+ * (like in case of OR, if "true" is found, makes sense to replace
+ * whole formula with "true")
+ * - skipNode - as name suggests, skip them
+ * (like in case of OR, you may want to skip any "false" nodes found)
+ *
+ * Use a null node if you want to ignore any of the optimizations.
+ */
+RewriteResponse flattenNode(TNode n, TNode trivialNode, TNode skipNode)
+{
+ if(n.hasAttribute(flattened()) && n.getAttribute(flattened())) {
+ return RewriteResponse(REWRITE_DONE, n);
+ }
+
+ typedef std::hash_set<TNode, TNodeHashFunction> node_set;
+
+ node_set visited;
+ visited.insert(skipNode);
+
+ std::vector<TNode> toProcess;
+ toProcess.push_back(n);
+
+ Kind k = n.getKind();
+ typedef std::vector<TNode> ChildList;
+ ChildList childList; //TNode should be fine, since 'n' is still there
+
+ Debug("sets-rewrite-flatten") << "[sets-rewrite-flatten] " << n << std::endl;
+ for (unsigned i = 0; i < toProcess.size(); ++ i) {
+ TNode current = toProcess[i];
+ Debug("sets-rewrite-flatten") << "[sets-rewrite-flatten] > Processing " << current << std::endl;
+ for(unsigned j = 0, j_end = current.getNumChildren(); j < j_end; ++ j) {
+ TNode child = current[j];
+ if(visited.find(child) != visited.end()) {
+ continue;
+ } else if(child == trivialNode) {
+ return RewriteResponse(REWRITE_DONE, trivialNode);
+ } else {
+ visited.insert(child);
+ if(child.getKind() == k) {
+ toProcess.push_back(child);
+ } else {
+ childList.push_back(child);
+ }
+ }
+ }
+ }
+ if (childList.size() == 0) return RewriteResponse(REWRITE_DONE, skipNode);
+ if (childList.size() == 1) return RewriteResponse(REWRITE_AGAIN, childList[0]);
+
+ sort(childList.begin(), childList.end());
+
+ /* Make sure we are under number of children possible in a node */
+ NodeManager* nodeManager = NodeManager::currentNM();
+ static const unsigned MAX_CHILDREN = (1u << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN ) - 1;
+ AlwaysAssert(childList.size() < MAX_CHILDREN, "do not support formulas this big");
+
+ ChildList::iterator cur = childList.begin(), next, en = childList.end();
+ Node ret = (*cur);
+ ++cur;
+ while( cur != en ) {
+ ret = nodeManager->mkNode(k, ret, *cur);
+ ret.setAttribute(flattened(), true);
+ ++cur;
+ }
+ Trace("sets-postrewrite") << "flatten Sets::postRewrite returning " << ret << std::endl;
+ if(ret != n) {
+ return RewriteResponse(REWRITE_AGAIN, ret); // again for constants
+ } else {
+ return RewriteResponse(REWRITE_DONE, ret);
+ }
+ // if (childList.size() < MAX_CHILDREN) {
+ // Node retNode = nodeManager->mkNode(k, childList);
+ // return RewriteResponse(REWRITE_DONE, retNode);
+ // } else {
+ // Assert(childList.size() < size_t(MAX_CHILDREN) * size_t(MAX_CHILDREN) );
+ // NodeBuilder<> nb(k);
+ // ChildList::iterator cur = childList.begin(), next, en = childList.end();
+ // while( cur != en ) {
+ // next = min(cur + MAX_CHILDREN, en);
+ // nb << (nodeManager->mkNode(k, ChildList(cur, next) ));
+ // cur = next;
+ // }
+ // return RewriteResponse(REWRITE_DONE, nb.constructNode());
+ // }
+}
+
bool checkConstantMembership(TNode elementTerm, TNode setTerm)
{
if(setTerm.getKind() == kind::EMPTYSET) {
@@ -103,57 +200,92 @@ RewriteResponse TheorySetsRewriter::postRewrite(TNode node) {
}//kind::IFF
case kind::SETMINUS: {
- if(node[0] == node[1]) {
- Node newNode = nm->mkConst(EmptySet(nm->toType(node[0].getType())));
- Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
- return RewriteResponse(REWRITE_DONE, newNode);
- } else if(node[0].getKind() == kind::EMPTYSET ||
- node[1].getKind() == kind::EMPTYSET) {
- Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
- return RewriteResponse(REWRITE_DONE, node[0]);
- } else if(node[0].isConst() && node[1].isConst()) {
- std::set<Node> left = NormalForm::getElementsFromNormalConstant(node[0]);
- std::set<Node> right = NormalForm::getElementsFromNormalConstant(node[1]);
- std::set<Node> newSet;
- std::set_difference(left.begin(), left.end(), right.begin(), right.end(),
- std::inserter(newSet, newSet.begin()));
- Node newNode = NormalForm::elementsToSet(newSet, node.getType());
- Assert(newNode.isConst());
- Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
- return RewriteResponse(REWRITE_DONE, newNode);
+ if( options::setsAggRewrite() ){
+ Node newNode = rewriteSet( node );
+ if( newNode!=node ){
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
+ }else{
+ if(node[0] == node[1]) {
+ Node newNode = nm->mkConst(EmptySet(nm->toType(node[0].getType())));
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ } else if(node[0].getKind() == kind::EMPTYSET ||
+ node[1].getKind() == kind::EMPTYSET) {
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if(node[0].isConst() && node[1].isConst()) {
+ std::set<Node> left = NormalForm::getElementsFromNormalConstant(node[0]);
+ std::set<Node> right = NormalForm::getElementsFromNormalConstant(node[1]);
+ std::set<Node> newSet;
+ std::set_difference(left.begin(), left.end(), right.begin(), right.end(),
+ std::inserter(newSet, newSet.begin()));
+ Node newNode = NormalForm::elementsToSet(newSet, node.getType());
+ Assert(newNode.isConst());
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
}
break;
- }//kind::INTERSECION
+ }//kind::SETMINUS
case kind::INTERSECTION: {
- if(node[0] == node[1]) {
- Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
- return RewriteResponse(REWRITE_DONE, node[0]);
- } else if(node[0].getKind() == kind::EMPTYSET) {
- return RewriteResponse(REWRITE_DONE, node[0]);
- } else if(node[1].getKind() == kind::EMPTYSET) {
- return RewriteResponse(REWRITE_DONE, node[1]);
- } else if(node[0].isConst() && node[1].isConst()) {
- std::set<Node> left = NormalForm::getElementsFromNormalConstant(node[0]);
- std::set<Node> right = NormalForm::getElementsFromNormalConstant(node[1]);
- std::set<Node> newSet;
- std::set_intersection(left.begin(), left.end(), right.begin(), right.end(),
- std::inserter(newSet, newSet.begin()));
- Node newNode = NormalForm::elementsToSet(newSet, node.getType());
- Assert(newNode.isConst());
- Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
- return RewriteResponse(REWRITE_DONE, newNode);
- } else if (node[0] > node[1]) {
- Node newNode = nm->mkNode(node.getKind(), node[1], node[0]);
- Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
- return RewriteResponse(REWRITE_DONE, newNode);
+ if( options::setsAggRewrite() ){
+ Node newNode = rewriteSet( node );
+ if( newNode!=node ){
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
+ // }else{
+ // Node emptySet = nm->mkConst(EmptySet(nm->toType(node[0].getType())));
+ // if(node[0].isConst() && node[1].isConst()) {
+ // std::set<Node> left = NormalForm::getElementsFromNormalConstant(node[0]);
+ // std::set<Node> right = NormalForm::getElementsFromNormalConstant(node[1]);
+ // std::set<Node> newSet;
+ // std::set_intersection(left.begin(), left.end(), right.begin(), right.end(),
+ // std::inserter(newSet, newSet.begin()));
+ // Node newNode = NormalForm::elementsToSet(newSet, node.getType());
+ // Assert(newNode.isConst());
+ // Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ // return RewriteResponse(REWRITE_DONE, newNode);
+ // } else {
+ // return flattenNode(node, /* trivialNode = */ emptySet, /* skipNode = */ Node());
+ // }
+ // }
+ }else{
+ if(node[0] == node[1]) {
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if(node[0].getKind() == kind::EMPTYSET) {
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if(node[1].getKind() == kind::EMPTYSET) {
+ return RewriteResponse(REWRITE_DONE, node[1]);
+ } else if(node[0].isConst() && node[1].isConst()) {
+ std::set<Node> left = NormalForm::getElementsFromNormalConstant(node[0]);
+ std::set<Node> right = NormalForm::getElementsFromNormalConstant(node[1]);
+ std::set<Node> newSet;
+ std::set_intersection(left.begin(), left.end(), right.begin(), right.end(),
+ std::inserter(newSet, newSet.begin()));
+ Node newNode = NormalForm::elementsToSet(newSet, node.getType());
+ Assert(newNode.isConst());
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ } else if (node[0] > node[1]) {
+ Node newNode = nm->mkNode(node.getKind(), node[1], node[0]);
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
}
break;
}//kind::INTERSECION
case kind::UNION: {
// NOTE: case where it is CONST is taken care of at the top
- if(node[0] == node[1]) {
+ if( options::setsAggRewrite() ){
+ Node newNode = rewriteSet( node );
+ if( newNode!=node ){
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
+ }else if(node[0] == node[1]) {
Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
return RewriteResponse(REWRITE_DONE, node[0]);
} else if(node[0].getKind() == kind::EMPTYSET) {
@@ -170,7 +302,7 @@ RewriteResponse TheorySetsRewriter::postRewrite(TNode node) {
Assert(newNode.isConst());
Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
return RewriteResponse(REWRITE_DONE, newNode);
- } else if (node[0] > node[1]) {
+ }else if (node[0] > node[1]) {
Node newNode = nm->mkNode(node.getKind(), node[1], node[0]);
Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
return RewriteResponse(REWRITE_DONE, newNode);
@@ -178,6 +310,13 @@ RewriteResponse TheorySetsRewriter::postRewrite(TNode node) {
break;
}//kind::UNION
+ case kind::CARD: {
+ if(node[0].isConst()) {
+ std::set<Node> elements = NormalForm::getElementsFromNormalConstant(node[0]);
+ return RewriteResponse(REWRITE_DONE, nm->mkConst(Rational(elements.size())));
+ }
+ }
+
case kind::TRANSPOSE: {
if(node[0].getKind() == kind::TRANSPOSE) {
return RewriteResponse(REWRITE_AGAIN, node[0][0]);
@@ -365,6 +504,180 @@ RewriteResponse TheorySetsRewriter::preRewrite(TNode node) {
return RewriteResponse(REWRITE_DONE, node);
}
+Node TheorySetsRewriter::rewriteSet( Node s ) {
+ Trace("sets-rewrite-debug") << "Rewrite set : " << s << std::endl;
+ Node empSet = NodeManager::currentNM()->mkConst(EmptySet(NodeManager::currentNM()->toType(s.getType())));
+ bool success;
+ do{
+ success = false;
+ std::map< Node, bool > ca;
+ Node ss = rewriteSet( s, ca, empSet );
+ if( ss!=s ){
+ Assert( !ss.isNull() );
+ Trace("sets-rewrite") << "Rewrite set : " << s << std::endl;
+ Trace("sets-rewrite") << "........got : " << ss << std::endl;
+ success = true;
+ s = ss;
+ }
+ }while( success );
+ return s;
+}
+
+Node TheorySetsRewriter::rewriteSet( Node s, std::map< Node, bool >& ca, Node empSet ) {
+ if( s.getKind()!=kind::UNION && s.getKind()!=kind::INTERSECTION && s.getKind()!=kind::SETMINUS ){
+ std::map< Node, bool >::iterator it = ca.find( s );
+ if( it==ca.end() ){
+ return s;
+ }else if( it->second ){
+ return Node::null();
+ }else{
+ return empSet;
+ }
+ }else{
+ Trace("sets-rewrite-debug") << "Get components : " << s << std::endl;
+ std::map< Node, bool > c;
+ bool pol = s.getKind()!=kind::UNION;
+ if( pol ){
+ //copy current components
+ for( std::map< Node, bool >::iterator it = ca.begin(); it != ca.end(); ++it ){
+ c[it->first] = it->second;
+ }
+ }
+ if( collectSetComponents( s, c, pol ) ){
+ if( Trace.isOn("sets-rewrite-debug") ){
+ Trace("sets-rewrite-debug") << " got components : " << std::endl;
+ for( std::map< Node, bool >::iterator it = c.begin(); it != c.end(); ++it ){
+ Trace("sets-rewrite-debug") << " " << it->first << " -> " << it->second << std::endl;
+ }
+ }
+
+ //simplify components based on what is asserted in ca, recursively
+ std::map< Node, bool > nc;
+ if( pol ){
+ //copy map
+ for( std::map< Node, bool >::iterator it = c.begin(); it != c.end(); ++it ){
+ nc[it->first] = it->second;
+ }
+ //rewrite each new component based on current assertions
+ for( std::map< Node, bool >::iterator it = c.begin(); it != c.end(); ++it ){
+ if( ca.find( it->first )==ca.end() ){
+ nc.erase( it->first );
+ Node prev = it->first;
+ //only rewrite positive components here
+ Node ss = it->second ? rewriteSet( it->first, nc, empSet ) : it->first;
+ if( prev!=ss ){
+ Trace("sets-rewrite-debug") << " simplify component : " << prev << "..." << ss << std::endl;
+ }
+ if( ss==empSet ){
+ Trace("sets-rewrite-debug") << " return singularity " << ss << std::endl;
+ return ss;
+ }else if( !ss.isNull() ){
+ std::map< Node, bool >::iterator itc = nc.find( ss );
+ if( itc==nc.end() ){
+ nc[ss] = it->second;
+ }else if( it->second!=itc->second ){
+ Trace("sets-rewrite-debug") << "...conflict, return empty set." << std::endl;
+ return empSet;
+ }
+ }
+ }
+ }
+ }else{
+ for( std::map< Node, bool >::iterator it = c.begin(); it != c.end(); ++it ){
+ Node prev = it->first;
+ Node ss = rewriteSet( it->first, ca, empSet );
+ if( prev!=ss ){
+ Trace("sets-rewrite-debug") << " simplify component : " << prev << "..." << ss << std::endl;
+ }
+ if( ss.isNull() ){
+ Trace("sets-rewrite-debug") << " return singularity " << ss << std::endl;
+ return ss;
+ }else if( ss!=empSet ){
+ std::map< Node, bool >::iterator itc = nc.find( ss );
+ if( itc==nc.end() ){
+ nc[ss] = it->second;
+ }else if( it->second!=itc->second ){
+ Trace("sets-rewrite-debug") << "...conflict, return complete set." << std::endl;
+ return Node::null();
+ }
+ }
+ }
+ }
+
+
+ //construct sorted lists of positive, negative components
+ std::vector< Node > comp[2];
+ for( std::map< Node, bool >::iterator it = nc.begin(); it != nc.end(); ++it ){
+ if( !pol || ca.find( it->first )==ca.end() ){
+ comp[ ( it->second==pol ) ? 0 : 1 ].push_back( it->first );
+ }
+ }
+ //construct normalized set
+ Node curr;
+ for( unsigned i=0; i<2; i++ ){
+ if( comp[i].size()>1 ){
+ std::sort( comp[i].begin(), comp[i].end() );
+ }
+ if( i==0 ){
+ if( comp[i].empty() ){
+ Trace("sets-rewrite-debug") << "...return trivial set (no components)." << std::endl;
+ if( pol ){
+ return Node::null();
+ }else{
+ return empSet;
+ }
+ }else{
+ curr = comp[i][0];
+ for( unsigned j=1; j<comp[i].size(); j++ ){
+ curr = NodeManager::currentNM()->mkNode( pol ? kind::INTERSECTION : kind::UNION, curr, comp[i][j] );
+ }
+ }
+ }else if( i==1 ){
+ if( !comp[i].empty() ){
+ Assert( pol );
+ Node rem = comp[i][0];
+ for( unsigned j=1; j<comp[i].size(); j++ ){
+ rem = NodeManager::currentNM()->mkNode( kind::UNION, rem, comp[i][j] );
+ }
+ curr = NodeManager::currentNM()->mkNode( kind::SETMINUS, curr, rem );
+ }
+ }
+ }
+ Trace("sets-rewrite-debug") << "...return " << curr << std::endl;
+ return curr;
+ }else{
+ if( pol ){
+ Trace("sets-rewrite-debug") << "...return empty set." << std::endl;
+ return NodeManager::currentNM()->mkConst(EmptySet(NodeManager::currentNM()->toType(s.getType())));
+ }else{
+ Trace("sets-rewrite-debug") << "...return complete set." << std::endl;
+ return Node::null();
+ }
+ }
+ }
+}
+
+bool TheorySetsRewriter::collectSetComponents( Node n, std::map< Node, bool >& c, bool pol ) {
+ std::map< Node, bool >::iterator itc = c.find( n );
+ if( itc!=c.end() ){
+ if( itc->second!=pol ){
+ return false;
+ }
+ }else{
+ if( ( pol && ( n.getKind()==kind::INTERSECTION || n.getKind()==kind::SETMINUS ) ) || ( !pol && n.getKind()==kind::UNION ) ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ bool newPol = ( i==1 && n.getKind()==kind::SETMINUS ) ? !pol : pol;
+ if( !collectSetComponents( n[i], c, newPol ) ){
+ return false;
+ }
+ }
+ }else{
+ c[n] = pol;
+ }
+ }
+ return true;
+}
+
}/* CVC4::theory::sets namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/sets/theory_sets_rewriter.h b/src/theory/sets/theory_sets_rewriter.h
index 58ee8bfb0..97c89520a 100644
--- a/src/theory/sets/theory_sets_rewriter.h
+++ b/src/theory/sets/theory_sets_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets_rewriter.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory rewriter.
**
@@ -26,6 +26,10 @@ namespace theory {
namespace sets {
class TheorySetsRewriter {
+private:
+ static bool collectSetComponents( Node n, std::map< Node, bool >& c, bool pol );
+ static Node rewriteSet( Node s, std::map< Node, bool >& ca, Node empSet );
+ static Node rewriteSet( Node s );
public:
/**
diff --git a/src/theory/sets/theory_sets_type_enumerator.h b/src/theory/sets/theory_sets_type_enumerator.h
index bb0e1794c..40863b0f2 100644
--- a/src/theory/sets/theory_sets_type_enumerator.h
+++ b/src/theory/sets/theory_sets_type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets_type_enumerator.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Morgan Deters, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/sets/theory_sets_type_rules.h b/src/theory/sets/theory_sets_type_rules.h
index fdcb094fc..92d6c9b6d 100644
--- a/src/theory/sets/theory_sets_type_rules.h
+++ b/src/theory/sets/theory_sets_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_sets_type_rules.h
** \verbatim
- ** Original author: Kshitij Bansal
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Kshitij Bansal, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sets theory type rules.
**
@@ -136,6 +136,25 @@ struct EmptySetTypeRule {
}
};/* struct EmptySetTypeRule */
+struct CardTypeRule {
+ inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+ throw (TypeCheckingExceptionPrivate, AssertionException) {
+ Assert(n.getKind() == kind::CARD);
+ TypeNode setType = n[0].getType(check);
+ if( check ) {
+ if(!setType.isSet()) {
+ throw TypeCheckingExceptionPrivate(n, "cardinality operates on a set, non-set object found");
+ }
+ }
+ return nodeManager->integerType();
+ }
+
+ inline static bool computeIsConst(NodeManager* nodeManager, TNode n) {
+ Assert(n.getKind() == kind::CARD);
+ return false;
+ }
+};/* struct CardTypeRule */
+
struct InsertTypeRule {
inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
throw (TypeCheckingExceptionPrivate, AssertionException) {
@@ -256,7 +275,6 @@ struct RelTransClosureTypeRule {
}
};/* struct RelTransClosureTypeRule */
-
struct SetsProperties {
inline static Cardinality computeCardinality(TypeNode type) {
Assert(type.getKind() == kind::SET_TYPE);
diff --git a/src/theory/shared_terms_database.cpp b/src/theory/shared_terms_database.cpp
index 89cba3ae4..0dc6cc7a1 100644
--- a/src/theory/shared_terms_database.cpp
+++ b/src/theory/shared_terms_database.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file shared_terms_database.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
@@ -122,7 +122,7 @@ Theory::Set SharedTermsDatabase::getNotifiedTheories(TNode term) const {
bool SharedTermsDatabase::propagateSharedEquality(TheoryId theory, TNode a, TNode b, bool value)
{
- Debug("shared-terms-database") << "SharedTermsDatabase::newEquality(" << theory << a << "," << b << ", " << (value ? "true" : "false") << ")" << endl;
+ Debug("shared-terms-database") << "SharedTermsDatabase::newEquality(" << theory << "," << a << "," << b << ", " << (value ? "true" : "false") << ")" << endl;
if (d_inConflict) {
return false;
diff --git a/src/theory/shared_terms_database.h b/src/theory/shared_terms_database.h
index c15336e29..c108122ef 100644
--- a/src/theory/shared_terms_database.h
+++ b/src/theory/shared_terms_database.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file shared_terms_database.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/sort_inference.cpp b/src/theory/sort_inference.cpp
index 060584fcf..1f8ec7ee4 100644
--- a/src/theory/sort_inference.cpp
+++ b/src/theory/sort_inference.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file sort_inference.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Sort inference module
**
@@ -118,10 +118,11 @@ void SortInference::simplify( std::vector< Node >& assertions, bool doSortInfere
if( doSortInference ){
Trace("sort-inference-proc") << "Calculating sort inference..." << std::endl;
//process all assertions
+ std::map< Node, int > visited;
for( unsigned i=0; i<assertions.size(); i++ ){
Trace("sort-inference-debug") << "Process " << assertions[i] << std::endl;
std::map< Node, Node > var_bound;
- process( assertions[i], var_bound );
+ process( assertions[i], var_bound, visited );
}
Trace("sort-inference-proc") << "...done" << std::endl;
for( std::map< Node, int >::iterator it = d_op_return_types.begin(); it != d_op_return_types.end(); ++it ){
@@ -155,10 +156,11 @@ void SortInference::simplify( std::vector< Node >& assertions, bool doSortInfere
bool rewritten = false;
//determine monotonicity of sorts
Trace("sort-inference-proc") << "Calculating monotonicty for subsorts..." << std::endl;
+ std::map< Node, std::map< int, bool > > visited;
for( unsigned i=0; i<assertions.size(); i++ ){
Trace("sort-inference-debug") << "Process monotonicity for " << assertions[i] << std::endl;
std::map< Node, Node > var_bound;
- processMonotonic( assertions[i], true, true, var_bound );
+ processMonotonic( assertions[i], true, true, var_bound, visited );
}
Trace("sort-inference-proc") << "...done" << std::endl;
@@ -176,13 +178,16 @@ void SortInference::simplify( std::vector< Node >& assertions, bool doSortInfere
//simplify all assertions by introducing new symbols wherever necessary
Trace("sort-inference-proc") << "Perform simplification..." << std::endl;
+ std::map< Node, std::map< TypeNode, Node > > visited2;
for( unsigned i=0; i<assertions.size(); i++ ){
Node prev = assertions[i];
std::map< Node, Node > var_bound;
- Trace("sort-inference-debug") << "Rewrite " << assertions[i] << std::endl;
- Node curr = simplify( assertions[i], var_bound );
+ Trace("sort-inference-debug") << "Simplify " << assertions[i] << std::endl;
+ TypeNode tnn;
+ Node curr = simplifyNode( assertions[i], var_bound, tnn, visited2 );
Trace("sort-inference-debug") << "Done." << std::endl;
if( curr!=assertions[i] ){
+ Trace("sort-inference-debug") << "Rewrite " << curr << std::endl;
curr = theory::Rewriter::rewrite( curr );
rewritten = true;
Trace("sort-inference-rewrite") << assertions << std::endl;
@@ -196,9 +201,17 @@ void SortInference::simplify( std::vector< Node >& assertions, bool doSortInfere
for( std::map< TypeNode, std::map< Node, Node > >::iterator it = d_const_map.begin(); it != d_const_map.end(); ++it ){
std::vector< Node > consts;
for( std::map< Node, Node >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+ Assert( it2->first.isConst() );
consts.push_back( it2->second );
}
- //TODO: add lemma enforcing introduced constants to be distinct
+ //add lemma enforcing introduced constants to be distinct
+ if( consts.size()>1 ){
+ Node distinct_const = NodeManager::currentNM()->mkNode( kind::DISTINCT, consts );
+ Trace("sort-inference-rewrite") << "Add the constant distinctness lemma: " << std::endl;
+ Trace("sort-inference-rewrite") << " " << distinct_const << std::endl;
+ assertions.push_back( distinct_const );
+ rewritten = true;
+ }
}
//enforce constraints based on monotonicity
@@ -242,43 +255,15 @@ void SortInference::simplify( std::vector< Node >& assertions, bool doSortInfere
reset();
Trace("sort-inference-debug") << "Finished sort inference, rewritten = " << rewritten << std::endl;
}
- /*
- else if( !options::ufssSymBreak() ){
- //just add the unit lemmas between constants
- std::map< TypeNode, std::map< int, Node > > constants;
- for( std::map< Node, int >::iterator it = d_op_return_types.begin(); it != d_op_return_types.end(); ++it ){
- int rt = d_type_union_find.getRepresentative( it->second );
- if( d_op_arg_types[ it->first ].empty() ){
- TypeNode tn = it->first.getType();
- if( constants[ tn ].find( rt )==constants[ tn ].end() ){
- constants[ tn ][ rt ] = it->first;
- }
- }
- }
- //add unit lemmas for each constant
- for( std::map< TypeNode, std::map< int, Node > >::iterator it = constants.begin(); it != constants.end(); ++it ){
- Node first_const;
- for( std::map< int, Node >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
- if( first_const.isNull() ){
- first_const = it2->second;
- }else{
- Node eq = first_const.eqNode( it2->second );
- //eq = Rewriter::rewrite( eq );
- Trace("sort-inference-lemma") << "Sort inference lemma : " << eq << std::endl;
- assertions.push_back( eq );
- }
- }
- }
- }
- */
initialSortCount = sortCount;
}
if( doMonotonicyInference ){
+ std::map< Node, std::map< int, bool > > visited;
Trace("sort-inference-proc") << "Calculating monotonicty for types..." << std::endl;
for( unsigned i=0; i<assertions.size(); i++ ){
Trace("sort-inference-debug") << "Process type monotonicity for " << assertions[i] << std::endl;
std::map< Node, Node > var_bound;
- processMonotonic( assertions[i], true, true, var_bound, true );
+ processMonotonic( assertions[i], true, true, var_bound, visited, true );
}
Trace("sort-inference-proc") << "...done" << std::endl;
}
@@ -338,174 +323,185 @@ int SortInference::getIdForType( TypeNode tn ){
}
}
-int SortInference::process( Node n, std::map< Node, Node >& var_bound ){
- //add to variable bindings
- if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
- if( d_var_types.find( n )!=d_var_types.end() ){
- return getIdForType( n.getType() );
- }else{
- for( size_t i=0; i<n[0].getNumChildren(); i++ ){
- //apply sort inference to quantified variables
- d_var_types[n][ n[0][i] ] = sortCount;
- sortCount++;
+int SortInference::process( Node n, std::map< Node, Node >& var_bound, std::map< Node, int >& visited ){
+ std::map< Node, int >::iterator itv = visited.find( n );
+ if( itv!=visited.end() ){
+ return itv->second;
+ }else{
+ //add to variable bindings
+ bool use_new_visited = false;
+ std::map< Node, int > new_visited;
+ if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
+ if( d_var_types.find( n )!=d_var_types.end() ){
+ return getIdForType( n.getType() );
+ }else{
+ for( size_t i=0; i<n[0].getNumChildren(); i++ ){
+ //apply sort inference to quantified variables
+ d_var_types[n][ n[0][i] ] = sortCount;
+ sortCount++;
- //type of the quantified variable must be the same
- var_bound[ n[0][i] ] = n;
+ //type of the quantified variable must be the same
+ var_bound[ n[0][i] ] = n;
+ }
}
+ use_new_visited = true;
}
- }
- //process children
- std::vector< Node > children;
- std::vector< int > child_types;
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- bool processChild = true;
- if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
- processChild = options::userPatternsQuant()==theory::quantifiers::USER_PAT_MODE_IGNORE ? i==1 : i>=1;
- }
- if( processChild ){
- children.push_back( n[i] );
- child_types.push_back( process( n[i], var_bound ) );
+ //process children
+ std::vector< Node > children;
+ std::vector< int > child_types;
+ for( size_t i=0; i<n.getNumChildren(); i++ ){
+ bool processChild = true;
+ if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
+ processChild = options::userPatternsQuant()==theory::quantifiers::USER_PAT_MODE_IGNORE ? i==1 : i>=1;
+ }
+ if( processChild ){
+ children.push_back( n[i] );
+ child_types.push_back( process( n[i], var_bound, use_new_visited ? new_visited : visited ) );
+ }
}
- }
- //remove from variable bindings
- if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
- //erase from variable bound
- for( size_t i=0; i<n[0].getNumChildren(); i++ ){
- var_bound.erase( n[0][i] );
- }
- }
- Trace("sort-inference-debug") << "...Process " << n << std::endl;
-
- int retType;
- if( n.getKind()==kind::EQUAL ){
- Trace("sort-inference-debug") << "For equality " << n << ", set equal types from : " << n[0].getType() << " " << n[1].getType() << std::endl;
- //if original types are mixed (e.g. Int/Real), don't commit type equality in either direction
- if( n[0].getType()!=n[1].getType() ){
- //for now, assume the original types
- for( unsigned i=0; i<2; i++ ){
- int ct = getIdForType( n[i].getType() );
- setEqual( child_types[i], ct );
+ //remove from variable bindings
+ if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
+ //erase from variable bound
+ for( size_t i=0; i<n[0].getNumChildren(); i++ ){
+ var_bound.erase( n[0][i] );
}
- }else{
- //we only require that the left and right hand side must be equal
- setEqual( child_types[0], child_types[1] );
}
- //int eqType = getIdForType( n[0].getType() );
- //setEqual( child_types[0], eqType );
- //setEqual( child_types[1], eqType );
- retType = getIdForType( n.getType() );
- }else if( n.getKind()==kind::APPLY_UF ){
- Node op = n.getOperator();
- TypeNode tn_op = op.getType();
- if( d_op_return_types.find( op )==d_op_return_types.end() ){
- if( n.getType().isBoolean() ){
- //use booleans
- d_op_return_types[op] = getIdForType( n.getType() );
+ Trace("sort-inference-debug") << "...Process " << n << std::endl;
+
+ int retType;
+ if( n.getKind()==kind::EQUAL ){
+ Trace("sort-inference-debug") << "For equality " << n << ", set equal types from : " << n[0].getType() << " " << n[1].getType() << std::endl;
+ //if original types are mixed (e.g. Int/Real), don't commit type equality in either direction
+ if( n[0].getType()!=n[1].getType() ){
+ //for now, assume the original types
+ for( unsigned i=0; i<2; i++ ){
+ int ct = getIdForType( n[i].getType() );
+ setEqual( child_types[i], ct );
+ }
}else{
- //assign arbitrary sort for return type
- d_op_return_types[op] = sortCount;
- sortCount++;
+ //we only require that the left and right hand side must be equal
+ setEqual( child_types[0], child_types[1] );
}
- //d_type_eq_class[sortCount].push_back( op );
- //assign arbitrary sort for argument types
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- d_op_arg_types[op].push_back( sortCount );
- sortCount++;
- }
- }
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- //the argument of the operator must match the return type of the subterm
- if( n[i].getType()!=tn_op[i] ){
- //if type mismatch, assume original types
- Trace("sort-inference-debug") << "Argument " << i << " of " << op << " " << n[i] << " has type " << n[i].getType();
- Trace("sort-inference-debug") << ", while operator arg has type " << tn_op[i] << std::endl;
- int ct1 = getIdForType( n[i].getType() );
- setEqual( child_types[i], ct1 );
- int ct2 = getIdForType( tn_op[i] );
- setEqual( d_op_arg_types[op][i], ct2 );
- }else{
- setEqual( child_types[i], d_op_arg_types[op][i] );
+ d_equality_types[n] = child_types[0];
+ retType = getIdForType( n.getType() );
+ }else if( n.getKind()==kind::APPLY_UF ){
+ Node op = n.getOperator();
+ TypeNode tn_op = op.getType();
+ if( d_op_return_types.find( op )==d_op_return_types.end() ){
+ if( n.getType().isBoolean() ){
+ //use booleans
+ d_op_return_types[op] = getIdForType( n.getType() );
+ }else{
+ //assign arbitrary sort for return type
+ d_op_return_types[op] = sortCount;
+ sortCount++;
+ }
+ //d_type_eq_class[sortCount].push_back( op );
+ //assign arbitrary sort for argument types
+ for( size_t i=0; i<n.getNumChildren(); i++ ){
+ d_op_arg_types[op].push_back( sortCount );
+ sortCount++;
+ }
}
- }
- //return type is the return type
- retType = d_op_return_types[op];
- }else{
- std::map< Node, Node >::iterator it = var_bound.find( n );
- if( it!=var_bound.end() ){
- Trace("sort-inference-debug") << n << " is a bound variable." << std::endl;
- //the return type was specified while binding
- retType = d_var_types[it->second][n];
- }else if( n.getKind() == kind::VARIABLE || n.getKind()==kind::SKOLEM ){
- Trace("sort-inference-debug") << n << " is a variable." << std::endl;
- if( d_op_return_types.find( n )==d_op_return_types.end() ){
- //assign arbitrary sort
- d_op_return_types[n] = sortCount;
- sortCount++;
- //d_type_eq_class[sortCount].push_back( n );
+ for( size_t i=0; i<n.getNumChildren(); i++ ){
+ //the argument of the operator must match the return type of the subterm
+ if( n[i].getType()!=tn_op[i] ){
+ //if type mismatch, assume original types
+ Trace("sort-inference-debug") << "Argument " << i << " of " << op << " " << n[i] << " has type " << n[i].getType();
+ Trace("sort-inference-debug") << ", while operator arg has type " << tn_op[i] << std::endl;
+ int ct1 = getIdForType( n[i].getType() );
+ setEqual( child_types[i], ct1 );
+ int ct2 = getIdForType( tn_op[i] );
+ setEqual( d_op_arg_types[op][i], ct2 );
+ }else{
+ setEqual( child_types[i], d_op_arg_types[op][i] );
+ }
}
- retType = d_op_return_types[n];
- //}else if( n.isConst() ){
- // Trace("sort-inference-debug") << n << " is a constant." << std::endl;
- //can be any type we want
- // retType = sortCount;
- // sortCount++;
+ //return type is the return type
+ retType = d_op_return_types[op];
}else{
- Trace("sort-inference-debug") << n << " is a interpreted symbol." << std::endl;
- //it is an interpretted term
- for( size_t i=0; i<children.size(); i++ ){
- Trace("sort-inference-debug") << children[i] << " forced to have " << children[i].getType() << std::endl;
- //must enforce the actual type of the operator on the children
- int ct = getIdForType( children[i].getType() );
- setEqual( child_types[i], ct );
+ std::map< Node, Node >::iterator it = var_bound.find( n );
+ if( it!=var_bound.end() ){
+ Trace("sort-inference-debug") << n << " is a bound variable." << std::endl;
+ //the return type was specified while binding
+ retType = d_var_types[it->second][n];
+ }else if( n.getKind() == kind::VARIABLE || n.getKind()==kind::SKOLEM ){
+ Trace("sort-inference-debug") << n << " is a variable." << std::endl;
+ if( d_op_return_types.find( n )==d_op_return_types.end() ){
+ //assign arbitrary sort
+ d_op_return_types[n] = sortCount;
+ sortCount++;
+ //d_type_eq_class[sortCount].push_back( n );
+ }
+ retType = d_op_return_types[n];
+ }else if( n.isConst() ){
+ Trace("sort-inference-debug") << n << " is a constant." << std::endl;
+ //can be any type we want
+ retType = sortCount;
+ sortCount++;
+ }else{
+ Trace("sort-inference-debug") << n << " is a interpreted symbol." << std::endl;
+ //it is an interpreted term
+ for( size_t i=0; i<children.size(); i++ ){
+ Trace("sort-inference-debug") << children[i] << " forced to have " << children[i].getType() << std::endl;
+ //must enforce the actual type of the operator on the children
+ int ct = getIdForType( children[i].getType() );
+ setEqual( child_types[i], ct );
+ }
+ //return type must be the actual return type
+ retType = getIdForType( n.getType() );
}
- //return type must be the actual return type
- retType = getIdForType( n.getType() );
}
+ Trace("sort-inference-debug") << "...Type( " << n << " ) = ";
+ printSort("sort-inference-debug", retType );
+ Trace("sort-inference-debug") << std::endl;
+ visited[n] = retType;
+ return retType;
}
- Trace("sort-inference-debug") << "...Type( " << n << " ) = ";
- printSort("sort-inference-debug", retType );
- Trace("sort-inference-debug") << std::endl;
- return retType;
}
-void SortInference::processMonotonic( Node n, bool pol, bool hasPol, std::map< Node, Node >& var_bound, bool typeMode ) {
- Trace("sort-inference-debug") << "...Process monotonic " << pol << " " << hasPol << " " << n << std::endl;
- if( n.getKind()==kind::FORALL ){
- //only consider variables universally if it is possible this quantified formula is asserted positively
- if( !hasPol || pol ){
- for( unsigned i=0; i<n[0].getNumChildren(); i++ ){
- var_bound[n[0][i]] = n;
+void SortInference::processMonotonic( Node n, bool pol, bool hasPol, std::map< Node, Node >& var_bound, std::map< Node, std::map< int, bool > >& visited, bool typeMode ) {
+ int pindex = hasPol ? ( pol ? 1 : -1 ) : 0;
+ if( visited[n].find( pindex )==visited[n].end() ){
+ visited[n][pindex] = true;
+ Trace("sort-inference-debug") << "...Process monotonic " << pol << " " << hasPol << " " << n << std::endl;
+ if( n.getKind()==kind::FORALL ){
+ //only consider variables universally if it is possible this quantified formula is asserted positively
+ if( !hasPol || pol ){
+ for( unsigned i=0; i<n[0].getNumChildren(); i++ ){
+ var_bound[n[0][i]] = n;
+ }
}
- }
- processMonotonic( n[1], pol, hasPol, var_bound, typeMode );
- if( !hasPol || pol ){
- for( unsigned i=0; i<n[0].getNumChildren(); i++ ){
- var_bound.erase( n[0][i] );
+ processMonotonic( n[1], pol, hasPol, var_bound, visited, typeMode );
+ if( !hasPol || pol ){
+ for( unsigned i=0; i<n[0].getNumChildren(); i++ ){
+ var_bound.erase( n[0][i] );
+ }
}
- }
- return;
- }else if( n.getKind()==kind::EQUAL ){
- if( !hasPol || pol ){
- for( unsigned i=0; i<2; i++ ){
- if( var_bound.find( n[i] )!=var_bound.end() ){
- if( !typeMode ){
- int sid = getSortId( var_bound[n[i]], n[i] );
- d_non_monotonic_sorts[sid] = true;
- }else{
- d_non_monotonic_sorts_orig[n[i].getType()] = true;
+ return;
+ }else if( n.getKind()==kind::EQUAL ){
+ if( !hasPol || pol ){
+ for( unsigned i=0; i<2; i++ ){
+ if( var_bound.find( n[i] )!=var_bound.end() ){
+ if( !typeMode ){
+ int sid = getSortId( var_bound[n[i]], n[i] );
+ d_non_monotonic_sorts[sid] = true;
+ }else{
+ d_non_monotonic_sorts_orig[n[i].getType()] = true;
+ }
+ break;
}
- break;
}
}
}
- }
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- bool npol;
- bool nhasPol;
- theory::QuantPhaseReq::getPolarity( n, i, hasPol, pol, nhasPol, npol );
- processMonotonic( n[i], npol, nhasPol, var_bound, typeMode );
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ bool npol;
+ bool nhasPol;
+ theory::QuantPhaseReq::getPolarity( n, i, hasPol, pol, nhasPol, npol );
+ processMonotonic( n[i], npol, nhasPol, var_bound, visited, typeMode );
+ }
}
}
@@ -544,7 +540,7 @@ TypeNode SortInference::getTypeForId( int t ){
}
Node SortInference::getNewSymbol( Node old, TypeNode tn ){
- if( tn==old.getType() ){
+ if( tn.isNull() || tn==old.getType() ){
return old;
}else if( old.isConst() ){
//must make constant of type tn
@@ -565,128 +561,139 @@ Node SortInference::getNewSymbol( Node old, TypeNode tn ){
}
}
-Node SortInference::simplify( Node n, std::map< Node, Node >& var_bound ){
- Trace("sort-inference-debug2") << "Simplify " << n << std::endl;
- std::vector< Node > children;
- if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
- //recreate based on types of variables
- std::vector< Node > new_children;
- for( size_t i=0; i<n[0].getNumChildren(); i++ ){
- TypeNode tn = getOrCreateTypeForId( d_var_types[n][ n[0][i] ], n[0][i].getType() );
- Node v = getNewSymbol( n[0][i], tn );
- Trace("sort-inference-debug2") << "Map variable " << n[0][i] << " to " << v << std::endl;
- new_children.push_back( v );
- var_bound[ n[0][i] ] = v;
+Node SortInference::simplifyNode( Node n, std::map< Node, Node >& var_bound, TypeNode tnn, std::map< Node, std::map< TypeNode, Node > >& visited ){
+ std::map< TypeNode, Node >::iterator itv = visited[n].find( tnn );
+ if( itv!=visited[n].end() ){
+ return itv->second;
+ }else{
+ Trace("sort-inference-debug2") << "Simplify " << n << ", type context=" << tnn << std::endl;
+ std::vector< Node > children;
+ std::map< Node, std::map< TypeNode, Node > > new_visited;
+ bool use_new_visited = false;
+ if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
+ //recreate based on types of variables
+ std::vector< Node > new_children;
+ for( size_t i=0; i<n[0].getNumChildren(); i++ ){
+ TypeNode tn = getOrCreateTypeForId( d_var_types[n][ n[0][i] ], n[0][i].getType() );
+ Node v = getNewSymbol( n[0][i], tn );
+ Trace("sort-inference-debug2") << "Map variable " << n[0][i] << " to " << v << std::endl;
+ new_children.push_back( v );
+ var_bound[ n[0][i] ] = v;
+ }
+ children.push_back( NodeManager::currentNM()->mkNode( n[0].getKind(), new_children ) );
+ use_new_visited = true;
}
- children.push_back( NodeManager::currentNM()->mkNode( n[0].getKind(), new_children ) );
- }
- //process children
- if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
- children.push_back( n.getOperator() );
- }
- bool childChanged = false;
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- bool processChild = true;
- if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
- processChild = options::userPatternsQuant()==theory::quantifiers::USER_PAT_MODE_IGNORE ? i==1 : i>=1;
+ //process children
+ if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
+ children.push_back( n.getOperator() );
}
- if( processChild ){
- Node nc = simplify( n[i], var_bound );
- Trace("sort-inference-debug2") << "Simplify " << i << " " << n[i] << " returned " << nc << std::endl;
- children.push_back( nc );
- childChanged = childChanged || nc!=n[i];
+ Node op;
+ if( n.hasOperator() ){
+ op = n.getOperator();
}
- }
-
- //remove from variable bindings
- if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
- //erase from variable bound
- for( size_t i=0; i<n[0].getNumChildren(); i++ ){
- Trace("sort-inference-debug2") << "Remove bound for " << n[0][i] << std::endl;
- var_bound.erase( n[0][i] );
+ bool childChanged = false;
+ TypeNode tnnc;
+ for( size_t i=0; i<n.getNumChildren(); i++ ){
+ bool processChild = true;
+ if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
+ processChild = options::userPatternsQuant()==theory::quantifiers::USER_PAT_MODE_IGNORE ? i==1 : i>=1;
+ }
+ if( processChild ){
+ if( n.getKind()==kind::APPLY_UF ){
+ Assert( d_op_arg_types.find( op )!=d_op_arg_types.end() );
+ tnnc = getOrCreateTypeForId( d_op_arg_types[op][i], n[i].getType() );
+ Assert( !tnnc.isNull() );
+ }else if( n.getKind()==kind::EQUAL && i==0 ){
+ Assert( d_equality_types.find( n )!=d_equality_types.end() );
+ tnnc = getOrCreateTypeForId( d_equality_types[n], n[0].getType() );
+ Assert( !tnnc.isNull() );
+ }
+ Node nc = simplifyNode( n[i], var_bound, tnnc, use_new_visited ? new_visited : visited );
+ Trace("sort-inference-debug2") << "Simplify " << i << " " << n[i] << " returned " << nc << std::endl;
+ children.push_back( nc );
+ childChanged = childChanged || nc!=n[i];
+ }
}
- return NodeManager::currentNM()->mkNode( n.getKind(), children );
- }else if( n.getKind()==kind::EQUAL ){
- TypeNode tn1 = children[0].getType();
- TypeNode tn2 = children[1].getType();
- if( !tn1.isSubtypeOf( tn2 ) && !tn2.isSubtypeOf( tn1 ) ){
- if( children[0].isConst() ){
- children[0] = getNewSymbol( children[0], children[1].getType() );
- }else if( children[1].isConst() ){
- children[1] = getNewSymbol( children[1], children[0].getType() );
- }else{
+
+ //remove from variable bindings
+ Node ret;
+ if( n.getKind()==kind::FORALL || n.getKind()==kind::EXISTS ){
+ //erase from variable bound
+ for( size_t i=0; i<n[0].getNumChildren(); i++ ){
+ Trace("sort-inference-debug2") << "Remove bound for " << n[0][i] << std::endl;
+ var_bound.erase( n[0][i] );
+ }
+ ret = NodeManager::currentNM()->mkNode( n.getKind(), children );
+ }else if( n.getKind()==kind::EQUAL ){
+ TypeNode tn1 = children[0].getType();
+ TypeNode tn2 = children[1].getType();
+ if( !tn1.isSubtypeOf( tn2 ) && !tn2.isSubtypeOf( tn1 ) ){
Trace("sort-inference-warn") << "Sort inference created bad equality: " << children[0] << " = " << children[1] << std::endl;
Trace("sort-inference-warn") << " Types : " << children[0].getType() << " " << children[1].getType() << std::endl;
Assert( false );
}
- }
- return NodeManager::currentNM()->mkNode( kind::EQUAL, children );
- }else if( n.getKind()==kind::APPLY_UF ){
- Node op = n.getOperator();
- if( d_symbol_map.find( op )==d_symbol_map.end() ){
- //make the new operator if necessary
- bool opChanged = false;
- std::vector< TypeNode > argTypes;
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- TypeNode tn = getOrCreateTypeForId( d_op_arg_types[op][i], n[i].getType() );
- argTypes.push_back( tn );
- if( tn!=n[i].getType() ){
+ ret = NodeManager::currentNM()->mkNode( kind::EQUAL, children );
+ }else if( n.getKind()==kind::APPLY_UF ){
+ if( d_symbol_map.find( op )==d_symbol_map.end() ){
+ //make the new operator if necessary
+ bool opChanged = false;
+ std::vector< TypeNode > argTypes;
+ for( size_t i=0; i<n.getNumChildren(); i++ ){
+ TypeNode tn = getOrCreateTypeForId( d_op_arg_types[op][i], n[i].getType() );
+ argTypes.push_back( tn );
+ if( tn!=n[i].getType() ){
+ opChanged = true;
+ }
+ }
+ TypeNode retType = getOrCreateTypeForId( d_op_return_types[op], n.getType() );
+ if( retType!=n.getType() ){
opChanged = true;
}
- }
- TypeNode retType = getOrCreateTypeForId( d_op_return_types[op], n.getType() );
- if( retType!=n.getType() ){
- opChanged = true;
- }
- if( opChanged ){
- std::stringstream ss;
- ss << "io_" << op;
- TypeNode typ = NodeManager::currentNM()->mkFunctionType( argTypes, retType );
- d_symbol_map[op] = NodeManager::currentNM()->mkSkolem( ss.str(), typ, "op created during sort inference" );
- Trace("setp-model") << "Function " << op << " is replaced with " << d_symbol_map[op] << std::endl;
- d_model_replace_f[op] = d_symbol_map[op];
- }else{
- d_symbol_map[op] = op;
- }
- }
- children[0] = d_symbol_map[op];
- //make sure all children have been taken care of
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- TypeNode tn = children[i+1].getType();
- TypeNode tna = getTypeForId( d_op_arg_types[op][i] );
- if( tn!=tna ){
- if( n[i].isConst() ){
- children[i+1] = getNewSymbol( n[i], tna );
+ if( opChanged ){
+ std::stringstream ss;
+ ss << "io_" << op;
+ TypeNode typ = NodeManager::currentNM()->mkFunctionType( argTypes, retType );
+ d_symbol_map[op] = NodeManager::currentNM()->mkSkolem( ss.str(), typ, "op created during sort inference" );
+ Trace("setp-model") << "Function " << op << " is replaced with " << d_symbol_map[op] << std::endl;
+ d_model_replace_f[op] = d_symbol_map[op];
}else{
+ d_symbol_map[op] = op;
+ }
+ }
+ children[0] = d_symbol_map[op];
+ //make sure all children have been taken care of
+ for( size_t i=0; i<n.getNumChildren(); i++ ){
+ TypeNode tn = children[i+1].getType();
+ TypeNode tna = getTypeForId( d_op_arg_types[op][i] );
+ if( tn!=tna ){
Trace("sort-inference-warn") << "Sort inference created bad child: " << n << " " << n[i] << " " << tn << " " << tna << std::endl;
Assert( false );
}
}
- }
- return NodeManager::currentNM()->mkNode( kind::APPLY_UF, children );
- }else{
- std::map< Node, Node >::iterator it = var_bound.find( n );
- if( it!=var_bound.end() ){
- return it->second;
- }else if( n.getKind() == kind::VARIABLE || n.getKind() == kind::SKOLEM ){
- if( d_symbol_map.find( n )==d_symbol_map.end() ){
- TypeNode tn = getOrCreateTypeForId( d_op_return_types[n], n.getType() );
- d_symbol_map[n] = getNewSymbol( n, tn );
- }
- return d_symbol_map[n];
- }else if( n.isConst() ){
- //just return n, we will fix at higher scope
- return n;
+ ret = NodeManager::currentNM()->mkNode( kind::APPLY_UF, children );
}else{
- if( childChanged ){
- return NodeManager::currentNM()->mkNode( n.getKind(), children );
+ std::map< Node, Node >::iterator it = var_bound.find( n );
+ if( it!=var_bound.end() ){
+ ret = it->second;
+ }else if( n.getKind() == kind::VARIABLE || n.getKind() == kind::SKOLEM ){
+ if( d_symbol_map.find( n )==d_symbol_map.end() ){
+ TypeNode tn = getOrCreateTypeForId( d_op_return_types[n], n.getType() );
+ d_symbol_map[n] = getNewSymbol( n, tn );
+ }
+ ret = d_symbol_map[n];
+ }else if( n.isConst() ){
+ //type is determined by context
+ ret = getNewSymbol( n, tnn );
+ }else if( childChanged ){
+ ret = NodeManager::currentNM()->mkNode( n.getKind(), children );
}else{
- return n;
+ ret = n;
}
}
+ visited[n][tnn] = ret;
+ return ret;
}
-
}
Node SortInference::mkInjection( TypeNode tn1, TypeNode tn2 ) {
@@ -728,7 +735,8 @@ void SortInference::setSkolemVar( Node f, Node v, Node sk ){
if( isWellSortedFormula( f ) && d_var_types.find( f )==d_var_types.end() ){
//calculate the sort for variables if not done so already
std::map< Node, Node > var_bound;
- process( f, var_bound );
+ std::map< Node, int > visited;
+ process( f, var_bound, visited );
}
d_op_return_types[sk] = getSortId( f, v );
Trace("sort-inference-temp") << "Set skolem sort id for " << sk << " to " << d_op_return_types[sk] << std::endl;
diff --git a/src/theory/sort_inference.h b/src/theory/sort_inference.h
index f926776de..ae3342f92 100644
--- a/src/theory/sort_inference.h
+++ b/src/theory/sort_inference.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sort_inference.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Pre-process step for performing sort inference
**/
@@ -61,6 +61,7 @@ private:
//for apply uf operators
std::map< Node, int > d_op_return_types;
std::map< Node, std::vector< int > > d_op_arg_types;
+ std::map< Node, int > d_equality_types;
//for bound variables
std::map< Node, std::map< Node, int > > d_var_types;
//get representative
@@ -68,10 +69,10 @@ private:
int getIdForType( TypeNode tn );
void printSort( const char* c, int t );
//process
- int process( Node n, std::map< Node, Node >& var_bound );
+ int process( Node n, std::map< Node, Node >& var_bound, std::map< Node, int >& visited );
//for monotonicity inference
private:
- void processMonotonic( Node n, bool pol, bool hasPol, std::map< Node, Node >& var_bound, bool typeMode = false );
+ void processMonotonic( Node n, bool pol, bool hasPol, std::map< Node, Node >& var_bound, std::map< Node, std::map< int, bool > >& visited, bool typeMode = false );
//for rewriting
private:
@@ -84,7 +85,7 @@ private:
TypeNode getTypeForId( int t );
Node getNewSymbol( Node old, TypeNode tn );
//simplify
- Node simplify( Node n, std::map< Node, Node >& var_bound );
+ Node simplifyNode( Node n, std::map< Node, Node >& var_bound, TypeNode tnn, std::map< Node, std::map< TypeNode, Node > >& visited );
//make injection
Node mkInjection( TypeNode tn1, TypeNode tn2 );
//reset
diff --git a/src/theory/strings/regexp_operation.cpp b/src/theory/strings/regexp_operation.cpp
index 98f03327a..53344dd6c 100644
--- a/src/theory/strings/regexp_operation.cpp
+++ b/src/theory/strings/regexp_operation.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file regexp_operation.cpp
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tianyi Liang, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Symbolic Regular Expresion Operations
**
diff --git a/src/theory/strings/regexp_operation.h b/src/theory/strings/regexp_operation.h
index 012a573c1..c537553f2 100644
--- a/src/theory/strings/regexp_operation.h
+++ b/src/theory/strings/regexp_operation.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file regexp_operation.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tianyi Liang, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Symbolic Regular Expresion Operations
**
diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp
index 529e69e82..b3e1925ae 100644
--- a/src/theory/strings/theory_strings.cpp
+++ b/src/theory/strings/theory_strings.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings.cpp
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Martin Brain <>, Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tianyi Liang, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the theory of strings.
**
@@ -653,7 +653,9 @@ void TheoryStrings::checkReduction( Node atom, int pol, int effort ) {
if( atom.getKind()==kind::STRING_IN_REGEXP ){
if( atom[1].getKind()==kind::REGEXP_RANGE ){
Node eq = d_one.eqNode(NodeManager::currentNM()->mkNode(kind::STRING_LENGTH, atom[0]));
- sendLemma( atom, eq, "RE-Range-Len" );
+ std::vector< Node > exp_vec;
+ exp_vec.push_back( atom );
+ sendInference( d_empty_vec, exp_vec, eq, "RE-Range-Len", true );
}
}else if( atom.getKind()==kind::STRING_STRCTN ){
Node x = atom[0];
@@ -663,7 +665,9 @@ void TheoryStrings::checkReduction( Node atom, int pol, int effort ) {
Node sk1 = mkSkolemCached( x, s, sk_id_ctn_pre, "sc1" );
Node sk2 = mkSkolemCached( x, s, sk_id_ctn_post, "sc2" );
Node eq = Rewriter::rewrite( x.eqNode( mkConcat( sk1, s, sk2 ) ) );
- sendLemma( atom, eq, "POS-CTN" );
+ std::vector< Node > exp_vec;
+ exp_vec.push_back( atom );
+ sendInference( d_empty_vec, exp_vec, eq, "POS-CTN", true );
}else{
// for STRING_SUBSTR,
// STRING_STRIDOF, STRING_ITOS, STRING_U16TOS, STRING_U32TOS, STRING_STOI, STRING_STOU16, STRING_STOU32, STRING_STRREPL
@@ -675,7 +679,7 @@ void TheoryStrings::checkReduction( Node atom, int pol, int effort ) {
nnlem = Rewriter::rewrite( nnlem );
Trace("strings-red-lemma") << "Reduction_" << effort << " lemma : " << nnlem << std::endl;
Trace("strings-red-lemma") << "...from " << atom << std::endl;
- sendLemma( d_true, nnlem, "Reduction" );
+ sendInference( d_empty_vec, nnlem, "Reduction", true );
}
}
}
@@ -950,7 +954,7 @@ void TheoryStrings::checkInit() {
}
}
//infer the equality
- sendInfer( mkAnd( exp ), n.eqNode( nc ), "I_Norm" );
+ sendInference( exp, n.eqNode( nc ), "I_Norm" );
}else{
//update the extf map : only process if neither has been reduced
NodeBoolMap::const_iterator it = d_ext_func_terms.find( n );
@@ -989,7 +993,7 @@ void TheoryStrings::checkInit() {
}
AlwaysAssert( foundNEmpty );
//infer the equality
- sendInfer( mkAnd( exp ), n.eqNode( c[0] ), "I_Norm_S" );
+ sendInference( exp, n.eqNode( c[0] ), "I_Norm_S" );
}
d_congruent.insert( n );
congruent[k]++;
@@ -1141,11 +1145,7 @@ void TheoryStrings::checkExtendedFuncsEval( int effort ) {
}
if( !conc.isNull() ){
Trace("strings-extf") << " resolve extf : " << nr << " -> " << nrc << std::endl;
- if( n.getType().isInteger() || d_extf_exp[n].empty() ){
- sendLemma( mkExplain( d_extf_exp[n] ), conc, effort==0 ? "EXTF" : "EXTF-N" );
- }else{
- sendInfer( mkAnd( d_extf_exp[n] ), conc, effort==0 ? "EXTF" : "EXTF-N" );
- }
+ sendInference( d_extf_exp[n], conc, effort==0 ? "EXTF" : "EXTF-N", n.getType().isInteger() || d_extf_exp[n].empty() );
if( d_conflict ){
Trace("strings-extf-debug") << " conflict, return." << std::endl;
return;
@@ -1158,7 +1158,7 @@ void TheoryStrings::checkExtendedFuncsEval( int effort ) {
Trace("strings-extf-debug") << " decomposable..." << std::endl;
Trace("strings-extf") << " resolve extf : " << nr << " -> " << nrc << ", pol = " << d_extf_pol[n] << std::endl;
for( unsigned i=0; i<nrc.getNumChildren(); i++ ){
- sendInfer( mkAnd( d_extf_exp[n] ), d_extf_pol[n]==-1 ? nrc[i].negate() : nrc[i], effort==0 ? "EXTF_d" : "EXTF_d-N" );
+ sendInference( d_extf_exp[n], d_extf_pol[n]==-1 ? nrc[i].negate() : nrc[i], effort==0 ? "EXTF_d" : "EXTF_d-N" );
}
}else{
to_reduce = nrc;
@@ -1202,13 +1202,13 @@ void TheoryStrings::checkExtfInference( Node n, Node nr, int effort ){
std::vector< Node > children;
children.push_back( nr[0] );
children.push_back( nr[1] );
- Node exp_n = mkAnd( d_extf_exp[n] );
+ //Node exp_n = mkAnd( d_extf_exp[n] );
for( unsigned i=0; i<nr[index].getNumChildren(); i++ ){
children[index] = nr[index][i];
Node conc = NodeManager::currentNM()->mkNode( kind::STRING_STRCTN, children );
//can mark as reduced, since model for n => model for conc
d_ext_func_terms[conc] = false;
- sendInfer( exp_n, n_pol==1 ? conc : conc.negate(), "CTN_Decompose" );
+ sendInference( d_extf_exp[n], n_pol==1 ? conc : conc.negate(), "CTN_Decompose" );
}
}
}else{
@@ -1238,7 +1238,7 @@ void TheoryStrings::checkExtfInference( Node n, Node nr, int effort ){
Node ofrom = d_extf_info[nr[0]].d_ctn_from[opol][i];
Assert( d_extf_exp.find( ofrom )!=d_extf_exp.end() );
exp.insert( exp.end(), d_extf_exp[ofrom].begin(), d_extf_exp[ofrom].end() );
- sendInfer( mkAnd( exp ), conc, "CTN_Trans" );
+ sendInference( exp, conc, "CTN_Trans" );
}
}
}else{
@@ -1417,8 +1417,9 @@ void TheoryStrings::checkFlatForms() {
}else{
Node curr = d_flat_form[a][count];
Node curr_c = d_eqc_to_const[curr];
+ Node ac = a[d_flat_form_index[a][count]];
std::vector< Node > lexp;
- Node lcurr = getLength( curr, lexp );
+ Node lcurr = getLength( ac, lexp );
for( unsigned i=1; i<it->second.size(); i++ ){
b = it->second[i];
if( std::find( inelig.begin(), inelig.end(), b )==inelig.end() ){
@@ -1438,7 +1439,6 @@ void TheoryStrings::checkFlatForms() {
}else{
Node cc = d_flat_form[b][count];
if( cc!=curr ){
- Node ac = a[d_flat_form_index[a][count]];
Node bc = b[d_flat_form_index[b][count]];
inelig.push_back( b );
Assert( !areEqual( curr, cc ) );
@@ -1462,11 +1462,17 @@ void TheoryStrings::checkFlatForms() {
break;
}else{
//if lengths are the same, apply LengthEq
- Node lcc = getLength( cc, lexp );
+ std::vector< Node > lexp2;
+ Node lcc = getLength( bc, lexp2 );
if( areEqual( lcurr, lcc ) ){
Trace("strings-ff-debug") << "Infer " << ac << " == " << bc << " since " << lcurr << " == " << lcc << std::endl;
//exp_n.push_back( getLength( curr, true ).eqNode( getLength( cc, true ) ) );
+ Trace("strings-ff-debug") << "Explanation for " << lcurr << " is ";
+ for( unsigned j=0; j<lexp.size(); j++ ) { Trace("strings-ff-debug") << lexp[j] << std::endl; }
+ Trace("strings-ff-debug") << "Explanation for " << lcc << " is ";
+ for( unsigned j=0; j<lexp2.size(); j++ ) { Trace("strings-ff-debug") << lexp2[j] << std::endl; }
exp.insert( exp.end(), lexp.begin(), lexp.end() );
+ exp.insert( exp.end(), lexp2.begin(), lexp2.end() );
addToExplanation( lcurr, lcc, exp );
conc = ac.eqNode( bc );
inf_type = 1;
@@ -1505,7 +1511,7 @@ void TheoryStrings::checkFlatForms() {
}
}
//if( exp_n.empty() ){
- sendInfer( mkAnd( exp ), conc, inf_type==0? "F_Const" : ( inf_type==1 ? "F_LengthEq" : ( inf_type==2 ? "F_Endpoint" : "F_EndpointEq" ) ) );
+ sendInference( exp, conc, inf_type==0? "F_Const" : ( inf_type==1 ? "F_LengthEq" : ( inf_type==2 ? "F_Endpoint" : "F_EndpointEq" ) ) );
//}else{
//}
if( d_conflict ){
@@ -1555,7 +1561,9 @@ Node TheoryStrings::checkCycles( Node eqc, std::vector< Node >& curr, std::vecto
if( eqc==d_emptyString_r ){
//for empty eqc, ensure all components are empty
if( nr!=d_emptyString_r ){
- sendInfer( n.eqNode( d_emptyString ), n[i].eqNode( d_emptyString ), "I_CYCLE_E" );
+ std::vector< Node > exp;
+ exp.push_back( n.eqNode( d_emptyString ) );
+ sendInference( exp, n[i].eqNode( d_emptyString ), "I_CYCLE_E" );
return Node::null();
}
}else{
@@ -1574,7 +1582,7 @@ Node TheoryStrings::checkCycles( Node eqc, std::vector< Node >& curr, std::vecto
for( unsigned j=0; j<n.getNumChildren(); j++ ){
//take first non-empty
if( j!=i && !areEqual( n[j], d_emptyString ) ){
- sendInfer( mkAnd( exp ), n[j].eqNode( d_emptyString ), "I_CYCLE" );
+ sendInference( exp, n[j].eqNode( d_emptyString ), "I_CYCLE" );
return Node::null();
}
}
@@ -1642,7 +1650,7 @@ void TheoryStrings::checkNormalForms(){
//two equivalence classes have same normal form, merge
nf_exp.push_back( eqc_to_exp[nf_to_eqc[nf_term]] );
Node eq = eqc.eqNode( nf_to_eqc[nf_term] );
- sendInfer( mkAnd( nf_exp ), eq, "Normal_Form" );
+ sendInference( nf_exp, eq, "Normal_Form" );
} else {
nf_to_eqc[nf_term] = eqc;
eqc_to_exp[eqc] = mkAnd( nf_exp );
@@ -1701,14 +1709,16 @@ bool TheoryStrings::normalizeEquivalenceClass( Node eqc, std::vector< Node > & n
std::vector< std::vector< Node > > normal_forms;
// explanation for each normal form (phi)
std::vector< std::vector< Node > > normal_forms_exp;
+ // dependency information
+ std::vector< std::map< Node, std::map< bool, int > > > normal_forms_exp_depend;
// record terms for each normal form (t)
std::vector< Node > normal_form_src;
//Get Normal Forms
- result = getNormalForms(eqc, nf, normal_forms, normal_forms_exp, normal_form_src);
+ result = getNormalForms(eqc, normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend);
if( hasProcessed() ){
- return true;
+ return true;
}else if( result ){
- if( processNEqc(normal_forms, normal_forms_exp, normal_form_src) ){
+ if( processNEqc(normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend) ){
return true;
}
}
@@ -1716,20 +1726,43 @@ bool TheoryStrings::normalizeEquivalenceClass( Node eqc, std::vector< Node > & n
if( normal_forms.empty() ){
Trace("strings-solve-debug2") << "construct the normal form" << std::endl;
getConcatVec( eqc, nf );
+ d_normal_forms_base[eqc] = eqc;
}else{
- Trace("strings-solve-debug2") << "just take the first normal form" << std::endl;
- //just take the first normal form
- nf.insert( nf.end(), normal_forms[0].begin(), normal_forms[0].end() );
- nf_exp.insert( nf_exp.end(), normal_forms_exp[0].begin(), normal_forms_exp[0].end() );
- if( eqc!=normal_form_src[0] ){
- nf_exp.push_back( eqc.eqNode( normal_form_src[0] ) );
+ int nf_index = 0;
+ //nf.insert( nf.end(), normal_forms[nf_index].begin(), normal_forms[nf_index].end() );
+ //nf_exp.insert( nf_exp.end(), normal_forms_exp[nf_index].begin(), normal_forms_exp[nf_index].end() );
+ //Trace("strings-solve-debug2") << "take normal form ... done" << std::endl;
+ //d_normal_forms_base[eqc] = normal_form_src[nf_index];
+ ///*
+ std::vector< Node >::iterator itn = std::find( normal_form_src.begin(), normal_form_src.end(), eqc );
+ if( itn!=normal_form_src.end() ){
+ nf_index = itn - normal_form_src.begin();
+ Trace("strings-solve-debug2") << "take normal form " << nf_index << std::endl;
+ Assert( normal_form_src[nf_index]==eqc );
+ }else{
+ //just take the first normal form
+ Trace("strings-solve-debug2") << "take the first normal form" << std::endl;
+ }
+ nf.insert( nf.end(), normal_forms[nf_index].begin(), normal_forms[nf_index].end() );
+ nf_exp.insert( nf_exp.end(), normal_forms_exp[nf_index].begin(), normal_forms_exp[nf_index].end() );
+ //if( eqc!=normal_form_src[nf_index] ){
+ // nf_exp.push_back( eqc.eqNode( normal_form_src[nf_index] ) );
+ //}
+ Trace("strings-solve-debug2") << "take normal form ... done" << std::endl;
+ d_normal_forms_base[eqc] = normal_form_src[nf_index];
+ //*/
+ //track dependencies
+ for( unsigned i=0; i<normal_forms_exp[nf_index].size(); i++ ){
+ Node exp = normal_forms_exp[nf_index][i];
+ for( unsigned r=0; r<2; r++ ){
+ d_normal_forms_exp_depend[eqc][exp][r==0] = normal_forms_exp_depend[nf_index][exp][r==0];
+ }
}
- Trace("strings-solve-debug2") << "just take the first normal form ... done" << std::endl;
}
- d_normal_forms_base[eqc] = normal_form_src.empty() ? eqc : normal_form_src[0];
d_normal_forms[eqc].insert( d_normal_forms[eqc].end(), nf.begin(), nf.end() );
d_normal_forms_exp[eqc].insert( d_normal_forms_exp[eqc].end(), nf_exp.begin(), nf_exp.end() );
+
Trace("strings-process-debug") << "Return process equivalence class " << eqc << " : returned, size = " << nf.size() << std::endl;
}else{
Trace("strings-process-debug") << "Return process equivalence class " << eqc << " : already computed, size = " << d_normal_forms[eqc].size() << std::endl;
@@ -1741,9 +1774,8 @@ bool TheoryStrings::normalizeEquivalenceClass( Node eqc, std::vector< Node > & n
}
}
-bool TheoryStrings::getNormalForms( Node &eqc, std::vector< Node > & nf,
- std::vector< std::vector< Node > > &normal_forms, std::vector< std::vector< Node > > &normal_forms_exp,
- std::vector< Node > &normal_form_src) {
+bool TheoryStrings::getNormalForms( Node &eqc, std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend ) {
Trace("strings-process-debug") << "Get normal forms " << eqc << std::endl;
eq::EqClassIterator eqc_i = eq::EqClassIterator( eqc, &d_equalityEngine );
while( !eqc_i.isFinished() ){
@@ -1751,8 +1783,9 @@ bool TheoryStrings::getNormalForms( Node &eqc, std::vector< Node > & nf,
if( d_congruent.find( n )==d_congruent.end() ){
if( n.getKind() == kind::CONST_STRING || n.getKind() == kind::STRING_CONCAT ){
Trace("strings-process-debug") << "Get Normal Form : Process term " << n << " in eqc " << eqc << std::endl;
- std::vector<Node> nf_n;
- std::vector<Node> nf_exp_n;
+ std::vector< Node > nf_n;
+ std::vector< Node > nf_exp_n;
+ std::map< Node, std::map< bool, int > > nf_exp_depend_n;
if( n.getKind()==kind::CONST_STRING ){
if( n!=d_emptyString ) {
nf_n.push_back( n );
@@ -1760,33 +1793,55 @@ bool TheoryStrings::getNormalForms( Node &eqc, std::vector< Node > & nf,
}else if( n.getKind()==kind::STRING_CONCAT ){
for( unsigned i=0; i<n.getNumChildren(); i++ ) {
Node nr = d_equalityEngine.getRepresentative( n[i] );
- std::vector< Node > nf_temp;
- std::vector< Node > nf_exp_temp;
Trace("strings-process-debug") << "Normalizing subterm " << n[i] << " = " << nr << std::endl;
Assert( d_normal_forms.find( nr )!=d_normal_forms.end() );
- nf_temp.insert( nf_temp.end(), d_normal_forms[nr].begin(), d_normal_forms[nr].end() );
- nf_exp_temp.insert( nf_exp_temp.end(), d_normal_forms_exp[nr].begin(), d_normal_forms_exp[nr].end() );
+ unsigned orig_size = nf_n.size();
+ unsigned add_size = d_normal_forms[nr].size();
//if not the empty string, add to current normal form
- if( nf.size()!=1 || nf[0]!=d_emptyString ){
- for( unsigned r=0; r<nf_temp.size(); r++ ) {
+ if( !d_normal_forms[nr].empty() ){
+ for( unsigned r=0; r<d_normal_forms[nr].size(); r++ ) {
if( Trace.isOn("strings-error") ) {
- if( nf_temp[r].getKind()==kind::STRING_CONCAT ){
+ if( d_normal_forms[nr][r].getKind()==kind::STRING_CONCAT ){
Trace("strings-error") << "Strings::Error: From eqc = " << eqc << ", " << n << " index " << i << ", bad normal form : ";
- for( unsigned rr=0; rr<nf_temp.size(); rr++ ) {
- Trace("strings-error") << nf_temp[rr] << " ";
+ for( unsigned rr=0; rr<d_normal_forms[nr].size(); rr++ ) {
+ Trace("strings-error") << d_normal_forms[nr][rr] << " ";
}
Trace("strings-error") << std::endl;
}
}
- Assert( nf_temp[r].getKind()!=kind::STRING_CONCAT );
+ Assert( d_normal_forms[nr][r].getKind()!=kind::STRING_CONCAT );
+ }
+ nf_n.insert( nf_n.end(), d_normal_forms[nr].begin(), d_normal_forms[nr].end() );
+ }
+
+ for( unsigned j=0; j<d_normal_forms_exp[nr].size(); j++ ){
+ Node exp = d_normal_forms_exp[nr][j];
+ nf_exp_n.push_back( exp );
+ //track depends
+ for( unsigned k=0; k<2; k++ ){
+ int prev_dep = d_normal_forms_exp_depend[nr][exp][k==1];
+ if( k==0 ){
+ nf_exp_depend_n[exp][false] = orig_size + prev_dep;
+ }else if( k==1 ){
+ //store forward index (converted back to reverse index below)
+ nf_exp_depend_n[exp][true] = orig_size + ( add_size - prev_dep );
+ }
}
- nf_n.insert( nf_n.end(), nf_temp.begin(), nf_temp.end() );
}
- nf_exp_n.insert( nf_exp_n.end(), nf_exp_temp.begin(), nf_exp_temp.end() );
if( nr!=n[i] ){
- nf_exp_n.push_back( n[i].eqNode( nr ) );
+ Node eq = n[i].eqNode( nr );
+ nf_exp_n.push_back( eq );
+ //track depends
+ nf_exp_depend_n[eq][false] = orig_size;
+ nf_exp_depend_n[eq][true] = orig_size + add_size;
}
}
+ //convert forward indices to reverse indices
+ int total_size = nf_n.size();
+ for( std::map< Node, std::map< bool, int > >::iterator it = nf_exp_depend_n.begin(); it != nf_exp_depend_n.end(); ++it ){
+ it->second[true] = total_size - it->second[true];
+ Assert( it->second[true]>=0 );
+ }
}
//if not equal to self
if( nf_n.size()>1 || ( nf_n.size()==1 && nf_n[0].getKind()==kind::CONST_STRING ) ){
@@ -1801,8 +1856,9 @@ bool TheoryStrings::getNormalForms( Node &eqc, std::vector< Node > & nf,
}
}
normal_forms.push_back(nf_n);
- normal_forms_exp.push_back(nf_exp_n);
normal_form_src.push_back(n);
+ normal_forms_exp.push_back(nf_exp_n);
+ normal_forms_exp_depend.push_back(nf_exp_depend_n);
}else{
//this was redundant: combination of self + empty string(s)
Node nn = nf_n.size()==0 ? d_emptyString : nf_n[0];
@@ -1814,7 +1870,7 @@ bool TheoryStrings::getNormalForms( Node &eqc, std::vector< Node > & nf,
ant.insert( ant.end(), nf_exp_n.begin(), nf_exp_n.end() );
ant.push_back( n.eqNode( eqc ) );
Node conc = Rewriter::rewrite( nn.eqNode( eqc ) );
- sendInfer( mkAnd( ant ), conc, "CYCLE-T" );
+ sendInference( ant, conc, "CYCLE-T" );
return true;
}
*/
@@ -1846,72 +1902,92 @@ bool TheoryStrings::getNormalForms( Node &eqc, std::vector< Node > & nf,
}
Trace("strings-solve") << normal_forms_exp[i][j];
}
+ Trace("strings-solve") << std::endl;
+ Trace("strings-solve") << "WITH DEPENDENCIES : " << std::endl;
+ for( unsigned j=0; j<normal_forms_exp[i].size(); j++ ) {
+ Trace("strings-solve") << " " << normal_forms_exp[i][j] << " -> ";
+ Trace("strings-solve") << normal_forms_exp_depend[i][normal_forms_exp[i][j]][false] << ",";
+ Trace("strings-solve") << normal_forms_exp_depend[i][normal_forms_exp[i][j]][true] << std::endl;
+ }
}
Trace("strings-solve") << std::endl;
+
}
} else {
- //std::vector< Node > nf;
- //nf.push_back( eqc );
- //normal_forms.push_back(nf);
- //std::vector< Node > nf_exp_def;
- //normal_forms_exp.push_back(nf_exp_def);
- //normal_form_src.push_back(eqc);
Trace("strings-solve") << "--- Single normal form for equivalence class " << eqc << std::endl;
}
}
return true;
}
+void TheoryStrings::getExplanationVectorForPrefix( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend,
+ unsigned i, unsigned j, int index, bool isRev, std::vector< Node >& curr_exp ) {
+ if( index==-1 || !options::stringMinPrefixExplain() ){
+ curr_exp.insert(curr_exp.end(), normal_forms_exp[i].begin(), normal_forms_exp[i].end() );
+ curr_exp.insert(curr_exp.end(), normal_forms_exp[j].begin(), normal_forms_exp[j].end() );
+ }else{
+ Trace("strings-explain-prefix") << "Get explanation for prefix " << index << " of normal forms " << i << " and " << j << ", reverse = " << isRev << std::endl;
+ for( unsigned r=0; r<2; r++ ){
+ int tindex = r==0 ? i : j;
+ for( unsigned k=0; k<normal_forms_exp[tindex].size(); k++ ){
+ Node exp = normal_forms_exp[tindex][k];
+ int dep = normal_forms_exp_depend[tindex][exp][isRev];
+ if( dep<=index ){
+ curr_exp.push_back( exp );
+ Trace("strings-explain-prefix-debug") << " include : " << exp << std::endl;
+ }else{
+ Trace("strings-explain-prefix-debug") << " exclude : " << exp << std::endl;
+ }
+ }
+ }
+ Trace("strings-explain-prefix") << "Included " << curr_exp.size() << " / " << ( normal_forms_exp[i].size() + normal_forms_exp[j].size() ) << std::endl;
+ }
+ if( normal_form_src[i]!=normal_form_src[j] ){
+ curr_exp.push_back( normal_form_src[i].eqNode( normal_form_src[j] ) );
+ }
+}
-bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_forms, std::vector< std::vector< Node > > &normal_forms_exp,
- std::vector< Node > &normal_form_src) {
+bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend ) {
bool flag_lb = false;
std::vector< Node > c_lb_exp;
- int c_i, c_j, c_loop_n_index, c_other_n_index, c_loop_index, c_index, c_other_index;
+ int c_i, c_j, c_loop_n_index, c_other_n_index, c_loop_index, c_index;
for(unsigned i=0; i<normal_forms.size()-1; i++) {
//unify each normalform[j] with normal_forms[i]
for(unsigned j=i+1; j<normal_forms.size(); j++ ) {
Trace("strings-solve") << "Strings: Process normal form #" << i << " against #" << j << "..." << std::endl;
if( isNormalFormPair( normal_form_src[i], normal_form_src[j] ) ) {
Trace("strings-solve") << "Strings: Already cached." << std::endl;
- } else {
- //the current explanation for why the prefix is equal
- std::vector< Node > curr_exp;
- curr_exp.insert(curr_exp.end(), normal_forms_exp[i].begin(), normal_forms_exp[i].end() );
- curr_exp.insert(curr_exp.end(), normal_forms_exp[j].begin(), normal_forms_exp[j].end() );
- if( normal_form_src[i]!=normal_form_src[j] ){
- curr_exp.push_back( normal_form_src[i].eqNode( normal_form_src[j] ) );
- }
-
+ }else{
//process the reverse direction first (check for easy conflicts and inferences)
- if( processReverseNEq( normal_forms, normal_form_src, curr_exp, i, j ) ){
+ if( processReverseNEq( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j ) ){
return true;
}
//ensure that normal_forms[i] and normal_forms[j] are the same modulo equality
- unsigned index_i = 0;
- unsigned index_j = 0;
+ unsigned index = 0;
bool success;
do{
//simple check
- if( processSimpleNEq( normal_forms, normal_form_src, curr_exp, i, j, index_i, index_j, false ) ){
+ if( processSimpleNEq( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, index, false ) ){
//added a lemma, return
return true;
}
success = false;
//if we are at the end
- if(index_i==normal_forms[i].size() || index_j==normal_forms[j].size() ) {
- Assert( index_i==normal_forms[i].size() && index_j==normal_forms[j].size() );
+ if(index==normal_forms[i].size() || index==normal_forms[j].size() ) {
+ Assert( index==normal_forms[i].size() && index==normal_forms[j].size() );
//we're done
//addNormalFormPair( normal_form_src[i], normal_form_src[j] );
} else {
std::vector< Node > lexp;
- Node length_term_i = getLength( normal_forms[i][index_i], lexp );
- Node length_term_j = getLength( normal_forms[j][index_j], lexp );
+ Node length_term_i = getLength( normal_forms[i][index], lexp );
+ Node length_term_j = getLength( normal_forms[j][index], lexp );
//check length(normal_forms[i][index]) == length(normal_forms[j][index])
if( !areDisequal(length_term_i, length_term_j) && !areEqual(length_term_i, length_term_j) &&
- normal_forms[i][index_i].getKind()!=kind::CONST_STRING && normal_forms[j][index_j].getKind()!=kind::CONST_STRING ) {
+ normal_forms[i][index].getKind()!=kind::CONST_STRING && normal_forms[j][index].getKind()!=kind::CONST_STRING ) {
//length terms are equal, merge equivalence classes if not already done so
Node length_eq = NodeManager::currentNM()->mkNode( kind::EQUAL, length_term_i, length_term_j );
Trace("strings-solve-debug") << "Non-simple Case 1 : string lengths neither equal nor disequal" << std::endl;
@@ -1924,23 +2000,21 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
Trace("strings-solve-debug") << "Non-simple Case 2 : must compare strings" << std::endl;
int loop_in_i = -1;
int loop_in_j = -1;
- if( detectLoop(normal_forms, i, j, index_i, index_j, loop_in_i, loop_in_j) ){
+ if( detectLoop(normal_forms, i, j, index, loop_in_i, loop_in_j) ){
if( !flag_lb ){
c_i = i;
c_j = j;
c_loop_n_index = loop_in_i!=-1 ? i : j;
c_other_n_index = loop_in_i!=-1 ? j : i;
c_loop_index = loop_in_i!=-1 ? loop_in_i : loop_in_j;
- c_index = loop_in_i!=-1 ? index_i : index_j;
- c_other_index = loop_in_i!=-1 ? index_j : index_i;
-
- c_lb_exp = curr_exp;
+ c_index = index;
+
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, -1, false, c_lb_exp );
if(options::stringLB() == 0) {
flag_lb = true;
} else {
- if(processLoop(c_lb_exp, normal_forms, normal_form_src,
- c_i, c_j, c_loop_n_index, c_other_n_index, c_loop_index, c_index, c_other_index)) {
+ if(processLoop(c_lb_exp, normal_forms, normal_form_src, c_i, c_j, c_loop_n_index, c_other_n_index, c_loop_index, c_index)) {
return true;
}
}
@@ -1949,26 +2023,24 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
Node conc;
std::vector< Node > antec;
Trace("strings-solve-debug") << "No loops detected." << std::endl;
- if( normal_forms[i][index_i].getKind() == kind::CONST_STRING || normal_forms[j][index_j].getKind() == kind::CONST_STRING) {
- unsigned const_k = normal_forms[i][index_i].getKind() == kind::CONST_STRING ? i : j;
- unsigned const_index_k = normal_forms[i][index_i].getKind() == kind::CONST_STRING ? index_i : index_j;
- unsigned nconst_k = normal_forms[i][index_i].getKind() == kind::CONST_STRING ? j : i;
- unsigned nconst_index_k = normal_forms[i][index_i].getKind() == kind::CONST_STRING ? index_j : index_i;
- Node const_str = normal_forms[const_k][const_index_k];
- Node other_str = normal_forms[nconst_k][nconst_index_k];
+ if( normal_forms[i][index].getKind() == kind::CONST_STRING || normal_forms[j][index].getKind() == kind::CONST_STRING) {
+ unsigned const_k = normal_forms[i][index].getKind() == kind::CONST_STRING ? i : j;
+ unsigned nconst_k = normal_forms[i][index].getKind() == kind::CONST_STRING ? j : i;
+ Node const_str = normal_forms[const_k][index];
+ Node other_str = normal_forms[nconst_k][index];
Assert( other_str.getKind()!=kind::CONST_STRING, "Other string is not constant." );
Assert( other_str.getKind()!=kind::STRING_CONCAT, "Other string is not CONCAT." );
- if( !areDisequal(other_str, d_emptyString) ) {
+ if( !d_equalityEngine.areDisequal(other_str, d_emptyString, true) ) {
sendSplit( other_str, d_emptyString, "Len-Split(CST)" );
} else {
Assert(areDisequal(other_str, d_emptyString), "CST Split on empty Var");
- antec.insert( antec.end(), curr_exp.begin(), curr_exp.end() );
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, index, false, antec );
Node xnz = other_str.eqNode(d_emptyString).negate();
antec.push_back( xnz );
Node conc;
- if( normal_forms[nconst_k].size() > nconst_index_k + 1 && normal_forms[nconst_k][nconst_index_k + 1].isConst() ) {
+ if( normal_forms[nconst_k].size() > index + 1 && normal_forms[nconst_k][index + 1].isConst() ) {
CVC4::String stra = const_str.getConst<String>();
- CVC4::String strb = normal_forms[nconst_k][nconst_index_k + 1].getConst<String>();
+ CVC4::String strb = normal_forms[nconst_k][index + 1].getConst<String>();
CVC4::String stra1 = stra.substr(1);
size_t p = stra.size() - stra1.overlap(strb);
size_t p2 = stra1.find(strb);
@@ -1987,13 +2059,12 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
}
conc = Rewriter::rewrite( conc );
- sendLemma( mkExplain( antec ), conc, "S-Split(CST-P)" );
- //sendInfer(mkAnd( antec ), conc, "S-Split(CST-P)");
+ sendInference( antec, conc, "S-Split(CST-P)", true );
}
return true;
} else {
std::vector< Node > antec_new_lits;
- antec.insert(antec.end(), curr_exp.begin(), curr_exp.end() );
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, index, false, antec );
Node ldeq = NodeManager::currentNM()->mkNode( kind::EQUAL, length_term_i, length_term_j ).negate();
if( d_equalityEngine.areDisequal( length_term_i, length_term_j, true ) ){
@@ -2004,7 +2075,7 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
//x!=e /\ y!=e
for(unsigned xory=0; xory<2; xory++) {
- Node x = xory==0 ? normal_forms[i][index_i] : normal_forms[j][index_j];
+ Node x = xory==0 ? normal_forms[i][index] : normal_forms[j][index];
Node xgtz = x.eqNode( d_emptyString ).negate();
if( d_equalityEngine.areDisequal( x, d_emptyString, true ) ) {
antec.push_back( xgtz );
@@ -2012,15 +2083,31 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
antec_new_lits.push_back( xgtz );
}
}
+ Node sk = mkSkolemCached( normal_forms[i][index], normal_forms[j][index], sk_id_v_spt, "v_spt", 1 );
+ Node eq1 = normal_forms[i][index].eqNode( mkConcat(normal_forms[j][index], sk) );
+ Node eq2 = normal_forms[j][index].eqNode( mkConcat(normal_forms[i][index], sk) );
+ if( options::stringCheckEntailLen() ){
+ //check entailment
+ for( unsigned e=0; e<2; e++ ){
+ Node lt1 = e==0 ? length_term_i : length_term_j;
+ Node lt2 = e==0 ? length_term_j : length_term_i;
+ Node ent_lit = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::GT, lt1, lt2 ) );
+ std::pair<bool, Node> et = d_valuation.entailmentCheck(THEORY_OF_TYPE_BASED, ent_lit );
+ if( et.first ){
+ Trace("strings-entail") << "Strings entailment : " << ent_lit << " is entailed in the current context." << std::endl;
+ Trace("strings-entail") << " explanation was : " << et.second << std::endl;
+ conc = e==0 ? eq1 : eq2;
+ antec_new_lits.push_back( et.second );
+ break;
+ }
+ }
+ }
+ if( conc.isNull() ){
+ conc = Rewriter::rewrite(NodeManager::currentNM()->mkNode( kind::OR, eq1, eq2 ));
+ }
- Node sk = mkSkolemCached( normal_forms[i][index_i], normal_forms[j][index_j], sk_id_v_spt, "v_spt", 1 );
- Node eq1 = normal_forms[i][index_i].eqNode( mkConcat(normal_forms[j][index_j], sk) );
- Node eq2 = normal_forms[j][index_j].eqNode( mkConcat(normal_forms[i][index_i], sk) );
- conc = Rewriter::rewrite(NodeManager::currentNM()->mkNode( kind::OR, eq1, eq2 ));
- Node ant = mkExplain( antec, antec_new_lits );
- sendLemma( ant, conc, "S-Split(VAR)" );
- //sendInfer( ant, conc, "S-Split(VAR)" );
+ sendInference( antec, antec_new_lits, conc, "S-Split(VAR)", true );
//++(d_statistics.d_eq_splits);
return true;
}
@@ -2035,8 +2122,7 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
}
}
if(flag_lb) {
- if(processLoop(c_lb_exp, normal_forms, normal_form_src,
- c_i, c_j, c_loop_n_index, c_other_n_index, c_loop_index, c_index, c_other_index)) {
+ if(processLoop(c_lb_exp, normal_forms, normal_form_src, c_i, c_j, c_loop_n_index, c_other_n_index, c_loop_index, c_index)) {
return true;
}
}
@@ -2045,16 +2131,14 @@ bool TheoryStrings::processNEqc( std::vector< std::vector< Node > > &normal_form
}
bool TheoryStrings::processReverseNEq( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
- std::vector< Node > &curr_exp, unsigned i, unsigned j ) {
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend,
+ unsigned i, unsigned j ) {
//reverse normal form of i, j
std::reverse( normal_forms[i].begin(), normal_forms[i].end() );
std::reverse( normal_forms[j].begin(), normal_forms[j].end() );
- std::vector< Node > t_curr_exp;
- t_curr_exp.insert( t_curr_exp.begin(), curr_exp.begin(), curr_exp.end() );
- unsigned index_i = 0;
- unsigned index_j = 0;
- bool ret = processSimpleNEq( normal_forms, normal_form_src, t_curr_exp, i, j, index_i, index_j, true );
+ unsigned index = 0;
+ bool ret = processSimpleNEq( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, index, true );
//reverse normal form of i, j
std::reverse( normal_forms[i].begin(), normal_forms[i].end() );
@@ -2063,66 +2147,65 @@ bool TheoryStrings::processReverseNEq( std::vector< std::vector< Node > > &norma
return ret;
}
-bool TheoryStrings::processSimpleNEq( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src, std::vector< Node > &curr_exp,
- unsigned i, unsigned j, unsigned& index_i, unsigned& index_j, bool isRev ) {
+bool TheoryStrings::processSimpleNEq( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend,
+ unsigned i, unsigned j, unsigned& index, bool isRev ) {
bool success;
do {
success = false;
//if we are at the end
- if(index_i==normal_forms[i].size() || index_j==normal_forms[j].size() ) {
- if( index_i==normal_forms[i].size() && index_j==normal_forms[j].size() ) {
+ if(index==normal_forms[i].size() || index==normal_forms[j].size() ) {
+ if( index==normal_forms[i].size() && index==normal_forms[j].size() ) {
//we're done
} else {
//the remainder must be empty
- unsigned k = index_i==normal_forms[i].size() ? j : i;
- unsigned index_k = index_i==normal_forms[i].size() ? index_j : index_i;
- Node eq_exp = mkAnd( curr_exp );
+ unsigned k = index==normal_forms[i].size() ? j : i;
+ unsigned index_k = index;
+ //Node eq_exp = mkAnd( curr_exp );
+ std::vector< Node > curr_exp;
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, -1, isRev, curr_exp );
while(!d_conflict && index_k<normal_forms[k].size()) {
//can infer that this string must be empty
Node eq = normal_forms[k][index_k].eqNode( d_emptyString );
//Trace("strings-lemma") << "Strings: Infer " << eq << " from " << eq_exp << std::endl;
Assert( !areEqual( d_emptyString, normal_forms[k][index_k] ) );
- sendInfer( eq_exp, eq, "EQ_Endpoint" );
+ sendInference( curr_exp, eq, "EQ_Endpoint" );
index_k++;
}
return true;
}
}else{
- Trace("strings-solve-debug") << "Process " << normal_forms[i][index_i] << " ... " << normal_forms[j][index_j] << std::endl;
- if(areEqual(normal_forms[i][index_i], normal_forms[j][index_j])) {
+ Trace("strings-solve-debug") << "Process " << normal_forms[i][index] << " ... " << normal_forms[j][index] << std::endl;
+ if( normal_forms[i][index]==normal_forms[j][index] ){
Trace("strings-solve-debug") << "Simple Case 1 : strings are equal" << std::endl;
- //terms are equal, continue
- if( normal_forms[i][index_i]!=normal_forms[j][index_j] ){
- Node eq = normal_forms[i][index_i].eqNode(normal_forms[j][index_j]);
- Trace("strings-solve-debug") << "Add to explanation : " << eq << std::endl;
- curr_exp.push_back(eq);
- }
- index_j++;
- index_i++;
+ index++;
success = true;
- } else {
+ }else{
+ Assert( !areEqual(normal_forms[i][index], normal_forms[j][index]) );
std::vector< Node > temp_exp;
- Node length_term_i = getLength( normal_forms[i][index_i], temp_exp );
- Node length_term_j = getLength( normal_forms[j][index_j], temp_exp );
+ Node length_term_i = getLength( normal_forms[i][index], temp_exp );
+ Node length_term_j = getLength( normal_forms[j][index], temp_exp );
//check length(normal_forms[i][index]) == length(normal_forms[j][index])
if( areEqual( length_term_i, length_term_j ) ){
Trace("strings-solve-debug") << "Simple Case 2 : string lengths are equal" << std::endl;
- Node eq = normal_forms[i][index_i].eqNode( normal_forms[j][index_j] );
+ Node eq = normal_forms[i][index].eqNode( normal_forms[j][index] );
//eq = Rewriter::rewrite( eq );
Node length_eq = length_term_i.eqNode( length_term_j );
- temp_exp.insert(temp_exp.end(), curr_exp.begin(), curr_exp.end() );
+ //temp_exp.insert(temp_exp.end(), curr_exp.begin(), curr_exp.end() );
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, index, isRev, temp_exp );
temp_exp.push_back(length_eq);
- sendInfer( mkAnd( temp_exp ), eq, "LengthEq" );
+ sendInference( temp_exp, eq, "LengthEq" );
return true;
- }else if( ( normal_forms[i][index_i].getKind()!=kind::CONST_STRING && index_i==normal_forms[i].size()-1 ) ||
- ( normal_forms[j][index_j].getKind()!=kind::CONST_STRING && index_j==normal_forms[j].size()-1 ) ){
+ }else if( ( normal_forms[i][index].getKind()!=kind::CONST_STRING && index==normal_forms[i].size()-1 ) ||
+ ( normal_forms[j][index].getKind()!=kind::CONST_STRING && index==normal_forms[j].size()-1 ) ){
Trace("strings-solve-debug") << "Simple Case 3 : at endpoint" << std::endl;
Node conc;
std::vector< Node > antec;
- antec.insert(antec.end(), curr_exp.begin(), curr_exp.end() );
+ //antec.insert(antec.end(), curr_exp.begin(), curr_exp.end() );
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, -1, isRev, antec );
std::vector< Node > eqn;
for( unsigned r=0; r<2; r++ ) {
- int index_k = r==0 ? index_i : index_j;
+ int index_k = index;
int k = r==0 ? i : j;
std::vector< Node > eqnc;
for( unsigned index_l=index_k; index_l<normal_forms[k].size(); index_l++ ) {
@@ -2136,16 +2219,15 @@ bool TheoryStrings::processSimpleNEq( std::vector< std::vector< Node > > &normal
}
if( !areEqual( eqn[0], eqn[1] ) ) {
conc = eqn[0].eqNode( eqn[1] );
- sendLemma( mkExplain( antec ), conc, "ENDPOINT" );
- //sendInfer( mkAnd( antec ), conc, "ENDPOINT" );
+ sendInference( antec, conc, "ENDPOINT", true );
return true;
}else{
- index_i = normal_forms[i].size();
- index_j = normal_forms[j].size();
+ Assert( normal_forms[i].size()==normal_forms[j].size() );
+ index = normal_forms[i].size();
}
- } else if(normal_forms[i][index_i].isConst() && normal_forms[j][index_j].isConst()) {
- Node const_str = normal_forms[i][index_i];
- Node other_str = normal_forms[j][index_j];
+ } else if( normal_forms[i][index].isConst() && normal_forms[j][index].isConst() ){
+ Node const_str = normal_forms[i][index];
+ Node other_str = normal_forms[j][index];
Trace("strings-solve-debug") << "Simple Case 3 : Const Split : " << const_str << " vs " << other_str << std::endl;
unsigned len_short = const_str.getConst<String>().size() <= other_str.getConst<String>().size() ? const_str.getConst<String>().size() : other_str.getConst<String>().size();
bool isSameFix = isRev ? const_str.getConst<String>().rstrncmp(other_str.getConst<String>(), len_short): const_str.getConst<String>().strncmp(other_str.getConst<String>(), len_short);
@@ -2153,29 +2235,26 @@ bool TheoryStrings::processSimpleNEq( std::vector< std::vector< Node > > &normal
//same prefix/suffix
//k is the index of the string that is shorter
int k = const_str.getConst<String>().size()<other_str.getConst<String>().size() ? i : j;
- int index_k = const_str.getConst<String>().size()<other_str.getConst<String>().size() ? index_i : index_j;
int l = const_str.getConst<String>().size()<other_str.getConst<String>().size() ? j : i;
- int index_l = const_str.getConst<String>().size()<other_str.getConst<String>().size() ? index_j : index_i;
if(isRev) {
- int new_len = normal_forms[l][index_l].getConst<String>().size() - len_short;
- Node remainderStr = NodeManager::currentNM()->mkConst( normal_forms[l][index_l].getConst<String>().substr(0, new_len) );
- Trace("strings-solve-debug-test") << "Break normal form of " << normal_forms[l][index_l] << " into " << normal_forms[k][index_k] << ", " << remainderStr << std::endl;
- normal_forms[l].insert( normal_forms[l].begin()+index_l + 1, remainderStr );
+ int new_len = normal_forms[l][index].getConst<String>().size() - len_short;
+ Node remainderStr = NodeManager::currentNM()->mkConst( normal_forms[l][index].getConst<String>().substr(0, new_len) );
+ Trace("strings-solve-debug-test") << "Break normal form of " << normal_forms[l][index] << " into " << normal_forms[k][index] << ", " << remainderStr << std::endl;
+ normal_forms[l].insert( normal_forms[l].begin()+index + 1, remainderStr );
} else {
- Node remainderStr = NodeManager::currentNM()->mkConst(normal_forms[l][index_l].getConst<String>().substr(len_short));
- Trace("strings-solve-debug-test") << "Break normal form of " << normal_forms[l][index_l] << " into " << normal_forms[k][index_k] << ", " << remainderStr << std::endl;
- normal_forms[l].insert( normal_forms[l].begin()+index_l + 1, remainderStr );
+ Node remainderStr = NodeManager::currentNM()->mkConst(normal_forms[l][index].getConst<String>().substr(len_short));
+ Trace("strings-solve-debug-test") << "Break normal form of " << normal_forms[l][index] << " into " << normal_forms[k][index] << ", " << remainderStr << std::endl;
+ normal_forms[l].insert( normal_forms[l].begin()+index + 1, remainderStr );
}
- normal_forms[l][index_l] = normal_forms[k][index_k];
- index_i++;
- index_j++;
+ normal_forms[l][index] = normal_forms[k][index];
+ index++;
success = true;
} else {
std::vector< Node > antec;
//curr_exp is conflict
- antec.insert(antec.end(), curr_exp.begin(), curr_exp.end() );
- Node ant = mkExplain( antec );
- sendLemma( ant, d_false, "Const Conflict" );
+ //antec.insert(antec.end(), curr_exp.begin(), curr_exp.end() );
+ getExplanationVectorForPrefix( normal_forms, normal_form_src, normal_forms_exp, normal_forms_exp_depend, i, j, index, isRev, antec );
+ sendInference( antec, d_false, "Const Conflict", true );
return true;
}
}
@@ -2185,18 +2264,15 @@ bool TheoryStrings::processSimpleNEq( std::vector< std::vector< Node > > &normal
return false;
}
-bool TheoryStrings::detectLoop( std::vector< std::vector< Node > > &normal_forms, int i, int j,
- int index_i, int index_j, int &loop_in_i, int &loop_in_j) {
+bool TheoryStrings::detectLoop( std::vector< std::vector< Node > > &normal_forms, int i, int j, int index, int &loop_in_i, int &loop_in_j) {
int has_loop[2] = { -1, -1 };
if( options::stringLB() != 2 ) {
for( unsigned r=0; r<2; r++ ) {
- int index = (r==0 ? index_i : index_j);
- int other_index = (r==0 ? index_j : index_i );
int n_index = (r==0 ? i : j);
int other_n_index = (r==0 ? j : i);
- if( normal_forms[other_n_index][other_index].getKind() != kind::CONST_STRING ) {
+ if( normal_forms[other_n_index][index].getKind() != kind::CONST_STRING ) {
for( unsigned lp = index+1; lp<normal_forms[n_index].size(); lp++ ){
- if( normal_forms[n_index][lp]==normal_forms[other_n_index][other_index] ){
+ if( normal_forms[n_index][lp]==normal_forms[other_n_index][index] ){
has_loop[r] = lp;
break;
}
@@ -2215,163 +2291,173 @@ bool TheoryStrings::detectLoop( std::vector< std::vector< Node > > &normal_forms
//xs(zy)=t(yz)xr
bool TheoryStrings::processLoop( std::vector< Node > &antec, std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
- int i, int j, int loop_n_index, int other_n_index, int loop_index, int index, int other_index) {
- Node conc;
- Trace("strings-loop") << "Detected possible loop for " << normal_forms[loop_n_index][loop_index] << std::endl;
- Trace("strings-loop") << " ... (X)= " << normal_forms[other_n_index][other_index] << std::endl;
-
- Trace("strings-loop") << " ... T(Y.Z)= ";
- std::vector< Node > vec_t;
- for(int lp=index; lp<loop_index; ++lp) {
- if(lp != index) Trace("strings-loop") << " ++ ";
- Trace("strings-loop") << normal_forms[loop_n_index][lp];
- vec_t.push_back( normal_forms[loop_n_index][lp] );
- }
- Node t_yz = mkConcat( vec_t );
- Trace("strings-loop") << " (" << t_yz << ")" << std::endl;
- Trace("strings-loop") << " ... S(Z.Y)= ";
- std::vector< Node > vec_s;
- for(int lp=other_index+1; lp<(int)normal_forms[other_n_index].size(); ++lp) {
- if(lp != other_index+1) Trace("strings-loop") << " ++ ";
- Trace("strings-loop") << normal_forms[other_n_index][lp];
- vec_s.push_back( normal_forms[other_n_index][lp] );
- }
- Node s_zy = mkConcat( vec_s );
- Trace("strings-loop") << " (" << s_zy << ")" << std::endl;
- Trace("strings-loop") << " ... R= ";
- std::vector< Node > vec_r;
- for(int lp=loop_index+1; lp<(int)normal_forms[loop_n_index].size(); ++lp) {
- if(lp != loop_index+1) Trace("strings-loop") << " ++ ";
- Trace("strings-loop") << normal_forms[loop_n_index][lp];
- vec_r.push_back( normal_forms[loop_n_index][lp] );
- }
- Node r = mkConcat( vec_r );
- Trace("strings-loop") << " (" << r << ")" << std::endl;
-
- //Trace("strings-loop") << "Lemma Cache: " << normal_form_src[i] << " vs " << normal_form_src[j] << std::endl;
- //TODO: can be more general
- if( s_zy.isConst() && r.isConst() && r != d_emptyString) {
- int c;
- bool flag = true;
- if(s_zy.getConst<String>().tailcmp( r.getConst<String>(), c ) ) {
- if(c >= 0) {
- s_zy = NodeManager::currentNM()->mkConst( s_zy.getConst<String>().substr(0, c) );
- r = d_emptyString;
- vec_r.clear();
- Trace("strings-loop") << "Strings::Loop: Refactor S(Z.Y)= " << s_zy << ", c=" << c << std::endl;
- flag = false;
- }
+ int i, int j, int loop_n_index, int other_n_index, int loop_index, int index) {
+ if( options::stringAbortLoop() ){
+ Message() << "Looping word equation encountered." << std::endl;
+ exit( 1 );
+ }else{
+ Node conc;
+ Trace("strings-loop") << "Detected possible loop for " << normal_forms[loop_n_index][loop_index] << std::endl;
+ Trace("strings-loop") << " ... (X)= " << normal_forms[other_n_index][index] << std::endl;
+
+ Trace("strings-loop") << " ... T(Y.Z)= ";
+ std::vector< Node > vec_t;
+ for(int lp=index; lp<loop_index; ++lp) {
+ if(lp != index) Trace("strings-loop") << " ++ ";
+ Trace("strings-loop") << normal_forms[loop_n_index][lp];
+ vec_t.push_back( normal_forms[loop_n_index][lp] );
}
- if(flag) {
- Trace("strings-loop") << "Strings::Loop: tails are different." << std::endl;
- sendLemma( mkExplain( antec ), conc, "Loop Conflict" );
- return true;
+ Node t_yz = mkConcat( vec_t );
+ Trace("strings-loop") << " (" << t_yz << ")" << std::endl;
+ Trace("strings-loop") << " ... S(Z.Y)= ";
+ std::vector< Node > vec_s;
+ for(int lp=index+1; lp<(int)normal_forms[other_n_index].size(); ++lp) {
+ if(lp != index+1) Trace("strings-loop") << " ++ ";
+ Trace("strings-loop") << normal_forms[other_n_index][lp];
+ vec_s.push_back( normal_forms[other_n_index][lp] );
+ }
+ Node s_zy = mkConcat( vec_s );
+ Trace("strings-loop") << " (" << s_zy << ")" << std::endl;
+ Trace("strings-loop") << " ... R= ";
+ std::vector< Node > vec_r;
+ for(int lp=loop_index+1; lp<(int)normal_forms[loop_n_index].size(); ++lp) {
+ if(lp != loop_index+1) Trace("strings-loop") << " ++ ";
+ Trace("strings-loop") << normal_forms[loop_n_index][lp];
+ vec_r.push_back( normal_forms[loop_n_index][lp] );
+ }
+ Node r = mkConcat( vec_r );
+ Trace("strings-loop") << " (" << r << ")" << std::endl;
+
+ //Trace("strings-loop") << "Lemma Cache: " << normal_form_src[i] << " vs " << normal_form_src[j] << std::endl;
+ //TODO: can be more general
+ if( s_zy.isConst() && r.isConst() && r != d_emptyString) {
+ int c;
+ bool flag = true;
+ if(s_zy.getConst<String>().tailcmp( r.getConst<String>(), c ) ) {
+ if(c >= 0) {
+ s_zy = NodeManager::currentNM()->mkConst( s_zy.getConst<String>().substr(0, c) );
+ r = d_emptyString;
+ vec_r.clear();
+ Trace("strings-loop") << "Strings::Loop: Refactor S(Z.Y)= " << s_zy << ", c=" << c << std::endl;
+ flag = false;
+ }
+ }
+ if(flag) {
+ Trace("strings-loop") << "Strings::Loop: tails are different." << std::endl;
+ sendInference( antec, conc, "Loop Conflict", true );
+ return true;
+ }
}
- }
- //require that x is non-empty
- if( !areDisequal( normal_forms[loop_n_index][loop_index], d_emptyString ) ){
- //try to make normal_forms[loop_n_index][loop_index] equal to empty to avoid loop
- sendSplit( normal_forms[loop_n_index][loop_index], d_emptyString, "Len-Split(Loop-X)" );
- } else if( !areDisequal( t_yz, d_emptyString ) && t_yz.getKind()!=kind::CONST_STRING ) {
- //try to make normal_forms[loop_n_index][loop_index] equal to empty to avoid loop
- sendSplit( t_yz, d_emptyString, "Len-Split(Loop-YZ)" );
- } else {
- //need to break
- antec.push_back( normal_forms[loop_n_index][loop_index].eqNode( d_emptyString ).negate() );
- if( t_yz.getKind()!=kind::CONST_STRING ) {
- antec.push_back( t_yz.eqNode( d_emptyString ).negate() );
- }
- Node ant = mkExplain( antec );
- if(d_loop_antec.find(ant) == d_loop_antec.end()) {
- d_loop_antec.insert(ant);
-
- Node str_in_re;
- if( s_zy == t_yz &&
- r == d_emptyString &&
- s_zy.isConst() &&
- s_zy.getConst<String>().isRepeated()
- ) {
- Node rep_c = NodeManager::currentNM()->mkConst( s_zy.getConst<String>().substr(0, 1) );
- Trace("strings-loop") << "Special case (X)=" << normal_forms[other_n_index][other_index] << " " << std::endl;
- Trace("strings-loop") << "... (C)=" << rep_c << " " << std::endl;
- //special case
- str_in_re = NodeManager::currentNM()->mkNode( kind::STRING_IN_REGEXP, normal_forms[other_n_index][other_index],
- NodeManager::currentNM()->mkNode( kind::REGEXP_STAR,
- NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, rep_c ) ) );
- conc = str_in_re;
- } else if(t_yz.isConst()) {
- Trace("strings-loop") << "Strings::Loop: Const Normal Breaking." << std::endl;
- CVC4::String s = t_yz.getConst< CVC4::String >();
- unsigned size = s.size();
- std::vector< Node > vconc;
- for(unsigned len=1; len<=size; len++) {
- Node y = NodeManager::currentNM()->mkConst(s.substr(0, len));
- Node z = NodeManager::currentNM()->mkConst(s.substr(len, size - len));
- Node restr = s_zy;
- Node cc;
- if(r != d_emptyString) {
- std::vector< Node > v2(vec_r);
- v2.insert(v2.begin(), y);
- v2.insert(v2.begin(), z);
- restr = mkConcat( z, y );
- cc = Rewriter::rewrite(s_zy.eqNode( mkConcat( v2 ) ));
- } else {
- cc = Rewriter::rewrite(s_zy.eqNode( mkConcat( z, y) ));
- }
- if(cc == d_false) {
- continue;
+ //require that x is non-empty
+ if( !areDisequal( normal_forms[loop_n_index][loop_index], d_emptyString ) ){
+ //try to make normal_forms[loop_n_index][loop_index] equal to empty to avoid loop
+ sendSplit( normal_forms[loop_n_index][loop_index], d_emptyString, "Len-Split(Loop-X)" );
+ } else if( !areDisequal( t_yz, d_emptyString ) && t_yz.getKind()!=kind::CONST_STRING ) {
+ //try to make normal_forms[loop_n_index][loop_index] equal to empty to avoid loop
+ sendSplit( t_yz, d_emptyString, "Len-Split(Loop-YZ)" );
+ } else {
+ //need to break
+ antec.push_back( normal_forms[loop_n_index][loop_index].eqNode( d_emptyString ).negate() );
+ if( t_yz.getKind()!=kind::CONST_STRING ) {
+ antec.push_back( t_yz.eqNode( d_emptyString ).negate() );
+ }
+ Node ant = mkExplain( antec );
+ if(d_loop_antec.find(ant) == d_loop_antec.end()) {
+ d_loop_antec.insert(ant);
+
+ Node str_in_re;
+ if( s_zy == t_yz &&
+ r == d_emptyString &&
+ s_zy.isConst() &&
+ s_zy.getConst<String>().isRepeated()
+ ) {
+ Node rep_c = NodeManager::currentNM()->mkConst( s_zy.getConst<String>().substr(0, 1) );
+ Trace("strings-loop") << "Special case (X)=" << normal_forms[other_n_index][index] << " " << std::endl;
+ Trace("strings-loop") << "... (C)=" << rep_c << " " << std::endl;
+ //special case
+ str_in_re = NodeManager::currentNM()->mkNode( kind::STRING_IN_REGEXP, normal_forms[other_n_index][index],
+ NodeManager::currentNM()->mkNode( kind::REGEXP_STAR,
+ NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, rep_c ) ) );
+ conc = str_in_re;
+ } else if(t_yz.isConst()) {
+ Trace("strings-loop") << "Strings::Loop: Const Normal Breaking." << std::endl;
+ CVC4::String s = t_yz.getConst< CVC4::String >();
+ unsigned size = s.size();
+ std::vector< Node > vconc;
+ for(unsigned len=1; len<=size; len++) {
+ Node y = NodeManager::currentNM()->mkConst(s.substr(0, len));
+ Node z = NodeManager::currentNM()->mkConst(s.substr(len, size - len));
+ Node restr = s_zy;
+ Node cc;
+ if(r != d_emptyString) {
+ std::vector< Node > v2(vec_r);
+ v2.insert(v2.begin(), y);
+ v2.insert(v2.begin(), z);
+ restr = mkConcat( z, y );
+ cc = Rewriter::rewrite(s_zy.eqNode( mkConcat( v2 ) ));
+ } else {
+ cc = Rewriter::rewrite(s_zy.eqNode( mkConcat( z, y) ));
+ }
+ if(cc == d_false) {
+ continue;
+ }
+ Node conc2 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, normal_forms[other_n_index][index],
+ NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT,
+ NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, y),
+ NodeManager::currentNM()->mkNode(kind::REGEXP_STAR,
+ NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, restr))));
+ cc = cc==d_true ? conc2 : NodeManager::currentNM()->mkNode( kind::AND, cc, conc2 );
+ d_regexp_ant[conc2] = ant;
+ vconc.push_back(cc);
}
- Node conc2 = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, normal_forms[other_n_index][other_index],
- NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT,
- NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, y),
- NodeManager::currentNM()->mkNode(kind::REGEXP_STAR,
- NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, restr))));
- cc = cc==d_true ? conc2 : NodeManager::currentNM()->mkNode( kind::AND, cc, conc2 );
- d_regexp_ant[conc2] = ant;
- vconc.push_back(cc);
+ conc = vconc.size()==0 ? Node::null() : vconc.size()==1 ? vconc[0] : NodeManager::currentNM()->mkNode(kind::OR, vconc);
+ } else {
+ Trace("strings-loop") << "Strings::Loop: Normal Loop Breaking." << std::endl;
+ //right
+ Node sk_w= mkSkolemS( "w_loop" );
+ Node sk_y= mkSkolemS( "y_loop", 1 );
+ Node sk_z= mkSkolemS( "z_loop" );
+ //t1 * ... * tn = y * z
+ Node conc1 = t_yz.eqNode( mkConcat( sk_y, sk_z ) );
+ // s1 * ... * sk = z * y * r
+ vec_r.insert(vec_r.begin(), sk_y);
+ vec_r.insert(vec_r.begin(), sk_z);
+ Node conc2 = s_zy.eqNode( mkConcat( vec_r ) );
+ Node conc3 = normal_forms[other_n_index][index].eqNode( mkConcat( sk_y, sk_w ) );
+ Node restr = r == d_emptyString ? s_zy : mkConcat( sk_z, sk_y );
+ str_in_re = NodeManager::currentNM()->mkNode( kind::STRING_IN_REGEXP, sk_w,
+ NodeManager::currentNM()->mkNode( kind::REGEXP_STAR,
+ NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, restr ) ) );
+
+ std::vector< Node > vec_conc;
+ vec_conc.push_back(conc1); vec_conc.push_back(conc2); vec_conc.push_back(conc3);
+ vec_conc.push_back(str_in_re);
+ //vec_conc.push_back(sk_y.eqNode(d_emptyString).negate());//by mkskolems
+ conc = NodeManager::currentNM()->mkNode( kind::AND, vec_conc );
+ } // normal case
+
+ //set its antecedant to ant, to say when it is relevant
+ if(!str_in_re.isNull()) {
+ d_regexp_ant[str_in_re] = ant;
+ }
+ //we will be done
+ addNormalFormPair( normal_form_src[i], normal_form_src[j] );
+ if( options::stringProcessLoop() ){
+ sendLemma( ant, conc, "F-LOOP" );
+ ++(d_statistics.d_loop_lemmas);
+ }else{
+ d_out->setIncomplete();
+ return false;
}
- conc = vconc.size()==0 ? Node::null() : vconc.size()==1 ? vconc[0] : NodeManager::currentNM()->mkNode(kind::OR, vconc);
+
} else {
- Trace("strings-loop") << "Strings::Loop: Normal Loop Breaking." << std::endl;
- //right
- Node sk_w= mkSkolemS( "w_loop" );
- Node sk_y= mkSkolemS( "y_loop", 1 );
- Node sk_z= mkSkolemS( "z_loop" );
- //t1 * ... * tn = y * z
- Node conc1 = t_yz.eqNode( mkConcat( sk_y, sk_z ) );
- // s1 * ... * sk = z * y * r
- vec_r.insert(vec_r.begin(), sk_y);
- vec_r.insert(vec_r.begin(), sk_z);
- Node conc2 = s_zy.eqNode( mkConcat( vec_r ) );
- Node conc3 = normal_forms[other_n_index][other_index].eqNode( mkConcat( sk_y, sk_w ) );
- Node restr = r == d_emptyString ? s_zy : mkConcat( sk_z, sk_y );
- str_in_re = NodeManager::currentNM()->mkNode( kind::STRING_IN_REGEXP, sk_w,
- NodeManager::currentNM()->mkNode( kind::REGEXP_STAR,
- NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP, restr ) ) );
-
- std::vector< Node > vec_conc;
- vec_conc.push_back(conc1); vec_conc.push_back(conc2); vec_conc.push_back(conc3);
- vec_conc.push_back(str_in_re);
- //vec_conc.push_back(sk_y.eqNode(d_emptyString).negate());//by mkskolems
- conc = NodeManager::currentNM()->mkNode( kind::AND, vec_conc );
- } // normal case
-
- //set its antecedant to ant, to say when it is relevant
- if(!str_in_re.isNull()) {
- d_regexp_ant[str_in_re] = ant;
+ Trace("strings-loop") << "Strings::Loop: loop lemma for " << ant << " has already added." << std::endl;
+ addNormalFormPair( normal_form_src[i], normal_form_src[j] );
+ return false;
}
-
- sendLemma( ant, conc, "F-LOOP" );
- ++(d_statistics.d_loop_lemmas);
-
- //we will be done
- addNormalFormPair( normal_form_src[i], normal_form_src[j] );
- } else {
- Trace("strings-loop") << "Strings::Loop: loop lemma for " << ant << " has already added." << std::endl;
- addNormalFormPair( normal_form_src[i], normal_form_src[j] );
- return false;
}
+ return true;
}
return true;
}
@@ -2437,7 +2523,7 @@ bool TheoryStrings::processDeq( Node ni, Node nj ) {
Node lsk2 = mkLength( sk2 );
conc.push_back( lsk2.eqNode( lj ) );
conc.push_back( NodeManager::currentNM()->mkNode( kind::OR, j.eqNode( mkConcat( sk1, sk3 ) ), i.eqNode( mkConcat( sk2, sk3 ) ) ) );
- sendLemma( mkExplain( antec, antec_new_lits ), NodeManager::currentNM()->mkNode( kind::AND, conc ), "D-DISL-Split" );
+ sendInference( antec, antec_new_lits, NodeManager::currentNM()->mkNode( kind::AND, conc ), "D-DISL-Split" );
++(d_statistics.d_deq_splits);
return true;
}else if( areEqual( li, lj ) ){
@@ -2498,8 +2584,7 @@ int TheoryStrings::processSimpleDeq( std::vector< Node >& nfi, std::vector< Node
}
Node conc = cc.size()==1 ? cc[0] : NodeManager::currentNM()->mkNode( kind::AND, cc );
conc = Rewriter::rewrite( conc );
- sendLemma(mkExplain( ant ), conc, "Disequality Normalize Empty");
- //sendInfer(mkAnd( ant ), conc, "Disequality Normalize Empty");
+ sendInference( ant, conc, "Disequality Normalize Empty", true);
return -1;
} else {
Node i = nfi[index];
@@ -2663,6 +2748,49 @@ void TheoryStrings::registerTerm( Node n, int effort ) {
}
}
+void TheoryStrings::sendInference( std::vector< Node >& exp, std::vector< Node >& exp_n, Node eq, const char * c, bool asLemma ) {
+ eq = eq.isNull() ? d_false : Rewriter::rewrite( eq );
+ if( eq!=d_true ){
+ if( Trace.isOn("strings-infer-debug") ){
+ Trace("strings-infer-debug") << "infer : " << eq << " from: " << std::endl;
+ for( unsigned i=0; i<exp.size(); i++ ){
+ Trace("strings-infer-debug") << " " << exp[i] << std::endl;
+ }
+ for( unsigned i=0; i<exp_n.size(); i++ ){
+ Trace("strings-infer-debug") << " N:" << exp_n[i] << std::endl;
+ }
+ //Trace("strings-infer-debug") << "as lemma : " << asLemma << std::endl;
+ }
+ bool doSendLemma = ( asLemma || eq==d_false || eq.getKind()==kind::OR || options::stringInferAsLemmas() );
+ if( doSendLemma ){
+ Node eq_exp;
+ if( options::stringRExplainLemmas() ){
+ eq_exp = mkExplain( exp, exp_n );
+ }else{
+ if( exp.empty() ){
+ eq_exp = mkAnd( exp_n );
+ }else if( exp_n.empty() ){
+ eq_exp = mkAnd( exp );
+ }else{
+ std::vector< Node > ev;
+ ev.insert( ev.end(), exp.begin(), exp.end() );
+ ev.insert( ev.end(), exp_n.begin(), exp_n.end() );
+ eq_exp = NodeManager::currentNM()->mkNode( kind::AND, ev );
+ }
+ }
+ sendLemma( eq_exp, eq, c );
+ }else{
+ Assert( exp_n.empty() );
+ sendInfer( mkAnd( exp ), eq, c );
+ }
+ }
+}
+
+void TheoryStrings::sendInference( std::vector< Node >& exp, Node eq, const char * c, bool asLemma ) {
+ std::vector< Node > exp_n;
+ sendInference( exp, exp_n, eq, c, asLemma );
+}
+
void TheoryStrings::sendLemma( Node ant, Node conc, const char * c ) {
if( conc.isNull() || conc == d_false ) {
d_out->conflict(ant);
@@ -2684,38 +2812,33 @@ void TheoryStrings::sendLemma( Node ant, Node conc, const char * c ) {
}
void TheoryStrings::sendInfer( Node eq_exp, Node eq, const char * c ) {
- Trace("strings-infer-debug") << "infer : " << eq << " from " << eq_exp << std::endl;
- eq = Rewriter::rewrite( eq );
- if( eq==d_false || eq.getKind()==kind::OR ) {
- sendLemma( eq_exp, eq, c );
- }else if( eq!=d_true ){
- if( options::stringInferSym() ){
- std::vector< Node > vars;
- std::vector< Node > subs;
- std::vector< Node > unproc;
- inferSubstitutionProxyVars( eq_exp, vars, subs, unproc );
- if( unproc.empty() ){
- Trace("strings-lemma-debug") << "Strings::Infer " << eq << " from " << eq_exp << " by " << c << std::endl;
- Node eqs = eq.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
- Trace("strings-lemma-debug") << "Strings::Infer Alternate : " << eqs << std::endl;
- for( unsigned i=0; i<vars.size(); i++ ){
- Trace("strings-lemma-debug") << " " << vars[i] << " -> " << subs[i] << std::endl;
- }
- sendLemma( d_true, eqs, c );
- return;
- }else{
- for( unsigned i=0; i<unproc.size(); i++ ){
- Trace("strings-lemma-debug") << " non-trivial exp : " << unproc[i] << std::endl;
- }
+ if( options::stringInferSym() ){
+ std::vector< Node > vars;
+ std::vector< Node > subs;
+ std::vector< Node > unproc;
+ inferSubstitutionProxyVars( eq_exp, vars, subs, unproc );
+ if( unproc.empty() ){
+ Trace("strings-lemma-debug") << "Strings::Infer " << eq << " from " << eq_exp << " by " << c << std::endl;
+ Node eqs = eq.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
+ Trace("strings-lemma-debug") << "Strings::Infer Alternate : " << eqs << std::endl;
+ for( unsigned i=0; i<vars.size(); i++ ){
+ Trace("strings-lemma-debug") << " " << vars[i] << " -> " << subs[i] << std::endl;
+ }
+ sendLemma( d_true, eqs, c );
+ return;
+ }else{
+ for( unsigned i=0; i<unproc.size(); i++ ){
+ Trace("strings-lemma-debug") << " non-trivial exp : " << unproc[i] << std::endl;
}
}
- Trace("strings-lemma") << "Strings::Infer " << eq << " from " << eq_exp << " by " << c << std::endl;
- Trace("strings-assert") << "(assert (=> " << eq_exp << " " << eq << ")) ; infer " << c << std::endl;
- d_pending.push_back( eq );
- d_pending_exp[eq] = eq_exp;
- d_infer.push_back( eq );
- d_infer_exp.push_back( eq_exp );
}
+ Trace("strings-lemma") << "Strings::Infer " << eq << " from " << eq_exp << " by " << c << std::endl;
+ Trace("strings-assert") << "(assert (=> " << eq_exp << " " << eq << ")) ; infer " << c << std::endl;
+ d_pending.push_back( eq );
+ d_pending_exp[eq] = eq_exp;
+ d_infer.push_back( eq );
+ d_infer_exp.push_back( eq_exp );
+
}
void TheoryStrings::sendSplit( Node a, Node b, const char * c, bool preq ) {
@@ -2993,7 +3116,7 @@ void TheoryStrings::checkLengthsEqc() {
Node eq = llt.eqNode( lc );
if( llt!=lc ){
ei->d_normalized_length.set( eq );
- sendLemma( mkExplain( ant ), eq, "LEN-NORM" );
+ sendInference( ant, eq, "LEN-NORM", true );
}
}
}else{
@@ -3009,7 +3132,7 @@ void TheoryStrings::checkLengthsEqc() {
Assert( d_proxy_var_to_length.find( pv )!=d_proxy_var_to_length.end() );
Node pvl = d_proxy_var_to_length[pv];
Node ceq = Rewriter::rewrite( mkLength( pv ).eqNode( pvl ) );
- sendLemma( d_true, ceq, "LEN-NORM-I" );
+ sendInference( d_empty_vec, ceq, "LEN-NORM-I", true );
}
}
*/
@@ -3075,13 +3198,12 @@ void TheoryStrings::checkCardinality() {
vec_node.push_back( len_eq_lr );
}
}
- Node antc = NodeManager::currentNM()->mkNode( kind::AND, vec_node );
Node len = NodeManager::currentNM()->mkNode( kind::STRING_LENGTH, cols[i][0] );
Node cons = NodeManager::currentNM()->mkNode( kind::GEQ, len, k_node );
cons = Rewriter::rewrite( cons );
ei->d_cardinality_lem_k.set( int_k+1 );
if( cons!=d_true ){
- sendLemma( antc, cons, "CARDINALITY" );
+ sendInference( d_empty_vec, vec_node, cons, "CARDINALITY", true );
return;
}
}
@@ -3344,9 +3466,8 @@ bool TheoryStrings::normalizePosMemberships(std::map< Node, std::vector< Node >
inter_r = d_regexp_opr.intersect(inter_r, inter_r2, spflag);
if(inter_r == d_emptyRegexp) {
//conflict
- Node antec = exp.size() == 1? exp[0] : NodeManager::currentNM()->mkNode(kind::AND, exp);
Node conc;
- sendLemma(antec, conc, "INTERSECT CONFLICT");
+ sendInference( d_empty_vec, exp, conc, "INTERSECT CONFLICT", true );
addLemma = true;
break;
}
@@ -3417,17 +3538,15 @@ bool TheoryStrings::applyRLen(std::map< Node, std::vector< Node > > &XinR_with_e
bool TheoryStrings::checkMembershipsWithoutLength(
std::map< Node, std::vector< Node > > &memb_with_exps,
std::map< Node, std::vector< Node > > &XinR_with_exps) {
- for(std::map< Node, std::vector< Node > >::const_iterator itr = memb_with_exps.begin();
- itr != memb_with_exps.end(); ++itr) {
+ for(std::map< Node, std::vector< Node > >::iterator itr = memb_with_exps.begin(); itr != memb_with_exps.end(); ++itr) {
Node memb = itr->first;
Node s = memb[0];
Node r = memb[1];
if(s.isConst()) {
memb = Rewriter::rewrite( memb );
if(memb == d_false) {
- Node antec = itr->second.size() == 1? itr->second[0] : NodeManager::currentNM()->mkNode(kind::AND, itr->second);
Node conc;
- sendLemma(antec, conc, "MEMBERSHIP CONFLICT");
+ sendInference(d_empty_vec, itr->second, conc, "MEMBERSHIP CONFLICT", true);
//addLemma = true;
return true;
} else {
@@ -3438,14 +3557,13 @@ bool TheoryStrings::checkMembershipsWithoutLength(
XinR_with_exps[itr->first] = itr->second;
} else {
Assert(s.getKind() == kind::STRING_CONCAT);
- Node antec = itr->second.size() == 1? itr->second[0] : NodeManager::currentNM()->mkNode(kind::AND, itr->second);
Node conc;
for( unsigned i=0; i<s.getNumChildren(); i++ ) {
if(s[i].isConst()) {
CVC4::String str( s[0].getConst< String >() );
//R-Consume, see Tianyi's thesis
if(!applyRConsume(str, r)) {
- sendLemma(antec, conc, "R-Consume CONFLICT");
+ sendInference(d_empty_vec, itr->second, conc, "R-Consume CONFLICT", true);
//addLemma = true;
return true;
}
@@ -3467,11 +3585,11 @@ bool TheoryStrings::checkMembershipsWithoutLength(
break;
} else if(conc.isNull() || conc == d_false) {
conc = Node::null();
- sendLemma(antec, conc, "R-Split Conflict");
+ sendInference(d_empty_vec, itr->second, conc, "R-Split Conflict", true);
//addLemma = true;
return true;
} else {
- sendLemma(antec, conc, "R-Split");
+ sendInference(d_empty_vec, itr->second, conc, "R-Split", true);
//addLemma = true;
return true;
}
@@ -3569,9 +3687,8 @@ void TheoryStrings::checkMemberships() {
Node n = NodeManager::currentNM()->mkNode(kind::STRING_IN_REGEXP, x, *itr2);
vec_nodes.push_back( n );
}
- Node antec = vec_nodes.size() == 1? vec_nodes[0] : NodeManager::currentNM()->mkNode(kind::AND, vec_nodes);
Node conc;
- sendLemma(antec, conc, "INTERSECT CONFLICT");
+ sendInference(vec_nodes, conc, "INTERSECT CONFLICT", true);
addedLemma = true;
break;
}
@@ -3661,9 +3778,6 @@ void TheoryStrings::checkMemberships() {
} else {
processed.push_back( assertion );
}
- } else if(conc == d_false) {
- conc = Node::null();
- sendLemma(antec, conc, "RegExp CST-SP Conflict");
} else {
sendLemma(antec, conc, "RegExp-CST-SP");
}
@@ -3712,8 +3826,7 @@ void TheoryStrings::checkMemberships() {
}
}
antec = Rewriter::rewrite( NodeManager::currentNM()->mkNode(kind::AND, antec, mkExplain(rnfexp)) );
- Node conc = nvec.size()==1 ? nvec[0] :
- NodeManager::currentNM()->mkNode(kind::AND, nvec);
+ Node conc = nvec.size()==1 ? nvec[0] : NodeManager::currentNM()->mkNode(kind::AND, nvec);
conc = Rewriter::rewrite(conc);
sendLemma( antec, conc, "REGEXP" );
addedLemma = true;
@@ -3946,7 +4059,7 @@ void TheoryStrings::checkConstantEquivalenceClasses( TermIndex* ti, std::vector<
//exp contains an explanation of n==c
Assert( countc==vecc.size() );
if( hasTerm( c ) ){
- sendInfer( mkAnd( exp ), n.eqNode( c ), "I_CONST_MERGE" );
+ sendInference( exp, n.eqNode( c ), "I_CONST_MERGE" );
return;
}else if( !hasProcessed() ){
Node nr = getRepresentative( n );
@@ -3967,7 +4080,7 @@ void TheoryStrings::checkConstantEquivalenceClasses( TermIndex* ti, std::vector<
exp.push_back( d_eqc_to_const_exp[nr] );
addToExplanation( n, d_eqc_to_const_base[nr], exp );
}
- sendLemma( mkExplain( exp ), d_false, "I_CONST_CONFLICT" );
+ sendInference( exp, d_false, "I_CONST_CONFLICT" );
return;
}else{
Trace("strings-debug") << "Duplicate constant." << std::endl;
@@ -4053,7 +4166,7 @@ void TheoryStrings::checkNegContains( std::vector< Node >& negContains ) {
lexp.push_back( atom.negate() );
Node xneqs = x.eqNode(s).negate();
d_neg_ctn_eqlen.insert( atom );
- sendLemma( mkExplain( lexp ), xneqs, "NEG-CTN-EQL" );
+ sendInference( lexp, xneqs, "NEG-CTN-EQL", true );
}
}else if( !areDisequal( lenx, lens ) ){
if(d_neg_ctn_ulen.find(atom) == d_neg_ctn_ulen.end()) {
@@ -4093,7 +4206,9 @@ void TheoryStrings::checkNegContains( std::vector< Node >& negContains ) {
conc = Rewriter::rewrite( NodeManager::currentNM()->mkNode( kind::OR, xlss, conc ) );
d_neg_ctn_cached.insert( atom );
- sendLemma( atom.negate(), conc, "NEG-CTN-BRK" );
+ std::vector< Node > exp;
+ exp.push_back( atom.negate() );
+ sendInference( d_empty_vec, exp, conc, "NEG-CTN-BRK", true );
//d_pending_req_phase[xlss] = true;
}
}
diff --git a/src/theory/strings/theory_strings.h b/src/theory/strings/theory_strings.h
index fef2983fd..b9da524de 100644
--- a/src/theory/strings/theory_strings.h
+++ b/src/theory/strings/theory_strings.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Martin Brain <>, Morgan Deters
+ ** Top contributors (to current version):
+ ** Tianyi Liang, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory of strings
**
@@ -158,6 +158,7 @@ private:
std::map< Node, Node > d_normal_forms_base;
std::map< Node, std::vector< Node > > d_normal_forms;
std::map< Node, std::vector< Node > > d_normal_forms_exp;
+ std::map< Node, std::map< Node, std::map< bool, int > > > d_normal_forms_exp_depend;
//map of pairs of terms that have the same normal form
NodeListMap d_nf_pairs;
void addNormalFormPair( Node n1, Node n2 );
@@ -174,7 +175,7 @@ private:
NodeBoolMap d_preproc_cache;
// extended functions inferences cache
NodeSet d_extf_infer_cache;
-
+ std::vector< Node > d_empty_vec;
private:
NodeSet d_congruent;
std::map< Node, Node > d_eqc_to_const;
@@ -236,7 +237,6 @@ private:
NodeNodeMap d_proxy_var;
NodeNodeMap d_proxy_var_to_length;
private:
-
//initial check
void checkInit();
void checkConstantEquivalenceClasses( TermIndex* ti, std::vector< Node >& vecc );
@@ -254,30 +254,31 @@ private:
//normal forms check
void checkNormalForms();
bool normalizeEquivalenceClass( Node n, std::vector< Node > & nf, std::vector< Node > & nf_exp );
- bool getNormalForms( Node &eqc, std::vector< Node > & nf,
- std::vector< std::vector< Node > > &normal_forms,
- std::vector< std::vector< Node > > &normal_forms_exp,
- std::vector< Node > &normal_form_src);
+ bool getNormalForms( Node &eqc, std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend);
bool detectLoop(std::vector< std::vector< Node > > &normal_forms,
- int i, int j, int index_i, int index_j,
- int &loop_in_i, int &loop_in_j);
+ int i, int j, int index, int &loop_in_i, int &loop_in_j);
bool processLoop(std::vector< Node > &antec,
std::vector< std::vector< Node > > &normal_forms,
std::vector< Node > &normal_form_src,
int i, int j, int loop_n_index, int other_n_index,
- int loop_index, int index, int other_index);
- bool processNEqc(std::vector< std::vector< Node > > &normal_forms,
- std::vector< std::vector< Node > > &normal_forms_exp,
- std::vector< Node > &normal_form_src);
- bool processReverseNEq(std::vector< std::vector< Node > > &normal_forms,
- std::vector< Node > &normal_form_src, std::vector< Node > &curr_exp, unsigned i, unsigned j );
- bool processSimpleNEq( std::vector< std::vector< Node > > &normal_forms,
- std::vector< Node > &normal_form_src, std::vector< Node > &curr_exp, unsigned i, unsigned j,
- unsigned& index_i, unsigned& index_j, bool isRev );
+ int loop_index, int index);
+ bool processNEqc( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend );
+ bool processReverseNEq( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend,
+ unsigned i, unsigned j );
+ bool processSimpleNEq( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend,
+ unsigned i, unsigned j, unsigned& index, bool isRev );
bool processDeq( Node n1, Node n2 );
int processReverseDeq( std::vector< Node >& nfi, std::vector< Node >& nfj, Node ni, Node nj );
int processSimpleDeq( std::vector< Node >& nfi, std::vector< Node >& nfj, Node ni, Node nj, unsigned& index, bool isRev );
void checkDeqNF();
+
+ void getExplanationVectorForPrefix( std::vector< std::vector< Node > > &normal_forms, std::vector< Node > &normal_form_src,
+ std::vector< std::vector< Node > > &normal_forms_exp, std::vector< std::map< Node, std::map< bool, int > > >& normal_forms_exp_depend,
+ unsigned i, unsigned j, int index, bool isRev, std::vector< Node >& curr_exp );
//check for extended functions
void checkExtendedFuncs();
@@ -337,6 +338,8 @@ protected:
//register term
void registerTerm( Node n, int effort );
//send lemma
+ void sendInference( std::vector< Node >& exp, std::vector< Node >& exp_n, Node eq, const char * c, bool asLemma = false );
+ void sendInference( std::vector< Node >& exp, Node eq, const char * c, bool asLemma = false );
void sendLemma( Node ant, Node conc, const char * c );
void sendInfer( Node eq_exp, Node eq, const char * c );
void sendSplit( Node a, Node b, const char * c, bool preq = true );
diff --git a/src/theory/strings/theory_strings_preprocess.cpp b/src/theory/strings/theory_strings_preprocess.cpp
index a1c93a369..a4f42bddd 100644
--- a/src/theory/strings/theory_strings_preprocess.cpp
+++ b/src/theory/strings/theory_strings_preprocess.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings_preprocess.cpp
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Tianyi Liang, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Strings Preprocess
**
diff --git a/src/theory/strings/theory_strings_preprocess.h b/src/theory/strings/theory_strings_preprocess.h
index 08805fddc..5bc9667ea 100644
--- a/src/theory/strings/theory_strings_preprocess.h
+++ b/src/theory/strings/theory_strings_preprocess.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings_preprocess.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Morgan Deters, Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Strings Preprocess
**
diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp
index 733471288..75243b84d 100644
--- a/src/theory/strings/theory_strings_rewriter.cpp
+++ b/src/theory/strings/theory_strings_rewriter.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings_rewriter.cpp
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tianyi Liang, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of the theory of strings.
**
diff --git a/src/theory/strings/theory_strings_rewriter.h b/src/theory/strings/theory_strings_rewriter.h
index f8b420904..59588eda2 100644
--- a/src/theory/strings/theory_strings_rewriter.h
+++ b/src/theory/strings/theory_strings_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings_rewriter.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tianyi Liang, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/strings/theory_strings_type_rules.h b/src/theory/strings/theory_strings_type_rules.h
index aff033338..eae993545 100644
--- a/src/theory/strings/theory_strings_type_rules.h
+++ b/src/theory/strings/theory_strings_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_strings_type_rules.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tianyi Liang, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Typing and cardinality rules for the theory of arrays
**
@@ -239,7 +239,7 @@ class RegExpConstantTypeRule {
public:
inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
throw (TypeCheckingExceptionPrivate, AssertionException) {
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -262,7 +262,7 @@ public:
throw TypeCheckingExceptionPrivate(n, "expecting at least 2 terms in regexp concat");
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -280,7 +280,7 @@ public:
}
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -298,7 +298,7 @@ public:
}
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -312,7 +312,7 @@ public:
throw TypeCheckingExceptionPrivate(n, "expecting regexp terms");
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -326,7 +326,7 @@ public:
throw TypeCheckingExceptionPrivate(n, "expecting regexp terms");
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -340,7 +340,7 @@ public:
throw TypeCheckingExceptionPrivate(n, "expecting regexp terms");
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -373,7 +373,7 @@ public:
throw TypeCheckingExceptionPrivate(n, "expecting standard ASCII characters in regexp range, or please set the option strings-std-ascii to be false");
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -409,7 +409,7 @@ public:
//}
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -426,7 +426,7 @@ public:
// throw TypeCheckingExceptionPrivate(n, "expecting constant string terms");
//}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -456,7 +456,7 @@ public:
throw (TypeCheckingExceptionPrivate, AssertionException) {
Assert(n.getKind() == kind::REGEXP_EMPTY);
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -466,7 +466,7 @@ public:
throw (TypeCheckingExceptionPrivate, AssertionException) {
Assert(n.getKind() == kind::REGEXP_SIGMA);
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
@@ -480,7 +480,7 @@ public:
throw TypeCheckingExceptionPrivate(n, "expecting an integer term in RV");
}
}
- return nodeManager->regexpType();
+ return nodeManager->regExpType();
}
};
diff --git a/src/theory/strings/type_enumerator.h b/src/theory/strings/type_enumerator.h
index bdaa683c1..1fe3d79f6 100644
--- a/src/theory/strings/type_enumerator.h
+++ b/src/theory/strings/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Tianyi Liang, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Enumerators for strings
**
diff --git a/src/theory/substitutions.cpp b/src/theory/substitutions.cpp
index af517dcf3..7dbfb2678 100644
--- a/src/theory/substitutions.cpp
+++ b/src/theory/substitutions.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file substitutions.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters, Clark Barrett
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Clark Barrett, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A substitution mapping for theory simplification
**
diff --git a/src/theory/substitutions.h b/src/theory/substitutions.h
index a4fd490c2..019fbd17e 100644
--- a/src/theory/substitutions.h
+++ b/src/theory/substitutions.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file substitutions.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett, Dejan Jovanovic
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A substitution mapping for theory simplification
**
diff --git a/src/theory/term_registration_visitor.cpp b/src/theory/term_registration_visitor.cpp
index 2aa00a177..830e7f809 100644
--- a/src/theory/term_registration_visitor.cpp
+++ b/src/theory/term_registration_visitor.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file term_registration_visitor.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Tim King, Clark Barrett, Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Andrew Reynolds, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/term_registration_visitor.h b/src/theory/term_registration_visitor.h
index a14b7a1ba..6d04910f6 100644
--- a/src/theory/term_registration_visitor.h
+++ b/src/theory/term_registration_visitor.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file term_registration_visitor.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** [[ Add lengthier description here ]]
** \todo document this file
diff --git a/src/theory/theory.cpp b/src/theory/theory.cpp
index ee5efc8db..7e2b6df55 100644
--- a/src/theory/theory.cpp
+++ b/src/theory/theory.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Clark Barrett, Dejan Jovanovic, Tim King
- ** Minor contributors (to current version): Kshitij Bansal, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Tim King, Dejan Jovanovic, Clark Barrett
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Base for theory interface.
**
@@ -231,7 +231,7 @@ void Theory::collectTerms(TNode n, set<Node>& termSet) const
}
-void Theory::computeRelevantTerms(set<Node>& termSet) const
+void Theory::computeRelevantTerms(set<Node>& termSet, bool includeShared) const
{
// Collect all terms appearing in assertions
context::CDList<Assertion>::const_iterator assert_it = facts_begin(), assert_it_end = facts_end();
@@ -239,6 +239,8 @@ void Theory::computeRelevantTerms(set<Node>& termSet) const
collectTerms(*assert_it, termSet);
}
+ if (!includeShared) return;
+
// Add terms that are shared terms
context::CDList<TNode>::const_iterator shared_it = shared_terms_begin(), shared_it_end = shared_terms_end();
for (; shared_it != shared_it_end; ++shared_it) {
diff --git a/src/theory/theory.h b/src/theory/theory.h
index c988c9120..382d4cf65 100644
--- a/src/theory/theory.h
+++ b/src/theory/theory.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King, Dejan Jovanovic
- ** Minor contributors (to current version): Francois Bobot, Kshitij Bansal, Martin Brain <>, Clark Barrett, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Base of the theory interface.
**
@@ -237,7 +237,7 @@ protected:
* termSet. This is used by collectModelInfo to delimit the set of
* terms that should be used when constructing a model
*/
- void computeRelevantTerms(std::set<Node>& termSet) const;
+ void computeRelevantTerms(std::set<Node>& termSet, bool includeShared = true) const;
/**
* Construct a Theory.
@@ -277,7 +277,7 @@ protected:
*
*/
bool d_proofsEnabled;
-
+
/**
* Returns the next assertion in the assertFact() queue.
*
diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp
index 45f7506de..f2231ff7a 100644
--- a/src/theory/theory_engine.cpp
+++ b/src/theory/theory_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_engine.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Christopher L. Conway, Tianyi Liang, Kshitij Bansal, Clark Barrett, Liana Hadarean, Andrew Reynolds, Tim King
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The theory engine
**
@@ -78,24 +78,26 @@ void TheoryEngine::finishInit() {
}
void TheoryEngine::eqNotifyNewClass(TNode t){
- if( d_logicInfo.isQuantified() ){
- d_quantEngine->addTermToDatabase( t );
+ if (d_logicInfo.isQuantified()) {
+ d_quantEngine->eqNotifyNewClass( t );
}
}
void TheoryEngine::eqNotifyPreMerge(TNode t1, TNode t2){
-
+ if (d_logicInfo.isQuantified()) {
+ d_quantEngine->eqNotifyPreMerge( t1, t2 );
+ }
}
void TheoryEngine::eqNotifyPostMerge(TNode t1, TNode t2){
-
+ if (d_logicInfo.isQuantified()) {
+ d_quantEngine->eqNotifyPostMerge( t1, t2 );
+ }
}
void TheoryEngine::eqNotifyDisequal(TNode t1, TNode t2, TNode reason){
- if( d_logicInfo.isQuantified() ){
- if( options::quantConflictFind() ){
- d_quantEngine->getConflictFind()->assertDisequal( t1, t2 );
- }
+ if (d_logicInfo.isQuantified()) {
+ d_quantEngine->eqNotifyDisequal( t1, t2, reason );
}
}
@@ -198,6 +200,7 @@ void TheoryEngine::interrupt() throw(ModalException) {
void TheoryEngine::preRegister(TNode preprocessed) {
+ Debug("theory") << "TheoryEngine::preRegister( " << preprocessed << ")" << std::endl;
if(Dump.isOn("missed-t-propagations")) {
d_possiblePropagations.push_back(preprocessed);
}
@@ -344,6 +347,7 @@ void TheoryEngine::check(Theory::Effort effort) {
if (theory::TheoryTraits<THEORY>::hasCheck && d_logicInfo.isTheoryEnabled(THEORY)) { \
theoryOf(THEORY)->check(effort); \
if (d_inConflict) { \
+ Debug("conflict") << THEORY << " in conflict. " << std::endl; \
break; \
} \
}
@@ -404,6 +408,9 @@ void TheoryEngine::check(Theory::Effort effort) {
// Do the combination
Debug("theory") << "TheoryEngine::check(" << effort << "): running combination" << endl;
combineTheories();
+ if(d_logicInfo.isQuantified()){
+ d_quantEngine->notifyCombineTheories();
+ }
}
}
@@ -418,14 +425,14 @@ void TheoryEngine::check(Theory::Effort effort) {
// must build model at this point
d_curr_model_builder->buildModel(d_curr_model, true);
}
- Trace("theory::assertions-model") << endl;
+ Trace("theory::assertions-model") << endl;
if (Trace.isOn("theory::assertions-model")) {
printAssertions("theory::assertions-model");
}
}
Debug("theory") << "TheoryEngine::check(" << effort << "): done, we are " << (d_inConflict ? "unsat" : "sat") << (d_lemmasAdded ? " with new lemmas" : " with no new lemmas");
- Debug("theory") << ", need check = " << needCheck() << endl;
+ Debug("theory") << ", need check = " << (needCheck() ? "YES" : "NO") << endl;
if(!d_inConflict && Theory::fullEffort(effort) && d_masterEqualityEngine != NULL && !d_lemmasAdded) {
AlwaysAssert(d_masterEqualityEngine->consistent());
@@ -490,7 +497,7 @@ void TheoryEngine::combineTheories() {
// We need to split on it
Debug("combineTheories") << "TheoryEngine::combineTheories(): requesting a split " << endl;
- lemma(equality.orNode(equality.notNode()), RULE_INVALID, false, false, false, carePair.theory);
+ lemma(equality.orNode(equality.notNode()), RULE_INVALID, false, false, false, carePair.theory, carePair.theory);
// This code is supposed to force preference to follow what the theory models already have
// but it doesn't seem to make a big difference - need to explore more -Clark
// if (true) {
@@ -1212,6 +1219,8 @@ Node TheoryEngine::ensureLiteral(TNode n) {
void TheoryEngine::printInstantiations( std::ostream& out ) {
if( d_quantEngine ){
d_quantEngine->printInstantiations( out );
+ }else{
+ out << "Internal error : instantiations not available when quantifiers are not present." << std::endl;
}
}
@@ -1223,6 +1232,15 @@ void TheoryEngine::printSynthSolution( std::ostream& out ) {
}
}
+void TheoryEngine::getInstantiations( std::map< Node, std::vector< Node > >& insts ) {
+ if( d_quantEngine ){
+ d_quantEngine->getInstantiations( insts );
+ }else{
+ Assert( false );
+ }
+}
+
+
static Node mkExplanation(const std::vector<NodeTheoryPair>& explanation) {
std::set<TNode> all;
@@ -1252,8 +1270,7 @@ static Node mkExplanation(const std::vector<NodeTheoryPair>& explanation) {
return conjunction;
}
-
-Node TheoryEngine::getExplanation(TNode node) {
+NodeTheoryPair TheoryEngine::getExplanationAndExplainer(TNode node) {
Debug("theory::explain") << "TheoryEngine::getExplanation(" << node << "): current propagation index = " << d_propagationMapTimestamp << endl;
bool polarity = node.getKind() != kind::NOT;
@@ -1263,12 +1280,16 @@ Node TheoryEngine::getExplanation(TNode node) {
if (!d_logicInfo.isSharingEnabled()) {
Node explanation = theoryOf(atom)->explain(node);
Debug("theory::explain") << "TheoryEngine::getExplanation(" << node << ") => " << explanation << endl;
- return explanation;
+ return NodeTheoryPair(explanation, theoryOf(atom)->getId());
}
// Initial thing to explain
NodeTheoryPair toExplain(node, THEORY_SAT_SOLVER, d_propagationMapTimestamp);
Assert(d_propagationMap.find(toExplain) != d_propagationMap.end());
+
+ NodeTheoryPair nodeExplainerPair = d_propagationMap[toExplain];
+ TheoryId explainer = nodeExplainerPair.theory;
+
// Create the workplace for explanations
std::vector<NodeTheoryPair> explanationVector;
explanationVector.push_back(d_propagationMap[toExplain]);
@@ -1278,7 +1299,11 @@ Node TheoryEngine::getExplanation(TNode node) {
Debug("theory::explain") << "TheoryEngine::getExplanation(" << node << ") => " << explanation << endl;
- return explanation;
+ return NodeTheoryPair(explanation, explainer);
+}
+
+Node TheoryEngine::getExplanation(TNode node) {
+ return getExplanationAndExplainer(node).node;
}
struct AtomsCollect {
@@ -1380,7 +1405,8 @@ theory::LemmaStatus TheoryEngine::lemma(TNode node,
bool negated,
bool removable,
bool preprocess,
- theory::TheoryId atomsTo) {
+ theory::TheoryId atomsTo,
+ theory::TheoryId ownerTheory) {
// For resource-limiting (also does a time check).
// spendResource();
@@ -1406,12 +1432,13 @@ theory::LemmaStatus TheoryEngine::lemma(TNode node,
d_channels->getLemmaOutputChannel()->notifyNewLemma(node.toExpr());
}
+ std::vector<Node> additionalLemmas;
+ IteSkolemMap iteSkolemMap;
+
// Run theory preprocessing, maybe
Node ppNode = preprocess ? this->preprocess(node) : Node(node);
// Remove the ITEs
- std::vector<Node> additionalLemmas;
- IteSkolemMap iteSkolemMap;
additionalLemmas.push_back(ppNode);
d_iteRemover.run(additionalLemmas, iteSkolemMap);
additionalLemmas[0] = theory::Rewriter::rewrite(additionalLemmas[0]);
@@ -1429,10 +1456,10 @@ theory::LemmaStatus TheoryEngine::lemma(TNode node,
}
// assert to prop engine
- d_propEngine->assertLemma(additionalLemmas[0], negated, removable, rule, node);
+ d_propEngine->assertLemma(additionalLemmas[0], negated, removable, rule, ownerTheory, node);
for (unsigned i = 1; i < additionalLemmas.size(); ++ i) {
additionalLemmas[i] = theory::Rewriter::rewrite(additionalLemmas[i]);
- d_propEngine->assertLemma(additionalLemmas[i], false, removable, rule, node);
+ d_propEngine->assertLemma(additionalLemmas[i], false, removable, rule, ownerTheory, node);
}
// WARNING: Below this point don't assume additionalLemmas[0] to be not negated.
@@ -1476,11 +1503,11 @@ void TheoryEngine::conflict(TNode conflict, TheoryId theoryId) {
Node fullConflict = mkExplanation(explanationVector);
Debug("theory::conflict") << "TheoryEngine::conflict(" << conflict << ", " << theoryId << "): full = " << fullConflict << endl;
Assert(properConflict(fullConflict));
- lemma(fullConflict, RULE_CONFLICT, true, true, false, THEORY_LAST);
+ lemma(fullConflict, RULE_CONFLICT, true, true, false, THEORY_LAST, theoryId);
} else {
// When only one theory, the conflict should need no processing
Assert(properConflict(conflict));
- lemma(conflict, RULE_CONFLICT, true, true, false, THEORY_LAST);
+ lemma(conflict, RULE_CONFLICT, true, true, false, THEORY_LAST, theoryId);
}
}
@@ -1718,7 +1745,7 @@ void TheoryEngine::ppUnconstrainedSimp(vector<Node>& assertions)
}
-void TheoryEngine::setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value) {
+void TheoryEngine::setUserAttribute(const std::string& attr, Node n, std::vector<Node>& node_values, std::string str_value) {
Trace("te-attr") << "set user attribute " << attr << " " << n << endl;
if( d_attr_handle.find( attr )!=d_attr_handle.end() ){
for( size_t i=0; i<d_attr_handle[attr].size(); i++ ){
diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h
index 886aa6863..db94edd7c 100644
--- a/src/theory/theory_engine.h
+++ b/src/theory/theory_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_engine.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds, Dejan Jovanovic
- ** Minor contributors (to current version): Christopher L. Conway, Francois Bobot, Kshitij Bansal, Clark Barrett, Liana Hadarean, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief The theory engine
**
@@ -59,7 +59,7 @@ struct NodeTheoryPair {
Node node;
theory::TheoryId theory;
size_t timestamp;
- NodeTheoryPair(TNode node, theory::TheoryId theory, size_t timestamp)
+ NodeTheoryPair(TNode node, theory::TheoryId theory, size_t timestamp = 0)
: node(node), theory(theory), timestamp(timestamp) {}
NodeTheoryPair()
: theory(theory::THEORY_LAST) {}
@@ -263,7 +263,7 @@ class TheoryEngine {
{
}
- void safePoint(uint64_t ammount) throw(theory::Interrupted, UnsafeInterruptException, AssertionException) {
+ void safePoint(uint64_t ammount) throw(theory::Interrupted, UnsafeInterruptException, AssertionException) {
spendResource(ammount);
if (d_engine->d_interrupted) {
throw theory::Interrupted();
@@ -294,14 +294,21 @@ class TheoryEngine {
Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
++ d_statistics.lemmas;
d_engine->d_outputChannelUsed = true;
- return d_engine->lemma(lemma, rule, false, removable, preprocess, sendAtoms ? d_theory: theory::THEORY_LAST);
+ return d_engine->lemma(lemma, rule, false, removable, preprocess, sendAtoms ? d_theory : theory::THEORY_LAST, d_theory);
}
+ /*theory::LemmaStatus preservedLemma(TNode lemma, bool removable = false, bool preprocess = false) throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException, LogicException) {
+ Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::preservedLemma(" << lemma << ")" << std::endl;
+ ++ d_statistics.lemmas;
+ d_engine->d_outputChannelUsed = true;
+ return d_engine->lemma(lemma, false, removable, preprocess, d_theory);
+ }*/
+
theory::LemmaStatus splitLemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
- Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
+ Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::splitLemma(" << lemma << ")" << std::endl;
++ d_statistics.lemmas;
d_engine->d_outputChannelUsed = true;
- return d_engine->lemma(lemma, RULE_SPLIT, false, removable, false, d_theory);
+ return d_engine->lemma(lemma, RULE_SPLIT, false, removable, false, d_theory, d_theory);
}
void demandRestart() throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
@@ -448,7 +455,8 @@ class TheoryEngine {
bool negated,
bool removable,
bool preprocess,
- theory::TheoryId atomsTo);
+ theory::TheoryId atomsTo,
+ theory::TheoryId ownerTheory);
/** Enusre that the given atoms are send to the given theory */
void ensureLemmaAtoms(const std::vector<TNode>& atoms, theory::TheoryId theory);
@@ -719,6 +727,12 @@ public:
Node getExplanation(TNode node);
/**
+ * Returns an explanation of the node propagated to the SAT solver and the theory
+ * that propagated it.
+ */
+ NodeTheoryPair getExplanationAndExplainer(TNode node);
+
+ /**
* collect model info
*/
void collectModelInfo( theory::TheoryModel* m, bool fullModel );
@@ -784,6 +798,11 @@ public:
void printSynthSolution( std::ostream& out );
/**
+ * Get instantiations
+ */
+ void getInstantiations( std::map< Node, std::vector< Node > >& insts );
+
+ /**
* Forwards an entailment check according to the given theoryOfMode.
* See theory.h for documentation on entailmentCheck().
*/
@@ -851,7 +870,7 @@ public:
* This function is called when an attribute is set by a user. In SMT-LIBv2 this is done
* via the syntax (! n :attr)
*/
- void setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value);
+ void setUserAttribute(const std::string& attr, Node n, std::vector<Node>& node_values, std::string str_value);
/**
* Handle user attribute.
diff --git a/src/theory/theory_model.cpp b/src/theory/theory_model.cpp
index 0eff9bd5d..fa7e497e2 100644
--- a/src/theory/theory_model.cpp
+++ b/src/theory/theory_model.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_model.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds, Clark Barrett
- ** Minor contributors (to current version): Kshitij Bansal, Liana Hadarean, Tim King
+ ** Top contributors (to current version):
+ ** Clark Barrett, Andrew Reynolds, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of model class
**/
@@ -631,7 +631,9 @@ void TheoryEngineModelBuilder::buildModel(Model* m, bool fullModel)
Trace("model-builder") << " Processing Term: " << n << endl;
// Record as rep if this node was specified as a representative
if (tm->d_reps.find(n) != tm->d_reps.end()){
- Assert(rep.isNull());
+ //AJR: I believe this assertion is too strict,
+ // e.g. datatypes may assert representative for two constructor terms that are not in the care graph and are merged during collectModelInfo.
+ //Assert(rep.isNull());
rep = tm->d_reps[n];
Assert(!rep.isNull() );
Trace("model-builder") << " Rep( " << eqc << " ) = " << rep << std::endl;
diff --git a/src/theory/theory_model.h b/src/theory/theory_model.h
index b0952538a..6e4f77336 100644
--- a/src/theory/theory_model.h
+++ b/src/theory/theory_model.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_model.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds, Clark Barrett
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Clark Barrett, Morgan Deters, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Model class
**/
diff --git a/src/theory/theory_registrar.h b/src/theory/theory_registrar.h
index d04251585..d0e3a5b0d 100644
--- a/src/theory/theory_registrar.h
+++ b/src/theory/theory_registrar.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_registrar.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: Morgan Deters, Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Class to encapsulate preregistration duties
**
diff --git a/src/theory/theory_test_utils.h b/src/theory/theory_test_utils.h
index 6247833f8..031c51d22 100644
--- a/src/theory/theory_test_utils.h
+++ b/src/theory/theory_test_utils.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_test_utils.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds, Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Common utilities for testing theories
**
diff --git a/src/theory/theory_traits_template.h b/src/theory/theory_traits_template.h
index b0e7010b7..0d2d0b8e2 100644
--- a/src/theory/theory_traits_template.h
+++ b/src/theory/theory_traits_template.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_traits_template.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A template for the theory_traits.h header, defining various
** (static) aspects of theories
diff --git a/src/theory/type_enumerator.h b/src/theory/type_enumerator.h
index 951967f50..d1318aaa8 100644
--- a/src/theory/type_enumerator.h
+++ b/src/theory/type_enumerator.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Enumerators for types
**
diff --git a/src/theory/type_enumerator_template.cpp b/src/theory/type_enumerator_template.cpp
index 6f9b565bf..2dfefa1a8 100644
--- a/src/theory/type_enumerator_template.cpp
+++ b/src/theory/type_enumerator_template.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file type_enumerator_template.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Enumerators for types
**
diff --git a/src/theory/uf/equality_engine.cpp b/src/theory/uf/equality_engine.cpp
index 0ac5096d2..9b429765e 100644
--- a/src/theory/uf/equality_engine.cpp
+++ b/src/theory/uf/equality_engine.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file equality_engine.cpp
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic, Tianyi Liang, Tim King, Francois Bobot, Morgan Deters, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Guy Katz, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -42,7 +42,6 @@ EqualityEngine::Statistics::~Statistics() {
smtStatisticsRegistry()->unregisterStat(&constantTermsCount);
}
-
/**
* Data used in the BFS search through the equality graph.
*/
@@ -94,6 +93,8 @@ void EqualityEngine::init() {
d_trueId = getNodeId(d_true);
d_falseId = getNodeId(d_false);
+
+ d_freshMergeReasonType = eq::NUMBER_OF_MERGE_REASONS;
}
EqualityEngine::~EqualityEngine() throw(AssertionException) {
@@ -157,7 +158,7 @@ void EqualityEngine::setMasterEqualityEngine(EqualityEngine* master) {
}
void EqualityEngine::enqueue(const MergeCandidate& candidate, bool back) {
- Debug("equality") << d_name << "::eq::enqueue(" << d_nodes[candidate.t1Id] << ", " << d_nodes[candidate.t2Id] << ", " << candidate.type << ")" << std::endl;
+ Debug("equality") << d_name << "::eq::enqueue(" << d_nodes[candidate.t1Id] << ", " << d_nodes[candidate.t2Id] << ", " << candidate.type << "). reason: " << candidate.reason << std::endl;
if (back) {
d_propagationQueue.push_back(candidate);
} else {
@@ -390,7 +391,7 @@ const EqualityNode& EqualityEngine::getEqualityNode(EqualityNodeId nodeId) const
return d_equalityNodes[nodeId];
}
-void EqualityEngine::assertEqualityInternal(TNode t1, TNode t2, TNode reason, MergeReasonType pid) {
+void EqualityEngine::assertEqualityInternal(TNode t1, TNode t2, TNode reason, unsigned pid) {
Debug("equality") << d_name << "::eq::addEqualityInternal(" << t1 << "," << t2 << "), pid = " << pid << std::endl;
@@ -408,7 +409,7 @@ void EqualityEngine::assertEqualityInternal(TNode t1, TNode t2, TNode reason, Me
enqueue(MergeCandidate(t1Id, t2Id, pid, reason));
}
-void EqualityEngine::assertPredicate(TNode t, bool polarity, TNode reason, MergeReasonType pid) {
+void EqualityEngine::assertPredicate(TNode t, bool polarity, TNode reason, unsigned pid) {
Debug("equality") << d_name << "::eq::addPredicate(" << t << "," << (polarity ? "true" : "false") << ")" << std::endl;
Assert(t.getKind() != kind::EQUAL, "Use assertEquality instead");
assertEqualityInternal(t, polarity ? d_true : d_false, reason, pid);
@@ -421,7 +422,7 @@ void EqualityEngine::mergePredicates(TNode p, TNode q, TNode reason) {
propagate();
}
-void EqualityEngine::assertEquality(TNode eq, bool polarity, TNode reason, MergeReasonType pid) {
+void EqualityEngine::assertEquality(TNode eq, bool polarity, TNode reason, unsigned pid) {
Debug("equality") << d_name << "::eq::addEquality(" << eq << "," << (polarity ? "true" : "false") << ")" << std::endl;
if (polarity) {
// If two terms are already equal, don't assert anything
@@ -889,7 +890,7 @@ void EqualityEngine::backtrack() {
}
-void EqualityEngine::addGraphEdge(EqualityNodeId t1, EqualityNodeId t2, MergeReasonType type, TNode reason) {
+void EqualityEngine::addGraphEdge(EqualityNodeId t1, EqualityNodeId t2, unsigned type, TNode reason) {
Debug("equality") << d_name << "::eq::addGraphEdge(" << d_nodes[t1] << "," << d_nodes[t2] << "," << reason << ")" << std::endl;
EqualityEdgeId edge = d_equalityEdges.size();
d_equalityEdges.push_back(EqualityEdge(t2, d_equalityGraph[t1], type, reason));
@@ -920,7 +921,7 @@ std::string EqualityEngine::edgesToString(EqualityEdgeId edgeId) const {
}
void EqualityEngine::explainEquality(TNode t1, TNode t2, bool polarity, std::vector<TNode>& equalities, EqProof * eqp) const {
- Debug("equality") << d_name << "::eq::explainEquality(" << t1 << ", " << t2 << ", " << (polarity ? "true" : "false") << ")" << std::endl;
+ Debug("equality") << d_name << "::eq::explainEquality(" << t1 << ", " << t2 << ", " << (polarity ? "true" : "false") << ")" << ", proof = " << (eqp ? "ON" : "OFF") << std::endl;
// The terms must be there already
Assert(hasTerm(t1) && hasTerm(t2));;
@@ -933,13 +934,72 @@ void EqualityEngine::explainEquality(TNode t1, TNode t2, bool polarity, std::vec
// Get the explanation
getExplanation(t1Id, t2Id, equalities, eqp);
} else {
+ if (eqp) {
+ eqp->d_id = eq::MERGED_THROUGH_TRANS;
+ eqp->d_node = d_nodes[t1Id].eqNode(d_nodes[t2Id]).notNode();
+ }
+
// Get the reason for this disequality
EqualityPair pair(t1Id, t2Id);
Assert(d_disequalityReasonsMap.find(pair) != d_disequalityReasonsMap.end(), "Don't ask for stuff I didn't notify you about");
DisequalityReasonRef reasonRef = d_disequalityReasonsMap.find(pair)->second;
+
for (unsigned i = reasonRef.mergesStart; i < reasonRef.mergesEnd; ++ i) {
+
EqualityPair toExplain = d_deducedDisequalityReasons[i];
- getExplanation(toExplain.first, toExplain.second, equalities, eqp);
+ EqProof* eqpc = NULL;
+
+ // If we're constructing a (transitivity) proof, we don't need to include an explanation for x=x.
+ if (eqp && toExplain.first != toExplain.second) {
+ eqpc = new EqProof;
+ }
+
+ getExplanation(toExplain.first, toExplain.second, equalities, eqpc);
+
+ if (eqpc) {
+ Debug("pf::ee") << "Child proof is:" << std::endl;
+ eqpc->debug_print("pf::ee", 1);
+
+ if (eqpc->d_id == eq::MERGED_THROUGH_TRANS) {
+ std::vector<EqProof *> orderedChildren;
+ bool nullCongruenceFound = false;
+ for (unsigned i = 0; i < eqpc->d_children.size(); ++i) {
+ if (eqpc->d_children[i]->d_id==eq::MERGED_THROUGH_CONGRUENCE && eqpc->d_children[i]->d_node.isNull()) {
+
+ // For now, assume there can only be one null congruence child
+ Assert(!nullCongruenceFound);
+ nullCongruenceFound = true;
+
+ Debug("pf::ee") << "Have congruence with empty d_node. Splitting..." << std::endl;
+ orderedChildren.insert(orderedChildren.begin(), eqpc->d_children[i]->d_children[0]);
+ orderedChildren.push_back(eqpc->d_children[i]->d_children[1]);
+ } else {
+ orderedChildren.push_back(eqpc->d_children[i]);
+ }
+ }
+
+ if (nullCongruenceFound) {
+ eqpc->d_children = orderedChildren;
+ Debug("pf::ee") << "Child proof's children have been reordered. It is now:" << std::endl;
+ eqpc->debug_print("pf::ee", 1);
+ }
+ }
+
+ eqp->d_children.push_back(eqpc);
+ }
+ }
+
+ if (eqp) {
+ if(eqp->d_children.size() == 1) {
+ // The transitivity proof has just one child. Simplify.
+ EqProof* temp = eqp->d_children[0];
+ eqp->d_children.clear();
+ *eqp = *temp;
+ delete temp;
+ }
+
+ Debug("pf::ee") << "Disequality explanation final proof: " << std::endl;
+ eqp->debug_print("pf::ee", 1);
}
}
}
@@ -972,7 +1032,12 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
// If the nodes are the same, we're done
if (t1Id == t2Id){
if( eqp ) {
- eqp->d_node = ProofManager::currentPM()->mkOp(d_nodes[t1Id]);
+ if ((d_nodes[t1Id].getKind() == kind::BUILTIN) && (d_nodes[t1Id].getConst<Kind>() == kind::SELECT)) {
+ std::vector<Node> no_children;
+ eqp->d_node = NodeManager::currentNM()->mkNode(kind::PARTIAL_SELECT_0, no_children);
+ } else {
+ eqp->d_node = ProofManager::currentPM()->mkOp(d_nodes[t1Id]);
+ }
}
return;
}
@@ -1019,24 +1084,28 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
Debug("equality") << d_name << "::eq::getExplanation(): path found: " << std::endl;
- std::vector< EqProof * > eqp_trans;
+ std::vector<EqProof *> eqp_trans;
// Reconstruct the path
do {
// The current node
currentNode = bfsQueue[currentIndex].nodeId;
EqualityNodeId edgeNode = d_equalityEdges[currentEdge].getNodeId();
- MergeReasonType reasonType = d_equalityEdges[currentEdge].getReasonType();
+ unsigned reasonType = d_equalityEdges[currentEdge].getReasonType();
+ Node reason = d_equalityEdges[currentEdge].getReason();
Debug("equality") << d_name << "::eq::getExplanation(): currentEdge = " << currentEdge << ", currentNode = " << currentNode << std::endl;
+ Debug("equality") << d_name << " targetNode = " << d_nodes[edgeNode] << std::endl;
Debug("equality") << d_name << " in currentEdge = (" << d_nodes[currentNode] << "," << d_nodes[edge.getNodeId()] << ")" << std::endl;
+ Debug("equality") << d_name << " reason type = " << reasonType << std::endl;
- EqProof * eqpc = NULL;
- //make child proof if a proof is being constructed
- if( eqp ){
+ EqProof* eqpc = NULL;
+ // Make child proof if a proof is being constructed
+ if (eqp) {
eqpc = new EqProof;
eqpc->d_id = reasonType;
}
+
// Add the actual equality to the vector
switch (reasonType) {
case MERGED_THROUGH_CONGRUENCE: {
@@ -1044,32 +1113,47 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
Debug("equality") << d_name << "::eq::getExplanation(): due to congruence, going deeper" << std::endl;
const FunctionApplication& f1 = d_applications[currentNode].original;
const FunctionApplication& f2 = d_applications[edgeNode].original;
+
Debug("equality") << push;
+ Debug("equality") << "Explaining left hand side equalities" << std::endl;
EqProof * eqpc1 = eqpc ? new EqProof : NULL;
getExplanation(f1.a, f2.a, equalities, eqpc1);
+ Debug("equality") << "Explaining right hand side equalities" << std::endl;
EqProof * eqpc2 = eqpc ? new EqProof : NULL;
getExplanation(f1.b, f2.b, equalities, eqpc2);
if( eqpc ){
eqpc->d_children.push_back( eqpc1 );
eqpc->d_children.push_back( eqpc2 );
- Debug("equality-pf") << "Congruence : " << d_nodes[currentNode] << " " << d_nodes[edgeNode] << std::endl;
if( d_nodes[currentNode].getKind()==kind::EQUAL ){
//leave node null for now
eqpc->d_node = Node::null();
- }else{
- Debug("equality-pf") << d_nodes[f1.a] << " / " << d_nodes[f2.a] << ", " << d_nodes[f1.b] << " / " << d_nodes[f2.b] << std::endl;
+ } else {
if(d_nodes[f1.a].getKind() == kind::APPLY_UF ||
d_nodes[f1.a].getKind() == kind::SELECT ||
d_nodes[f1.a].getKind() == kind::STORE) {
eqpc->d_node = d_nodes[f1.a];
} else {
- eqpc->d_node = NodeManager::currentNM()->mkNode(kind::PARTIAL_APPLY_UF, ProofManager::currentPM()->mkOp(d_nodes[f1.a]), d_nodes[f1.b]);
+ if (d_nodes[f1.a].getKind() == kind::BUILTIN && d_nodes[f1.a].getConst<Kind>() == kind::SELECT) {
+ eqpc->d_node = NodeManager::currentNM()->mkNode(kind::PARTIAL_SELECT_1, d_nodes[f1.b]);
+ // The first child is a PARTIAL_SELECT_0.
+ // Give it a child so that we know what kind of (read) it is, when we dump to LFSC.
+ Assert(eqpc->d_children[0]->d_node.getKind() == kind::PARTIAL_SELECT_0);
+ Assert(eqpc->d_children[0]->d_children.size() == 0);
+
+ eqpc->d_children[0]->d_node = NodeManager::currentNM()->mkNode(kind::PARTIAL_SELECT_0,
+ d_nodes[f1.b]);
+ } else {
+ eqpc->d_node = NodeManager::currentNM()->mkNode(kind::PARTIAL_APPLY_UF,
+ ProofManager::currentPM()->mkOp(d_nodes[f1.a]),
+ d_nodes[f1.b]);
+ }
}
}
}
Debug("equality") << pop;
break;
}
+
case MERGED_THROUGH_REFLEXIVITY: {
// x1 == x1
Debug("equality") << d_name << "::eq::getExplanation(): due to reflexivity, going deeper" << std::endl;
@@ -1088,6 +1172,7 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
break;
}
+
case MERGED_THROUGH_CONSTANTS: {
// f(c1, ..., cn) = c semantically, we can just ignore it
Debug("equality") << d_name << "::eq::getExplanation(): due to constants, explain the constants" << std::endl;
@@ -1111,23 +1196,41 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
}
Debug("equality") << pop;
-
break;
}
+
default: {
// Construct the equality
- Debug("equality") << d_name << "::eq::getExplanation(): adding: " << d_equalityEdges[currentEdge].getReason() << std::endl;
- if( eqpc ){
- if(reasonType == MERGED_THROUGH_EQUALITY) {
- eqpc->d_node = d_equalityEdges[currentEdge].getReason();
+ Debug("equality") << d_name << "::eq::getExplanation(): adding: "
+ << reason << std::endl;
+ Debug("equality") << d_name << "::eq::getExplanation(): reason type = " << reasonType << std::endl;
+
+ Node a = d_nodes[currentNode];
+ Node b = d_nodes[d_equalityEdges[currentEdge].getNodeId()];
+
+ if (eqpc) {
+ //apply proof reconstruction processing (when eqpc is non-null)
+ if (d_pathReconstructionTriggers.find(reasonType) != d_pathReconstructionTriggers.end()) {
+ d_pathReconstructionTriggers.find(reasonType)->second->notify(reasonType, reason, a, b,
+ equalities, eqpc);
+ }
+ if (reasonType == MERGED_THROUGH_EQUALITY) {
+ eqpc->d_node = reason;
} else {
- // theory-specific proof rule
- eqpc->d_node = d_nodes[d_equalityEdges[currentEdge].getNodeId()].eqNode(d_nodes[currentNode]);
- Debug("equality-pf") << "theory eq : " << eqpc->d_node << std::endl;
+ // The LFSC translator prefers (not (= a b)) over (= (= a b) false)
+
+ if (a == NodeManager::currentNM()->mkConst(false)) {
+ eqpc->d_node = b.notNode();
+ } else if (b == NodeManager::currentNM()->mkConst(false)) {
+ eqpc->d_node = a.notNode();
+ } else {
+ eqpc->d_node = b.eqNode(a);
+ }
}
eqpc->d_id = reasonType;
}
- equalities.push_back(d_equalityEdges[currentEdge].getReason());
+
+ equalities.push_back(reason);
break;
}
}
@@ -1137,7 +1240,7 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
currentIndex = bfsQueue[currentIndex].previousIndex;
//---from Morgan---
- if(eqpc != NULL && eqpc->d_id == MERGED_THROUGH_REFLEXIVITY) {
+ if (eqpc != NULL && eqpc->d_id == MERGED_THROUGH_REFLEXIVITY) {
if(eqpc->d_node.isNull()) {
Assert(eqpc->d_children.size() == 1);
EqProof *p = eqpc;
@@ -1149,11 +1252,10 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
}
//---end from Morgan---
- eqp_trans.push_back( eqpc );
-
+ eqp_trans.push_back(eqpc);
} while (currentEdge != null_id);
- if(eqp) {
+ if (eqp) {
if(eqp_trans.size() == 1) {
*eqp = *eqp_trans[0];
delete eqp_trans[0];
@@ -1162,6 +1264,8 @@ void EqualityEngine::getExplanation(EqualityNodeId t1Id, EqualityNodeId t2Id, st
eqp->d_children.insert( eqp->d_children.end(), eqp_trans.begin(), eqp_trans.end() );
eqp->d_node = NodeManager::currentNM()->mkNode(d_nodes[t1Id].getType().isBoolean() ? kind::IFF : kind::EQUAL, d_nodes[t1Id], d_nodes[t2Id]);
}
+
+ eqp->debug_print("pf::ee", 1);
}
// Done
@@ -1508,7 +1612,7 @@ void EqualityEngine::debugPrintGraph() const {
EqualityEdgeId edgeId = d_equalityGraph[nodeId];
while (edgeId != null_edge) {
const EqualityEdge& edge = d_equalityEdges[edgeId];
- Debug("equality::graph") << " " << d_nodes[edge.getNodeId()] << ":" << edge.getReason();
+ Debug("equality::graph") << " [" << edge.getNodeId() << "] " << d_nodes[edge.getNodeId()] << ":" << edge.getReason();
edgeId = edge.getNext();
}
@@ -1517,17 +1621,19 @@ void EqualityEngine::debugPrintGraph() const {
}
bool EqualityEngine::areEqual(TNode t1, TNode t2) const {
- Debug("equality") << d_name << "::eq::areEqual(" << t1 << "," << t2 << ")" << std::endl;
+ Debug("equality") << d_name << "::eq::areEqual(" << t1 << "," << t2 << ")";
Assert(hasTerm(t1));
Assert(hasTerm(t2));
- return getEqualityNode(t1).getFind() == getEqualityNode(t2).getFind();
+ bool result = getEqualityNode(t1).getFind() == getEqualityNode(t2).getFind();
+ Debug("equality") << (result ? "\t(YES)" : "\t(NO)") << std::endl;
+ return result;
}
bool EqualityEngine::areDisequal(TNode t1, TNode t2, bool ensureProof) const
{
- Debug("equality") << d_name << "::eq::areDisequal(" << t1 << "," << t2 << ")" << std::endl;
+ Debug("equality") << d_name << "::eq::areDisequal(" << t1 << "," << t2 << ")";
// Add the terms
Assert(hasTerm(t1));
@@ -1539,6 +1645,7 @@ bool EqualityEngine::areDisequal(TNode t1, TNode t2, bool ensureProof) const
// If we propagated this disequality we're true
if (hasPropagatedDisequality(t1Id, t2Id)) {
+ Debug("equality") << "\t(YES)" << std::endl;
return true;
}
@@ -1556,6 +1663,7 @@ bool EqualityEngine::areDisequal(TNode t1, TNode t2, bool ensureProof) const
nonConst->d_deducedDisequalityReasons.push_back(EqualityPair(t2Id, t2ClassId));
nonConst->storePropagatedDisequality(THEORY_LAST, t1Id, t2Id);
}
+ Debug("equality") << "\t(YES)" << std::endl;
return true;
}
@@ -1571,6 +1679,7 @@ bool EqualityEngine::areDisequal(TNode t1, TNode t2, bool ensureProof) const
nonConst->d_deducedDisequalityReasons.push_back(EqualityPair(t2Id, original.b));
nonConst->storePropagatedDisequality(THEORY_LAST, t1Id, t2Id);
}
+ Debug("equality") << "\t(YES)" << std::endl;
return true;
}
}
@@ -1587,21 +1696,33 @@ bool EqualityEngine::areDisequal(TNode t1, TNode t2, bool ensureProof) const
nonConst->d_deducedDisequalityReasons.push_back(EqualityPair(t1Id, original.b));
nonConst->storePropagatedDisequality(THEORY_LAST, t1Id, t2Id);
}
+ Debug("equality") << "\t(YES)" << std::endl;
return true;
}
}
// Couldn't deduce dis-equalityReturn whether the terms are disequal
+ Debug("equality") << "\t(NO)" << std::endl;
return false;
}
-size_t EqualityEngine::getSize(TNode t)
-{
+size_t EqualityEngine::getSize(TNode t) {
// Add the term
addTermInternal(t);
return getEqualityNode(getEqualityNode(t).getFind()).getSize();
}
+
+void EqualityEngine::addPathReconstructionTrigger(unsigned trigger, const PathReconstructionNotify* notify) {
+ // Currently we can only inform one callback per trigger
+ Assert(d_pathReconstructionTriggers.find(trigger) == d_pathReconstructionTriggers.end());
+ d_pathReconstructionTriggers[trigger] = notify;
+}
+
+unsigned EqualityEngine::getFreshMergeReasonType() {
+ return d_freshMergeReasonType++;
+}
+
void EqualityEngine::addTriggerTerm(TNode t, TheoryId tag)
{
Debug("equality::trigger") << d_name << "::eq::addTriggerTerm(" << t << ", " << tag << ")" << std::endl;
@@ -2103,10 +2224,9 @@ void EqProof::debug_print( const char * c, unsigned tb ) const{
d_children[i]->debug_print( c, tb+1 );
}
}
- Debug( c ) << ")";
+ Debug( c ) << ")" << std::endl;
}
-
} // Namespace uf
} // Namespace theory
} // Namespace CVC4
diff --git a/src/theory/uf/equality_engine.h b/src/theory/uf/equality_engine.h
index 9cfa16adf..f30f1e8a0 100644
--- a/src/theory/uf/equality_engine.h
+++ b/src/theory/uf/equality_engine.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file equality_engine.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Tim King, Kshitij Bansal, Dejan Jovanovic, Liana Hadarean, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -140,6 +140,18 @@ public:
void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { }
};/* class EqualityEngineNotifyNone */
+/**
+ * An interface for equality engine notifications during equality path reconstruction.
+ * Can be used to add theory-specific logic for, e.g., proof construction.
+ */
+class PathReconstructionNotify {
+public:
+
+ virtual ~PathReconstructionNotify() {}
+
+ virtual void notify(unsigned reasonType, Node reason, Node a, Node b,
+ std::vector<TNode>& equalities, EqProof* proof) const = 0;
+};
/**
* Class for keeping an incremental congruence closure over a set of terms. It provides
@@ -218,6 +230,9 @@ private:
/** The map of kinds to be treated as interpreted function applications (for evaluation of constants) */
KindMap d_congruenceKindsInterpreted;
+ /** Objects that need to be notified during equality path reconstruction */
+ std::map<unsigned, const PathReconstructionNotify*> d_pathReconstructionTriggers;
+
/** Map from nodes to their ids */
__gnu_cxx::hash_map<TNode, EqualityNodeId, TNodeHashFunction> d_nodeIds;
@@ -259,6 +274,9 @@ private:
/** Memory for the use-list nodes */
std::vector<UseListNode> d_useListNodes;
+ /** A fresh merge reason type to return upon request */
+ unsigned d_freshMergeReasonType;
+
/**
* We keep a list of asserted equalities. Not among original terms, but
* among the class representatives.
@@ -289,7 +307,7 @@ private:
// The next edge
EqualityEdgeId d_nextId;
// Type of reason for this equality
- MergeReasonType d_mergeType;
+ unsigned d_mergeType;
// Reason of this equality
TNode d_reason;
@@ -298,7 +316,7 @@ private:
EqualityEdge():
d_nodeId(null_edge), d_nextId(null_edge), d_mergeType(MERGED_THROUGH_CONGRUENCE) {}
- EqualityEdge(EqualityNodeId nodeId, EqualityNodeId nextId, MergeReasonType type, TNode reason):
+ EqualityEdge(EqualityNodeId nodeId, EqualityNodeId nextId, unsigned type, TNode reason):
d_nodeId(nodeId), d_nextId(nextId), d_mergeType(type), d_reason(reason) {}
/** Returns the id of the next edge */
@@ -308,7 +326,7 @@ private:
EqualityNodeId getNodeId() const { return d_nodeId; }
/** The reason of this edge */
- MergeReasonType getReasonType() const { return d_mergeType; }
+ unsigned getReasonType() const { return d_mergeType; }
/** The reason of this edge */
TNode getReason() const { return d_reason; }
@@ -333,7 +351,7 @@ private:
std::vector<EqualityEdgeId> d_equalityGraph;
/** Add an edge to the equality graph */
- void addGraphEdge(EqualityNodeId t1, EqualityNodeId t2, MergeReasonType type, TNode reason);
+ void addGraphEdge(EqualityNodeId t1, EqualityNodeId t2, unsigned type, TNode reason);
/** Returns the equality node of the given node */
EqualityNode& getEqualityNode(TNode node);
@@ -505,7 +523,7 @@ private:
/**
* Adds an equality of terms t1 and t2 to the database.
*/
- void assertEqualityInternal(TNode t1, TNode t2, TNode reason, MergeReasonType pid = MERGED_THROUGH_EQUALITY);
+ void assertEqualityInternal(TNode t1, TNode t2, TNode reason, unsigned pid = MERGED_THROUGH_EQUALITY);
/**
* Adds a trigger equality to the database with the trigger node and polarity for notification.
@@ -729,7 +747,7 @@ public:
* asserting the negated predicate
* @param reason the reason to keep for building explanations
*/
- void assertPredicate(TNode p, bool polarity, TNode reason, MergeReasonType pid = MERGED_THROUGH_EQUALITY);
+ void assertPredicate(TNode p, bool polarity, TNode reason, unsigned pid = MERGED_THROUGH_EQUALITY);
/**
* Adds predicate p and q and makes them equal.
@@ -744,7 +762,7 @@ public:
* asserting the negated equality
* @param reason the reason to keep for building explanations
*/
- void assertEquality(TNode eq, bool polarity, TNode reason, MergeReasonType pid = MERGED_THROUGH_EQUALITY);
+ void assertEquality(TNode eq, bool polarity, TNode reason, unsigned pid = MERGED_THROUGH_EQUALITY);
/**
* Returns the current representative of the term t.
@@ -833,6 +851,15 @@ public:
*/
bool consistent() const { return !d_done; }
+ /**
+ * Marks an object for merge type based notification during equality path reconstruction.
+ */
+ void addPathReconstructionTrigger(unsigned trigger, const PathReconstructionNotify* notify);
+
+ /**
+ * Returns a fresh merge reason type tag for the client to use.
+ */
+ unsigned getFreshMergeReasonType();
};
/**
@@ -876,7 +903,7 @@ class EqProof
{
public:
EqProof() : d_id(MERGED_THROUGH_REFLEXIVITY){}
- MergeReasonType d_id;
+ unsigned d_id;
Node d_node;
std::vector< EqProof * > d_children;
void debug_print( const char * c, unsigned tb = 0 ) const;
diff --git a/src/theory/uf/equality_engine_types.h b/src/theory/uf/equality_engine_types.h
index fb1e73575..346aebca7 100644
--- a/src/theory/uf/equality_engine_types.h
+++ b/src/theory/uf/equality_engine_types.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file equality_engine_types.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Andrew Reynolds, Guy Katz
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
@@ -67,14 +67,11 @@ enum MergeReasonType {
MERGED_THROUGH_REFLEXIVITY,
/** Equality was merged to false, due to both sides of equality being a constant */
MERGED_THROUGH_CONSTANTS,
-
/** (for proofs only) Equality was merged due to transitivity */
MERGED_THROUGH_TRANS,
- /** Theory specific proof rules */
- MERGED_ARRAYS_ROW,
- MERGED_ARRAYS_ROW1,
- MERGED_ARRAYS_EXT
+ /** Reason types beyond this constant are theory specific reasons */
+ NUMBER_OF_MERGE_REASONS
};
inline std::ostream& operator << (std::ostream& out, MergeReasonType reason) {
@@ -91,10 +88,10 @@ inline std::ostream& operator << (std::ostream& out, MergeReasonType reason) {
case MERGED_THROUGH_CONSTANTS:
out << "constants disequal";
break;
- // (for proofs only)
case MERGED_THROUGH_TRANS:
out << "transitivity";
break;
+
default:
out << "[theory]";
break;
@@ -108,9 +105,9 @@ inline std::ostream& operator << (std::ostream& out, MergeReasonType reason) {
*/
struct MergeCandidate {
EqualityNodeId t1Id, t2Id;
- MergeReasonType type;
+ unsigned type;
TNode reason;
- MergeCandidate(EqualityNodeId x, EqualityNodeId y, MergeReasonType type, TNode reason)
+ MergeCandidate(EqualityNodeId x, EqualityNodeId y, unsigned type, TNode reason)
: t1Id(x), t2Id(y), type(type), reason(reason)
{}
};
@@ -365,4 +362,3 @@ struct TriggerInfo {
} // namespace eq
} // namespace theory
} // namespace CVC4
-
diff --git a/src/theory/uf/symmetry_breaker.cpp b/src/theory/uf/symmetry_breaker.cpp
index 4f7a2667c..ed5d99bdf 100644
--- a/src/theory/uf/symmetry_breaker.cpp
+++ b/src/theory/uf/symmetry_breaker.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file symmetry_breaker.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of algorithm suggested by Deharbe, Fontaine,
** Merz, and Paleo, "Exploiting symmetry in SMT problems," CADE 2011
diff --git a/src/theory/uf/symmetry_breaker.h b/src/theory/uf/symmetry_breaker.h
index 5523c1c0d..b706f340f 100644
--- a/src/theory/uf/symmetry_breaker.h
+++ b/src/theory/uf/symmetry_breaker.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file symmetry_breaker.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of algorithm suggested by Deharbe, Fontaine,
** Merz, and Paleo, "Exploiting symmetry in SMT problems," CADE 2011
diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp
index ffb537734..0c7bed773 100644
--- a/src/theory/uf/theory_uf.cpp
+++ b/src/theory/uf/theory_uf.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Dejan Jovanovic
- ** Minor contributors (to current version): Clark Barrett, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is the interface to TheoryUF implementations
**
@@ -105,6 +105,8 @@ void TheoryUF::check(Effort level) {
TNode fact = assertion.assertion;
Debug("uf") << "TheoryUF::check(): processing " << fact << std::endl;
+ Debug("uf") << "Term's theory: " << theory::Theory::theoryOf(fact.toExpr()) << std::endl;
+
if (d_thss != NULL) {
bool isDecision = d_valuation.isSatLiteral(fact) && d_valuation.isDecision(fact);
d_thss->assertNode(fact, isDecision);
@@ -219,9 +221,15 @@ void TheoryUF::explain(TNode literal, std::vector<TNode>& assumptions, eq::EqPro
d_equalityEngine.explainPredicate(atom, polarity, assumptions, pf);
}
if( pf ){
- Debug("uf-pf") << std::endl;
- pf->debug_print("uf-pf");
+ Debug("pf::uf") << std::endl;
+ pf->debug_print("pf::uf");
+ }
+
+ Debug("pf::uf") << "UF: explain( " << literal << " ):" << std::endl << "\t";
+ for (unsigned i = 0; i < assumptions.size(); ++i) {
+ Debug("pf::uf") << assumptions[i] << " ";
}
+ Debug("pf::uf") << std::endl;
}
Node TheoryUF::explain(TNode literal) {
@@ -270,6 +278,7 @@ void TheoryUF::presolve() {
for(vector<Node>::const_iterator i = newClauses.begin();
i != newClauses.end();
++i) {
+ Debug("uf") << "uf: generating a lemma: " << *i << std::endl;
d_out->lemma(*i);
}
}
@@ -521,7 +530,7 @@ void TheoryUF::conflict(TNode a, TNode b) {
} else {
d_conflictNode = explain(a.eqNode(b),pf);
}
- ProofUF * puf = d_proofsEnabled ? new ProofUF( pf ) : NULL;
+ ProofUF* puf = d_proofsEnabled ? new ProofUF( pf ) : NULL;
d_out->conflict(d_conflictNode, puf);
d_conflict = true;
}
diff --git a/src/theory/uf/theory_uf.h b/src/theory/uf/theory_uf.h
index e29b923f9..42a804c09 100644
--- a/src/theory/uf/theory_uf.h
+++ b/src/theory/uf/theory_uf.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Dejan Jovanovic, Morgan Deters
- ** Minor contributors (to current version): Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Dejan Jovanovic, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is the interface to TheoryUF implementations
**
@@ -136,7 +136,7 @@ private:
* Explain a literal, with proof (if "pf" is non-NULL).
*/
Node explain(TNode literal, eq::EqProof* pf);
-
+
/** Literals to propagate */
context::CDList<Node> d_literalsToPropagate;
diff --git a/src/theory/uf/theory_uf_model.cpp b/src/theory/uf/theory_uf_model.cpp
index 6d0123a19..f6568ad7f 100644
--- a/src/theory/uf/theory_uf_model.cpp
+++ b/src/theory/uf/theory_uf_model.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_model.cpp
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of Theory UF Model
**/
diff --git a/src/theory/uf/theory_uf_model.h b/src/theory/uf/theory_uf_model.h
index 970a7d6b3..39e7ee6f0 100644
--- a/src/theory/uf/theory_uf_model.h
+++ b/src/theory/uf/theory_uf_model.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_model.h
** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Model for Theory UF
**/
diff --git a/src/theory/uf/theory_uf_rewriter.h b/src/theory/uf/theory_uf_rewriter.h
index 82dacb6c2..166d11451 100644
--- a/src/theory/uf/theory_uf_rewriter.h
+++ b/src/theory/uf/theory_uf_rewriter.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_rewriter.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Clark Barrett
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/theory/uf/theory_uf_strong_solver.cpp b/src/theory/uf/theory_uf_strong_solver.cpp
index 3ed1c4d40..ed28cc2fc 100644
--- a/src/theory/uf/theory_uf_strong_solver.cpp
+++ b/src/theory/uf/theory_uf_strong_solver.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_strong_solver.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): Clark Barrett
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Implementation of theory uf strong solver class
**/
@@ -29,17 +29,44 @@
//#define LAZY_REL_EQC
using namespace std;
-using namespace CVC4;
using namespace CVC4::kind;
using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::uf;
-void StrongSolverTheoryUF::SortModel::Region::addRep( Node n ) {
+
+namespace CVC4 {
+namespace theory {
+namespace uf {
+
+/* These are names are unambigious are we use abbreviations. */
+typedef StrongSolverTheoryUF::SortModel SortModel;
+typedef SortModel::Region Region;
+typedef Region::RegionNodeInfo RegionNodeInfo;
+typedef RegionNodeInfo::DiseqList DiseqList;
+
+Region::Region(SortModel* cf, context::Context* c)
+ : d_cf( cf )
+ , d_testCliqueSize( c, 0 )
+ , d_splitsSize( c, 0 )
+ , d_testClique( c )
+ , d_splits( c )
+ , d_reps_size( c, 0 )
+ , d_total_diseq_external( c, 0 )
+ , d_total_diseq_internal( c, 0 )
+ , d_valid( c, true ) {}
+
+Region::~Region() {
+ for(iterator i = begin(), iend = end(); i != iend; ++i) {
+ RegionNodeInfo* regionNodeInfo = (*i).second;
+ delete regionNodeInfo;
+ }
+ d_nodes.clear();
+}
+
+void Region::addRep( Node n ) {
setRep( n, true );
}
-void StrongSolverTheoryUF::SortModel::Region::takeNode( StrongSolverTheoryUF::SortModel::Region* r, Node n ){
+void Region::takeNode( Region* r, Node n ){
Assert( !hasRep( n ) );
Assert( r->hasRep( n ) );
//add representative
@@ -47,8 +74,8 @@ void StrongSolverTheoryUF::SortModel::Region::takeNode( StrongSolverTheoryUF::So
//take disequalities from r
RegionNodeInfo* rni = r->d_nodes[n];
for( int t=0; t<2; t++ ){
- RegionNodeInfo::DiseqList* del = rni->d_disequalities[t];
- for( NodeBoolMap::iterator it = del->d_disequalities.begin(); it != del->d_disequalities.end(); ++it ){
+ DiseqList* del = rni->get(t);
+ for(DiseqList::iterator it = del->begin(); it != del->end(); ++it ){
if( (*it).second ){
r->setDisequal( n, (*it).first, t, false );
if( t==0 ){
@@ -71,21 +98,22 @@ void StrongSolverTheoryUF::SortModel::Region::takeNode( StrongSolverTheoryUF::So
r->setRep( n, false );
}
-void StrongSolverTheoryUF::SortModel::Region::combine( StrongSolverTheoryUF::SortModel::Region* r ){
+void Region::combine( Region* r ){
//take all nodes from r
- for( std::map< Node, RegionNodeInfo* >::iterator it = r->d_nodes.begin(); it != r->d_nodes.end(); ++it ){
- if( it->second->d_valid ){
+ for(Region::iterator it = r->d_nodes.begin(); it != r->d_nodes.end(); ++it) {
+ if( it->second->valid() ){
setRep( it->first, true );
}
}
- for( std::map< Node, RegionNodeInfo* >::iterator it = r->d_nodes.begin(); it != r->d_nodes.end(); ++it ){
- if( it->second->d_valid ){
+ for(Region::iterator it = r->d_nodes.begin(); it != r->d_nodes.end(); ++it){
+ if( it->second->valid() ){
//take disequalities from r
Node n = it->first;
RegionNodeInfo* rni = it->second;
for( int t=0; t<2; t++ ){
- RegionNodeInfo::DiseqList* del = rni->d_disequalities[t];
- for( NodeBoolMap::iterator it2 = del->d_disequalities.begin(); it2 != del->d_disequalities.end(); ++it2 ){
+ RegionNodeInfo::DiseqList* del = rni->get(t);
+ for( RegionNodeInfo::DiseqList::iterator it2 = del->begin(),
+ it2end = del->end(); it2 != it2end; ++it2 ){
if( (*it2).second ){
if( t==0 && hasRep( (*it2).first ) ){
setDisequal( (*it2).first, n, 0, false );
@@ -103,12 +131,12 @@ void StrongSolverTheoryUF::SortModel::Region::combine( StrongSolverTheoryUF::Sor
}
/** setEqual */
-void StrongSolverTheoryUF::SortModel::Region::setEqual( Node a, Node b ){
+void Region::setEqual( Node a, Node b ){
Assert( hasRep( a ) && hasRep( b ) );
//move disequalities of b over to a
for( int t=0; t<2; t++ ){
- RegionNodeInfo::DiseqList* del = d_nodes[b]->d_disequalities[t];
- for( NodeBoolMap::iterator it = del->d_disequalities.begin(); it != del->d_disequalities.end(); ++it ){
+ DiseqList* del = d_nodes[b]->get(t);
+ for( DiseqList::iterator it = del->begin(); it != del->end(); ++it ){
if( (*it).second ){
Node n = (*it).first;
//get the region that contains the endpoint of the disequality b != ...
@@ -133,12 +161,13 @@ void StrongSolverTheoryUF::SortModel::Region::setEqual( Node a, Node b ){
setRep( b, false );
}
-void StrongSolverTheoryUF::SortModel::Region::setDisequal( Node n1, Node n2, int type, bool valid ){
- //Debug("uf-ss-region-debug") << "set disequal " << n1 << " " << n2 << " " << type << " " << valid << std::endl;
+void Region::setDisequal( Node n1, Node n2, int type, bool valid ){
+ //Debug("uf-ss-region-debug") << "set disequal " << n1 << " " << n2 << " "
+ // << type << " " << valid << std::endl;
//debugPrint("uf-ss-region-debug");
//Assert( isDisequal( n1, n2, type )!=valid );
if( isDisequal( n1, n2, type )!=valid ){ //DO_THIS: make assertion
- d_nodes[ n1 ]->d_disequalities[type]->setDisequal( n2, valid );
+ d_nodes[ n1 ]->get(type)->setDisequal( n2, valid );
if( type==0 ){
d_total_diseq_external = d_total_diseq_external + ( valid ? 1 : -1 );
}else{
@@ -149,7 +178,8 @@ void StrongSolverTheoryUF::SortModel::Region::setDisequal( Node n1, Node n2, int
d_testClique.find( n2 )!=d_testClique.end() && d_testClique[n2] ){
Node eq = NodeManager::currentNM()->mkNode( EQUAL, n1, n2 );
if( d_splits.find( eq )!=d_splits.end() && d_splits[ eq ] ){
- Debug("uf-ss-debug") << "removing split for " << n1 << " " << n2 << std::endl;
+ Debug("uf-ss-debug") << "removing split for " << n1 << " " << n2
+ << std::endl;
d_splits[ eq ] = false;
d_splitsSize = d_splitsSize - 1;
}
@@ -159,20 +189,20 @@ void StrongSolverTheoryUF::SortModel::Region::setDisequal( Node n1, Node n2, int
}
}
-void StrongSolverTheoryUF::SortModel::Region::setRep( Node n, bool valid ){
+void Region::setRep( Node n, bool valid ) {
Assert( hasRep( n )!=valid );
if( valid && d_nodes.find( n )==d_nodes.end() ){
d_nodes[n] = new RegionNodeInfo( d_cf->d_thss->getSatContext() );
}
- d_nodes[n]->d_valid = valid;
+ d_nodes[n]->setValid(valid);
d_reps_size = d_reps_size + ( valid ? 1 : -1 );
//removing a member of the test clique from this region
- if( d_testClique.find( n )!=d_testClique.end() && d_testClique[n] ){
+ if( d_testClique.find( n ) != d_testClique.end() && d_testClique[n] ){
Assert( !valid );
d_testClique[n] = false;
d_testCliqueSize = d_testCliqueSize - 1;
//remove all splits involving n
- for( NodeBoolMap::iterator it = d_splits.begin(); it != d_splits.end(); ++it ){
+ for( split_iterator it = begin_splits(); it != end_splits(); ++it ){
if( (*it).second ){
if( (*it).first[0]==n || (*it).first[1]==n ){
d_splits[ (*it).first ] = false;
@@ -183,33 +213,41 @@ void StrongSolverTheoryUF::SortModel::Region::setRep( Node n, bool valid ){
}
}
-bool StrongSolverTheoryUF::SortModel::Region::isDisequal( Node n1, Node n2, int type ){
- RegionNodeInfo::DiseqList* del = d_nodes[ n1 ]->d_disequalities[type];
- return del->d_disequalities.find( n2 )!=del->d_disequalities.end() && del->d_disequalities[n2];
+bool Region::isDisequal( Node n1, Node n2, int type ) {
+ RegionNodeInfo::DiseqList* del = d_nodes[ n1 ]->get(type);
+ return del->isSet(n2) && del->getDisequalityValue(n2);
}
struct sortInternalDegree {
- StrongSolverTheoryUF::SortModel::Region* r;
- bool operator() (Node i,Node j) { return (r->d_nodes[i]->getNumInternalDisequalities()>r->d_nodes[j]->getNumInternalDisequalities());}
+ Region* r;
+ bool operator() (Node i, Node j) {
+ return (r->getRegionInfo(i)->getNumInternalDisequalities() >
+ r->getRegionInfo(j)->getNumInternalDisequalities());
+ }
};
struct sortExternalDegree {
- StrongSolverTheoryUF::SortModel::Region* r;
- bool operator() (Node i,Node j) { return (r->d_nodes[i]->getNumExternalDisequalities()>r->d_nodes[j]->getNumExternalDisequalities());}
+ Region* r;
+ bool operator() (Node i,Node j) {
+ return (r->getRegionInfo(i)->getNumExternalDisequalities() >
+ r->getRegionInfo(j)->getNumExternalDisequalities());
+ }
};
int gmcCount = 0;
-bool StrongSolverTheoryUF::SortModel::Region::getMustCombine( int cardinality ){
+bool Region::getMustCombine( int cardinality ){
if( options::ufssRegions() && d_total_diseq_external>=unsigned(cardinality) ){
- //The number of external disequalities is greater than or equal to cardinality.
- //Thus, a clique of size cardinality+1 may exist between nodes in d_regions[i] and other regions
- //Check if this is actually the case: must have n nodes with outgoing degree (cardinality+1-n) for some n>0
+ //The number of external disequalities is greater than or equal to
+ //cardinality. Thus, a clique of size cardinality+1 may exist
+ //between nodes in d_regions[i] and other regions Check if this is
+ //actually the case: must have n nodes with outgoing degree
+ //(cardinality+1-n) for some n>0
std::vector< int > degrees;
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
+ for( Region::iterator it = begin(); it != end(); ++it ){
RegionNodeInfo* rni = it->second;
- if( rni->d_valid ){
- if( rni->getNumDisequalities()>=cardinality ){
+ if( rni->valid() ){
+ if( rni->getNumDisequalities() >= cardinality ){
int outDeg = rni->getNumExternalDisequalities();
if( outDeg>=cardinality ){
//we have 1 node of degree greater than (cardinality)
@@ -226,7 +264,8 @@ bool StrongSolverTheoryUF::SortModel::Region::getMustCombine( int cardinality ){
}
gmcCount++;
if( gmcCount%100==0 ){
- Trace("gmc-count") << gmcCount << " " << cardinality << " sample : " << degrees.size() << std::endl;
+ Trace("gmc-count") << gmcCount << " " << cardinality
+ << " sample : " << degrees.size() << std::endl;
}
//this should happen relatively infrequently....
std::sort( degrees.begin(), degrees.end() );
@@ -239,13 +278,14 @@ bool StrongSolverTheoryUF::SortModel::Region::getMustCombine( int cardinality ){
return false;
}
-bool StrongSolverTheoryUF::SortModel::Region::check( Theory::Effort level, int cardinality, std::vector< Node >& clique ){
+bool Region::check( Theory::Effort level, int cardinality,
+ std::vector< Node >& clique ) {
if( d_reps_size>unsigned(cardinality) ){
if( d_total_diseq_internal==d_reps_size*( d_reps_size - 1 ) ){
if( d_reps_size>1 ){
//quick clique check, all reps form a clique
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
- if( it->second->d_valid ){
+ for( iterator it = begin(); it != end(); ++it ){
+ if( it->second->valid() ){
clique.push_back( it->first );
}
}
@@ -254,15 +294,19 @@ bool StrongSolverTheoryUF::SortModel::Region::check( Theory::Effort level, int c
}else{
return false;
}
- }else if( options::ufssRegions() || options::ufssEagerSplits() || level==Theory::EFFORT_FULL ){
+ }else if( options::ufssRegions() || options::ufssEagerSplits() ||
+ level==Theory::EFFORT_FULL ) {
//build test clique, up to size cardinality+1
if( d_testCliqueSize<=unsigned(cardinality) ){
std::vector< Node > newClique;
if( d_testCliqueSize<unsigned(cardinality) ){
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
+ for( iterator it = begin(); it != end(); ++it ){
//if not in the test clique, add it to the set of new members
- if( it->second->d_valid && ( d_testClique.find( it->first )==d_testClique.end() || !d_testClique[ it->first ] ) ){
- //if( it->second->getNumInternalDisequalities()>cardinality || level==Theory::EFFORT_FULL ){
+ if( it->second->valid() &&
+ ( d_testClique.find( it->first ) == d_testClique.end() ||
+ !d_testClique[ it->first ] ) ){
+ //if( it->second->getNumInternalDisequalities()>cardinality ||
+ // level==Theory::EFFORT_FULL ){
newClique.push_back( it->first );
//}
}
@@ -271,14 +315,18 @@ bool StrongSolverTheoryUF::SortModel::Region::check( Theory::Effort level, int c
sortInternalDegree sidObj;
sidObj.r = this;
std::sort( newClique.begin(), newClique.end(), sidObj );
- newClique.erase( newClique.begin() + ( cardinality - d_testCliqueSize ) + 1, newClique.end() );
+ int offset = ( cardinality - d_testCliqueSize ) + 1;
+ newClique.erase( newClique.begin() + offset, newClique.end() );
}else{
//scan for the highest degree
int maxDeg = -1;
Node maxNode;
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
+ for( std::map< Node, RegionNodeInfo* >::iterator
+ it = d_nodes.begin(); it != d_nodes.end(); ++it ){
//if not in the test clique, add it to the set of new members
- if( it->second->d_valid && ( d_testClique.find( it->first )==d_testClique.end() || !d_testClique[ it->first ] ) ){
+ if( it->second->valid() &&
+ ( d_testClique.find( it->first )==d_testClique.end() ||
+ !d_testClique[ it->first ] ) ){
if( it->second->getNumInternalDisequalities()>maxDeg ){
maxDeg = it->second->getNumInternalDisequalities();
maxNode = it->first;
@@ -290,18 +338,27 @@ bool StrongSolverTheoryUF::SortModel::Region::check( Theory::Effort level, int c
}
//check splits internal to new members
for( int j=0; j<(int)newClique.size(); j++ ){
- Debug("uf-ss-debug") << "Choose to add clique member " << newClique[j] << std::endl;
+ Debug("uf-ss-debug") << "Choose to add clique member "
+ << newClique[j] << std::endl;
for( int k=(j+1); k<(int)newClique.size(); k++ ){
if( !isDisequal( newClique[j], newClique[k], 1 ) ){
- d_splits[ NodeManager::currentNM()->mkNode( EQUAL, newClique[j], newClique[k] ) ] = true;
+ Node at_j = newClique[j];
+ Node at_k = newClique[k];
+ Node j_eq_k =
+ NodeManager::currentNM()->mkNode( EQUAL, at_j, at_k );
+ d_splits[ j_eq_k ] = true;
d_splitsSize = d_splitsSize + 1;
}
}
//check disequalities with old members
- for( NodeBoolMap::iterator it = d_testClique.begin(); it != d_testClique.end(); ++it ){
+ for( NodeBoolMap::iterator it = d_testClique.begin();
+ it != d_testClique.end(); ++it ){
if( (*it).second ){
if( !isDisequal( (*it).first, newClique[j], 1 ) ){
- d_splits[ NodeManager::currentNM()->mkNode( EQUAL, (*it).first, newClique[j] ) ] = true;
+ Node at_it = (*it).first;
+ Node at_j = newClique[j];
+ Node it_eq_j = at_it.eqNode(at_j);
+ d_splits[ it_eq_j ] = true;
d_splitsSize = d_splitsSize + 1;
}
}
@@ -313,10 +370,12 @@ bool StrongSolverTheoryUF::SortModel::Region::check( Theory::Effort level, int c
d_testCliqueSize = d_testCliqueSize + 1;
}
}
- //check if test clique has larger size than cardinality, and forms a clique
- if( d_testCliqueSize>=unsigned(cardinality+1) && d_splitsSize==0 ){
+ // Check if test clique has larger size than cardinality, and
+ // forms a clique.
+ if( d_testCliqueSize >= unsigned(cardinality+1) && d_splitsSize==0 ){
//test clique is a clique
- for( NodeBoolMap::iterator it = d_testClique.begin(); it != d_testClique.end(); ++it ){
+ for( NodeBoolMap::iterator it = d_testClique.begin();
+ it != d_testClique.end(); ++it ){
if( (*it).second ){
clique.push_back( (*it).first );
}
@@ -328,10 +387,12 @@ bool StrongSolverTheoryUF::SortModel::Region::check( Theory::Effort level, int c
return false;
}
-bool StrongSolverTheoryUF::SortModel::Region::getCandidateClique( int cardinality, std::vector< Node >& clique ) {
+bool Region::getCandidateClique( int cardinality, std::vector< Node >& clique )
+{
if( d_testCliqueSize>=unsigned(cardinality+1) ){
//test clique is a clique
- for( NodeBoolMap::iterator it = d_testClique.begin(); it != d_testClique.end(); ++it ){
+ for( NodeBoolMap::iterator it = d_testClique.begin();
+ it != d_testClique.end(); ++it ){
if( (*it).second ){
clique.push_back( (*it).first );
}
@@ -341,12 +402,13 @@ bool StrongSolverTheoryUF::SortModel::Region::getCandidateClique( int cardinalit
return false;
}
-void StrongSolverTheoryUF::SortModel::Region::getNumExternalDisequalities( std::map< Node, int >& num_ext_disequalities ){
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
+void Region::getNumExternalDisequalities(
+ std::map< Node, int >& num_ext_disequalities ){
+ for( Region::iterator it = begin(); it != end(); ++it ){
RegionNodeInfo* rni = it->second;
- if( rni->d_valid ){
- RegionNodeInfo::DiseqList* del = rni->d_disequalities[0];
- for( NodeBoolMap::iterator it2 = del->d_disequalities.begin(); it2 != del->d_disequalities.end(); ++it2 ){
+ if( rni->valid() ){
+ DiseqList* del = rni->get(0);
+ for( DiseqList::iterator it2 = del->begin(); it2 != del->end(); ++it2 ){
if( (*it2).second ){
num_ext_disequalities[ (*it2).first ]++;
}
@@ -355,32 +417,35 @@ void StrongSolverTheoryUF::SortModel::Region::getNumExternalDisequalities( std::
}
}
-void StrongSolverTheoryUF::SortModel::Region::debugPrint( const char* c, bool incClique ){
+void Region::debugPrint( const char* c, bool incClique ) {
Debug( c ) << "Num reps: " << d_reps_size << std::endl;
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
+ for( Region::iterator it = begin(); it != end(); ++it ){
RegionNodeInfo* rni = it->second;
- if( rni->d_valid ){
+ if( rni->valid() ){
Node n = it->first;
Debug( c ) << " " << n << std::endl;
for( int i=0; i<2; i++ ){
Debug( c ) << " " << ( i==0 ? "Ext" : "Int" ) << " disequal:";
- RegionNodeInfo::DiseqList* del = rni->d_disequalities[i];
- for( NodeBoolMap::iterator it2 = del->d_disequalities.begin(); it2 != del->d_disequalities.end(); ++it2 ){
+ DiseqList* del = rni->get(i);
+ for( DiseqList::iterator it2 = del->begin(); it2 != del->end(); ++it2 ){
if( (*it2).second ){
Debug( c ) << " " << (*it2).first;
}
}
- Debug( c ) << ", total = " << del->d_size << std::endl;
+ Debug( c ) << ", total = " << del->size() << std::endl;
}
}
}
- Debug( c ) << "Total disequal: " << d_total_diseq_external << " external," << std::endl;
- Debug( c ) << " " << d_total_diseq_internal<< " internal." << std::endl;
+ Debug( c ) << "Total disequal: " << d_total_diseq_external << " external,"
+ << std::endl;
+ Debug( c ) << " " << d_total_diseq_internal << " internal."
+ << std::endl;
if( incClique ){
Debug( c ) << "Candidate clique members: " << std::endl;
Debug( c ) << " ";
- for( NodeBoolMap::iterator it = d_testClique.begin(); it != d_testClique.end(); ++ it ){
+ for( NodeBoolMap::iterator it = d_testClique.begin();
+ it != d_testClique.end(); ++ it ){
if( (*it).second ){
Debug( c ) << (*it).first << " ";
}
@@ -388,7 +453,8 @@ void StrongSolverTheoryUF::SortModel::Region::debugPrint( const char* c, bool in
Debug( c ) << ", size = " << d_testCliqueSize << std::endl;
Debug( c ) << "Required splits: " << std::endl;
Debug( c ) << " ";
- for( NodeBoolMap::iterator it = d_splits.begin(); it != d_splits.end(); ++ it ){
+ for( NodeBoolMap::iterator it = d_splits.begin(); it != d_splits.end();
+ ++ it ){
if( (*it).second ){
Debug( c ) << (*it).first << " ";
}
@@ -397,17 +463,25 @@ void StrongSolverTheoryUF::SortModel::Region::debugPrint( const char* c, bool in
}
}
-
-
-
-
-
-
-
-StrongSolverTheoryUF::SortModel::SortModel( Node n, context::Context* c, context::UserContext* u, StrongSolverTheoryUF* thss ) : d_type( n.getType() ),
- d_thss( thss ), d_regions_index( c, 0 ), d_regions_map( c ), d_split_score( c ), d_disequalities_index( c, 0 ),
- d_reps( c, 0 ), d_conflict( c, false ), d_cardinality( c, 1 ), d_aloc_cardinality( u, 0 ),
- d_cardinality_assertions( c ), d_hasCard( c, false ), d_maxNegCard( c, 0 ), d_initialized( u, false ), d_lemma_cache( u ){
+SortModel::SortModel( Node n,
+ context::Context* c,
+ context::UserContext* u,
+ StrongSolverTheoryUF* thss )
+ : d_type( n.getType() )
+ , d_thss( thss )
+ , d_regions_index( c, 0 )
+ , d_regions_map( c )
+ , d_split_score( c )
+ , d_disequalities_index( c, 0 )
+ , d_reps( c, 0 )
+ , d_conflict( c, false )
+ , d_cardinality( c, 1 )
+ , d_aloc_cardinality( u, 0 )
+ , d_hasCard( c, false )
+ , d_maxNegCard( c, 0 )
+ , d_initialized( u, false )
+ , d_lemma_cache( u )
+{
d_cardinality_term = n;
//if( d_type.isSort() ){
// TypeEnumerator te(tn);
@@ -417,8 +491,17 @@ StrongSolverTheoryUF::SortModel::SortModel( Node n, context::Context* c, context
//}
}
+SortModel::~SortModel() {
+ for(std::vector<Region*>::iterator i = d_regions.begin();
+ i != d_regions.end(); ++i) {
+ Region* region = *i;
+ delete region;
+ }
+ d_regions.clear();
+}
+
/** initialize */
-void StrongSolverTheoryUF::SortModel::initialize( OutputChannel* out ){
+void SortModel::initialize( OutputChannel* out ){
if( !d_initialized ){
d_initialized = true;
allocateCardinality( out );
@@ -426,17 +509,20 @@ void StrongSolverTheoryUF::SortModel::initialize( OutputChannel* out ){
}
/** new node */
-void StrongSolverTheoryUF::SortModel::newEqClass( Node n ){
+void SortModel::newEqClass( Node n ){
if( !d_conflict ){
if( d_regions_map.find( n )==d_regions_map.end() ){
- //must generate totality axioms for every cardinality we have allocated thus far
- for( std::map< int, Node >::iterator it = d_cardinality_literal.begin(); it != d_cardinality_literal.end(); ++it ){
+ // Must generate totality axioms for every cardinality we have
+ // allocated thus far.
+ for( std::map< int, Node >::iterator it = d_cardinality_literal.begin();
+ it != d_cardinality_literal.end(); ++it ){
if( applyTotality( it->first ) ){
addTotalityAxiom( n, it->first, &d_thss->getOutputChannel() );
}
}
if( options::ufssTotality() ){
- //regions map will store whether we need to equate this term with a constant equivalence class
+ // Regions map will store whether we need to equate this term
+ // with a constant equivalence class.
if( std::find( d_totality_terms[0].begin(), d_totality_terms[0].end(), n )==d_totality_terms[0].end() ){
d_regions_map[n] = 0;
}else{
@@ -444,16 +530,20 @@ void StrongSolverTheoryUF::SortModel::newEqClass( Node n ){
}
}else{
if( !options::ufssRegions() ){
- //if not using regions, always add new equivalence classes to region index = 0
+ // If not using regions, always add new equivalence classes
+ // to region index = 0.
d_regions_index = 0;
}
d_regions_map[n] = d_regions_index;
- Debug("uf-ss") << "StrongSolverTheoryUF: New Eq Class " << n << std::endl;
- Debug("uf-ss-debug") << d_regions_index << " " << (int)d_regions.size() << std::endl;
+ Debug("uf-ss") << "StrongSolverTheoryUF: New Eq Class " << n
+ << std::endl;
+ Debug("uf-ss-debug") << d_regions_index << " "
+ << (int)d_regions.size() << std::endl;
if( d_regions_index<d_regions.size() ){
d_regions[ d_regions_index ]->debugPrint("uf-ss-debug",true);
- d_regions[ d_regions_index ]->d_valid = true;
- Assert( !options::ufssRegions() || d_regions[ d_regions_index ]->getNumReps()==0 );
+ d_regions[ d_regions_index ]->setValid(true);
+ Assert( !options::ufssRegions() ||
+ d_regions[ d_regions_index ]->getNumReps()==0 );
}else{
d_regions.push_back( new Region( this, d_thss->getSatContext() ) );
}
@@ -466,7 +556,7 @@ void StrongSolverTheoryUF::SortModel::newEqClass( Node n ){
}
/** merge */
-void StrongSolverTheoryUF::SortModel::merge( Node a, Node b ){
+void SortModel::merge( Node a, Node b ){
if( !d_conflict ){
if( options::ufssTotality() ){
if( d_regions_map[b]==-1 ){
@@ -476,7 +566,8 @@ void StrongSolverTheoryUF::SortModel::merge( Node a, Node b ){
}else{
//Assert( a==d_th->d_equalityEngine.getRepresentative( a ) );
//Assert( b==d_th->d_equalityEngine.getRepresentative( b ) );
- Debug("uf-ss") << "StrongSolverTheoryUF: Merging " << a << " = " << b << "..." << std::endl;
+ Debug("uf-ss") << "StrongSolverTheoryUF: Merging "
+ << a << " = " << b << "..." << std::endl;
if( a!=b ){
Assert( d_regions_map.find( a )!=d_regions_map.end() );
Assert( d_regions_map.find( b )!=d_regions_map.end() );
@@ -493,10 +584,15 @@ void StrongSolverTheoryUF::SortModel::merge( Node a, Node b ){
d_regions[ri]->setEqual( a, b );
checkRegion( ri );
}else{
- // either move a to d_regions[bi], or b to d_regions[ai]
- int aex = d_regions[ai]->d_nodes[a]->getNumInternalDisequalities() - getNumDisequalitiesToRegion( a, bi );
- int bex = d_regions[bi]->d_nodes[b]->getNumInternalDisequalities() - getNumDisequalitiesToRegion( b, ai );
- //based on which would produce the fewest number of external disequalities
+ // Either move a to d_regions[bi], or b to d_regions[ai].
+ RegionNodeInfo* a_region_info = d_regions[ai]->getRegionInfo(a);
+ RegionNodeInfo* b_region_info = d_regions[bi]->getRegionInfo(b);
+ int aex = ( a_region_info->getNumInternalDisequalities() -
+ getNumDisequalitiesToRegion( a, bi ) );
+ int bex = ( b_region_info->getNumInternalDisequalities() -
+ getNumDisequalitiesToRegion( b, ai ) );
+ // Based on which would produce the fewest number of
+ // external disequalities.
if( aex<bex ){
moveNode( a, bi );
d_regions[bi]->setEqual( a, b );
@@ -529,7 +625,7 @@ void StrongSolverTheoryUF::SortModel::merge( Node a, Node b ){
}
/** assert terms are disequal */
-void StrongSolverTheoryUF::SortModel::assertDisequal( Node a, Node b, Node reason ){
+void SortModel::assertDisequal( Node a, Node b, Node reason ){
if( !d_conflict ){
if( options::ufssTotality() ){
//do nothing
@@ -584,7 +680,7 @@ void StrongSolverTheoryUF::SortModel::assertDisequal( Node a, Node b, Node reaso
}
}
-bool StrongSolverTheoryUF::SortModel::areDisequal( Node a, Node b ) {
+bool SortModel::areDisequal( Node a, Node b ) {
Assert( a == d_thss->getTheory()->d_equalityEngine.getRepresentative( a ) );
Assert( b == d_thss->getTheory()->d_equalityEngine.getRepresentative( b ) );
if( d_regions_map.find( a )!=d_regions_map.end() &&
@@ -598,7 +694,7 @@ bool StrongSolverTheoryUF::SortModel::areDisequal( Node a, Node b ) {
}
/** check */
-void StrongSolverTheoryUF::SortModel::check( Theory::Effort level, OutputChannel* out ){
+void SortModel::check( Theory::Effort level, OutputChannel* out ){
if( level>=Theory::EFFORT_STANDARD && d_hasCard && !d_conflict ){
Debug("uf-ss") << "StrongSolverTheoryUF: Check " << level << " " << d_type << std::endl;
//Notice() << "StrongSolverTheoryUF: Check " << level << std::endl;
@@ -616,7 +712,7 @@ void StrongSolverTheoryUF::SortModel::check( Theory::Effort level, OutputChannel
if( !options::ufssTotality() ){
//do a check within each region
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
+ if( d_regions[i]->valid() ){
std::vector< Node > clique;
if( d_regions[i]->check( level, d_cardinality, clique ) ){
if( options::ufssMode()==UF_SS_FULL ){
@@ -637,7 +733,7 @@ void StrongSolverTheoryUF::SortModel::check( Theory::Effort level, OutputChannel
Trace("uf-ss-debug") << "Add splits?" << std::endl;
//see if we have any recommended splits from large regions
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid && d_regions[i]->getNumReps()>d_cardinality ){
+ if( d_regions[i]->valid() && d_regions[i]->getNumReps()>d_cardinality ){
//just add the clique lemma
if( level==Theory::EFFORT_FULL && options::ufssCliqueSplits() ){
std::vector< Node > clique;
@@ -661,18 +757,19 @@ void StrongSolverTheoryUF::SortModel::check( Theory::Effort level, OutputChannel
}
}
}
- //if no added lemmas, force continuation via combination of regions
+ //If no added lemmas, force continuation via combination of regions.
if( level==Theory::EFFORT_FULL ){
if( !addedLemma ){
- Trace("uf-ss-debug") << "No splits added. " << d_cardinality << std::endl;
+ Trace("uf-ss-debug") << "No splits added. " << d_cardinality
+ << std::endl;
Trace("uf-ss-si") << "Must combine region" << std::endl;
bool recheck = false;
if( options::sortInference()){
- //if sort inference is enabled, search for regions with same sort
+ //If sort inference is enabled, search for regions with same sort.
std::map< int, int > sortsFound;
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
- Node op = d_regions[i]->d_nodes.begin()->first;
+ if( d_regions[i]->valid() ){
+ Node op = d_regions[i]->frontKey();
int sort_id = d_thss->getSortInference()->getSortId(op);
if( sortsFound.find( sort_id )!=sortsFound.end() ){
combineRegions( sortsFound[sort_id], i );
@@ -687,7 +784,7 @@ void StrongSolverTheoryUF::SortModel::check( Theory::Effort level, OutputChannel
if( !recheck ) {
//naive strategy, force region combination involving the first valid region
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
+ if( d_regions[i]->valid() ){
int fcr = forceCombineRegion( i, false );
Trace("uf-ss-debug") << "Combined regions " << i << " " << fcr << std::endl;
if( options::ufssMode()==UF_SS_FULL || fcr!=-1 ){
@@ -708,26 +805,28 @@ void StrongSolverTheoryUF::SortModel::check( Theory::Effort level, OutputChannel
}
}
-void StrongSolverTheoryUF::SortModel::presolve() {
+void SortModel::presolve() {
d_initialized = false;
d_aloc_cardinality = 0;
}
-void StrongSolverTheoryUF::SortModel::propagate( Theory::Effort level, OutputChannel* out ){
+void SortModel::propagate( Theory::Effort level, OutputChannel* out ){
}
-Node StrongSolverTheoryUF::SortModel::getNextDecisionRequest(){
+Node SortModel::getNextDecisionRequest(){
//request the current cardinality as a decision literal, if not already asserted
for( int i=1; i<=d_aloc_cardinality; i++ ){
if( !d_hasCard || i<d_cardinality ){
Node cn = d_cardinality_literal[ i ];
Assert( !cn.isNull() );
- if( d_cardinality_assertions.find( cn )==d_cardinality_assertions.end() ){
+ bool value;
+ if( !d_thss->getTheory()->d_valuation.hasSatValue( cn, value ) ){
Trace("uf-ss-dec") << "UFSS : Get next decision " << d_type << " " << i << std::endl;
return cn;
}else{
- Trace("uf-ss-dec-debug") << " dec : " << cn << " already asserted " << d_cardinality_assertions[cn].get() << std::endl;
+ Trace("uf-ss-dec-debug") << " dec : " << cn << " already asserted " << value << std::endl;
+ Assert( !value );
}
}
}
@@ -737,7 +836,7 @@ Node StrongSolverTheoryUF::SortModel::getNextDecisionRequest(){
return Node::null();
}
-bool StrongSolverTheoryUF::SortModel::minimize( OutputChannel* out, TheoryModel* m ){
+bool SortModel::minimize( OutputChannel* out, TheoryModel* m ){
if( options::ufssTotality() ){
//do nothing
}else{
@@ -774,7 +873,7 @@ bool StrongSolverTheoryUF::SortModel::minimize( OutputChannel* out, TheoryModel*
// if two equivalence classes are neither equal nor disequal, add a split
int validRegionIndex = -1;
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
+ if( d_regions[i]->valid() ){
if( validRegionIndex!=-1 ){
combineRegions( validRegionIndex, i );
if( addSplit( d_regions[validRegionIndex], out )!=0 ){
@@ -798,11 +897,11 @@ bool StrongSolverTheoryUF::SortModel::minimize( OutputChannel* out, TheoryModel*
}
-int StrongSolverTheoryUF::SortModel::getNumDisequalitiesToRegion( Node n, int ri ){
+int SortModel::getNumDisequalitiesToRegion( Node n, int ri ){
int ni = d_regions_map[n];
int counter = 0;
- Region::RegionNodeInfo::DiseqList* del = d_regions[ni]->d_nodes[n]->d_disequalities[0];
- for( NodeBoolMap::iterator it = del->d_disequalities.begin(); it != del->d_disequalities.end(); ++it ){
+ DiseqList* del = d_regions[ni]->getRegionInfo(n)->get(0);
+ for( DiseqList::iterator it = del->begin(); it != del->end(); ++it ){
if( (*it).second ){
if( d_regions_map[ (*it).first ]==ri ){
counter++;
@@ -812,12 +911,14 @@ int StrongSolverTheoryUF::SortModel::getNumDisequalitiesToRegion( Node n, int ri
return counter;
}
-void StrongSolverTheoryUF::SortModel::getDisequalitiesToRegions( int ri, std::map< int, int >& regions_diseq ){
- for( std::map< Node, Region::RegionNodeInfo* >::iterator it = d_regions[ri]->d_nodes.begin();
- it != d_regions[ri]->d_nodes.end(); ++it ){
- if( it->second->d_valid ){
- Region::RegionNodeInfo::DiseqList* del = it->second->d_disequalities[0];
- for( NodeBoolMap::iterator it2 = del->d_disequalities.begin(); it2 != del->d_disequalities.end(); ++it2 ){
+void SortModel::getDisequalitiesToRegions(int ri,
+ std::map< int, int >& regions_diseq)
+{
+ Region* region = d_regions[ri];
+ for(Region::iterator it = region->begin(); it != region->end(); ++it ){
+ if( it->second->valid() ){
+ DiseqList* del = it->second->get(0);
+ for( DiseqList::iterator it2 = del->begin(); it2 != del->end(); ++it2 ){
if( (*it2).second ){
Assert( isValid( d_regions_map[ (*it2).first ] ) );
//Notice() << "Found disequality with " << (*it2).first << ", region = " << d_regions_map[ (*it2).first ] << std::endl;
@@ -828,7 +929,7 @@ void StrongSolverTheoryUF::SortModel::getDisequalitiesToRegions( int ri, std::ma
}
}
-void StrongSolverTheoryUF::SortModel::setSplitScore( Node n, int s ){
+void SortModel::setSplitScore( Node n, int s ){
if( d_split_score.find( n )!=d_split_score.end() ){
int ss = d_split_score[ n ];
d_split_score[ n ] = s>ss ? s : ss;
@@ -840,13 +941,13 @@ void StrongSolverTheoryUF::SortModel::setSplitScore( Node n, int s ){
}
}
-void StrongSolverTheoryUF::SortModel::assertCardinality( OutputChannel* out, int c, bool val ){
+void SortModel::assertCardinality( OutputChannel* out, int c, bool val ){
if( !d_conflict ){
- Trace("uf-ss-assert") << "Assert cardinality " << d_type << " " << c << " " << val << " level = ";
- Trace("uf-ss-assert") << d_thss->getTheory()->d_valuation.getAssertionLevel() << std::endl;
+ Trace("uf-ss-assert")
+ << "Assert cardinality "<< d_type << " " << c << " " << val << " level = "
+ << d_thss->getTheory()->d_valuation.getAssertionLevel() << std::endl;
Assert( c>0 );
Node cl = getCardinalityLiteral( c );
- d_cardinality_assertions[ cl ] = val;
if( val ){
bool doCheckRegions = !d_hasCard;
bool prevHasCard = d_hasCard;
@@ -861,7 +962,7 @@ void StrongSolverTheoryUF::SortModel::assertCardinality( OutputChannel* out, int
//should check all regions now
if( doCheckRegions ){
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
+ if( d_regions[i]->valid() ){
checkRegion( i );
if( d_conflict ){
return;
@@ -890,8 +991,9 @@ void StrongSolverTheoryUF::SortModel::assertCardinality( OutputChannel* out, int
bool needsCard = true;
for( std::map< int, Node >::iterator it = d_cardinality_literal.begin(); it!=d_cardinality_literal.end(); ++it ){
if( it->first<=d_aloc_cardinality.get() ){
- if( d_cardinality_assertions.find( it->second )==d_cardinality_assertions.end() ){
- Debug("fmf-card-debug") << "..does not need allocate because of " << it->second << std::endl;
+ bool value;
+ if( !d_thss->getTheory()->d_valuation.hasSatValue( it->second, value ) ){
+ Debug("fmf-card-debug") << "..does not need allocate because we are waiting for " << it->second << std::endl;
needsCard = false;
break;
}
@@ -912,7 +1014,7 @@ void StrongSolverTheoryUF::SortModel::assertCardinality( OutputChannel* out, int
}
}
-void StrongSolverTheoryUF::SortModel::checkRegion( int ri, bool checkCombine ){
+void SortModel::checkRegion( int ri, bool checkCombine ){
if( isValid(ri) && d_hasCard ){
Assert( d_cardinality>0 );
if( checkCombine && d_regions[ri]->getMustCombine( d_cardinality ) ){
@@ -941,10 +1043,10 @@ void StrongSolverTheoryUF::SortModel::checkRegion( int ri, bool checkCombine ){
}
}
-int StrongSolverTheoryUF::SortModel::forceCombineRegion( int ri, bool useDensity ){
+int SortModel::forceCombineRegion( int ri, bool useDensity ){
if( !useDensity ){
for( int i=0; i<(int)d_regions_index; i++ ){
- if( ri!=i && d_regions[i]->d_valid ){
+ if( ri!=i && d_regions[i]->valid() ){
return combineRegions( ri, i );
}
}
@@ -981,7 +1083,7 @@ int StrongSolverTheoryUF::SortModel::forceCombineRegion( int ri, bool useDensity
}
-int StrongSolverTheoryUF::SortModel::combineRegions( int ai, int bi ){
+int SortModel::combineRegions( int ai, int bi ){
#ifdef COMBINE_REGIONS_SMALL_INTO_LARGE
if( d_regions[ai]->getNumReps()<d_regions[bi]->getNumReps() ){
return combineRegions( bi, ai );
@@ -989,19 +1091,20 @@ int StrongSolverTheoryUF::SortModel::combineRegions( int ai, int bi ){
#endif
Debug("uf-ss-region") << "uf-ss: Combine Region #" << bi << " with Region #" << ai << std::endl;
Assert( isValid( ai ) && isValid( bi ) );
- for( std::map< Node, Region::RegionNodeInfo* >::iterator it = d_regions[bi]->d_nodes.begin(); it != d_regions[bi]->d_nodes.end(); ++it ){
+ Region* region_bi = d_regions[bi];
+ for(Region::iterator it = region_bi->begin(); it != region_bi->end(); ++it){
Region::RegionNodeInfo* rni = it->second;
- if( rni->d_valid ){
+ if( rni->valid() ){
d_regions_map[ it->first ] = ai;
}
}
//update regions disequal DO_THIS?
d_regions[ai]->combine( d_regions[bi] );
- d_regions[bi]->d_valid = false;
+ d_regions[bi]->setValid( false );
return ai;
}
-void StrongSolverTheoryUF::SortModel::moveNode( Node n, int ri ){
+void SortModel::moveNode( Node n, int ri ){
Debug("uf-ss-region") << "uf-ss: Move node " << n << " to Region #" << ri << std::endl;
Assert( isValid( d_regions_map[ n ] ) );
Assert( isValid( ri ) );
@@ -1010,7 +1113,7 @@ void StrongSolverTheoryUF::SortModel::moveNode( Node n, int ri ){
d_regions_map[n] = ri;
}
-void StrongSolverTheoryUF::SortModel::allocateCardinality( OutputChannel* out ){
+void SortModel::allocateCardinality( OutputChannel* out ){
if( d_aloc_cardinality>0 ){
Trace("uf-ss-fmf") << "No model of size " << d_aloc_cardinality << " exists for type " << d_type << " in this branch" << std::endl;
}
@@ -1028,20 +1131,26 @@ void StrongSolverTheoryUF::SortModel::allocateCardinality( OutputChannel* out ){
//allocate the lowest such that it is not asserted
Node cl;
+ bool increment;
do {
+ increment = false;
d_aloc_cardinality = d_aloc_cardinality + 1;
cl = getCardinalityLiteral( d_aloc_cardinality );
- }while( d_cardinality_assertions.find( cl )!=d_cardinality_assertions.end() && !d_cardinality_assertions[cl] );
- //if one is already asserted postively, abort
- if( d_cardinality_assertions.find( cl )!=d_cardinality_assertions.end() ){
- return;
- }
+ bool value;
+ if( d_thss->getTheory()->d_valuation.hasSatValue( cl, value ) ){
+ if( value ){
+ //if one is already asserted postively, abort
+ return;
+ }else{
+ increment = true;
+ }
+ }
+ }while( increment );
//check for abort case
if( options::ufssAbortCardinality()==d_aloc_cardinality ){
- //abort here DO_THIS
Message() << "Maximum cardinality reached." << std::endl;
- exit( 0 );
+ exit( 1 );
}else{
if( applyTotality( d_aloc_cardinality ) ){
//must generate new cardinality lemma term
@@ -1093,11 +1202,12 @@ void StrongSolverTheoryUF::SortModel::allocateCardinality( OutputChannel* out ){
}
}
-int StrongSolverTheoryUF::SortModel::addSplit( Region* r, OutputChannel* out ){
+int SortModel::addSplit( Region* r, OutputChannel* out ){
Node s;
if( r->hasSplits() ){
//take the first split you find
- for( NodeBoolMap::iterator it = r->d_splits.begin(); it != r->d_splits.end(); ++it ){
+ for( Region::split_iterator it = r->begin_splits();
+ it != r->end_splits(); ++it ){
if( (*it).second ){
s = (*it).first;
break;
@@ -1106,13 +1216,16 @@ int StrongSolverTheoryUF::SortModel::addSplit( Region* r, OutputChannel* out ){
Assert( s!=Node::null() );
}else{
if( options::ufssMode()!=UF_SS_FULL ){
- //since candidate clique is not reported, we may need to find splits manually
- for ( std::map< Node, Region::RegionNodeInfo* >::iterator it = r->d_nodes.begin(); it != r->d_nodes.end(); ++it ){
- if ( it->second->d_valid ){
- for ( std::map< Node, Region::RegionNodeInfo* >::iterator it2 = r->d_nodes.begin(); it2 != r->d_nodes.end(); ++it2 ){
- if ( it->second!=it2->second && it2->second->d_valid ){
+ // Since candidate clique is not reported, we may need to find
+ // splits manually.
+ for ( Region::iterator it = r->begin(); it != r->end(); ++it ){
+ if ( it->second->valid() ){
+ for ( Region::iterator it2 = r->begin(); it2 != r->end(); ++it2 ){
+ if ( it->second!=it2->second && it2->second->valid() ){
if( !r->isDisequal( it->first, it2->first, 1 ) ){
- s = NodeManager::currentNM()->mkNode( EQUAL, it->first, it2->first );
+ Node it_node = it->first;
+ Node it2_node = it2->first;
+ s = it_node.eqNode(it2_node);
}
}
}
@@ -1128,7 +1241,8 @@ int StrongSolverTheoryUF::SortModel::addSplit( Region* r, OutputChannel* out ){
Node b_t = NodeManager::currentNM()->mkConst( true );
Node b_f = NodeManager::currentNM()->mkConst( false );
if( ss==b_f ){
- Trace("uf-ss-lemma") << "....Assert disequal directly : " << s[0] << " " << s[1] << std::endl;
+ Trace("uf-ss-lemma") << "....Assert disequal directly : "
+ << s[0] << " " << s[1] << std::endl;
assertDisequal( s[0], s[1], b_t );
return -1;
}else{
@@ -1165,7 +1279,7 @@ int StrongSolverTheoryUF::SortModel::addSplit( Region* r, OutputChannel* out ){
}
-void StrongSolverTheoryUF::SortModel::addCliqueLemma( std::vector< Node >& clique, OutputChannel* out ){
+void SortModel::addCliqueLemma( std::vector< Node >& clique, OutputChannel* out ){
Assert( d_hasCard );
Assert( d_cardinality>0 );
while( clique.size()>size_t(d_cardinality+1) ){
@@ -1318,7 +1432,7 @@ void StrongSolverTheoryUF::SortModel::addCliqueLemma( std::vector< Node >& cliqu
}
}
-void StrongSolverTheoryUF::SortModel::addTotalityAxiom( Node n, int cardinality, OutputChannel* out ){
+void SortModel::addTotalityAxiom( Node n, int cardinality, OutputChannel* out ){
if( std::find( d_totality_terms[0].begin(), d_totality_terms[0].end(), n )==d_totality_terms[0].end() ){
if( std::find( d_totality_lems[n].begin(), d_totality_lems[n].end(), cardinality ) == d_totality_lems[n].end() ){
d_totality_lems[n].push_back( cardinality );
@@ -1346,7 +1460,7 @@ void StrongSolverTheoryUF::SortModel::addTotalityAxiom( Node n, int cardinality,
for( unsigned j=0; j<(d_sym_break_terms[n.getType()][sort_id].size()-1); j++ ){
eqs.push_back( d_sym_break_terms[n.getType()][sort_id][j].eqNode( getTotalityLemmaTerm( cardinality, i-1 ) ) );
}
- Node ax = NodeManager::currentNM()->mkNode( OR, eqs );
+ Node ax = eqs.size()==1 ? eqs[0] : NodeManager::currentNM()->mkNode( OR, eqs );
Node lem = NodeManager::currentNM()->mkNode( IMPLIES, eq, ax );
Trace("uf-ss-lemma") << "*** Add (canonicity) totality axiom " << lem << std::endl;
d_thss->getOutputChannel().lemma( lem );
@@ -1369,7 +1483,7 @@ void StrongSolverTheoryUF::SortModel::addTotalityAxiom( Node n, int cardinality,
}
}
-void StrongSolverTheoryUF::SortModel::addClique( int c, std::vector< Node >& clique ) {
+void SortModel::addClique( int c, std::vector< Node >& clique ) {
//if( d_clique_trie[c].add( clique ) ){
// d_cliques[ c ].push_back( clique );
//}
@@ -1377,20 +1491,20 @@ void StrongSolverTheoryUF::SortModel::addClique( int c, std::vector< Node >& cli
/** apply totality */
-bool StrongSolverTheoryUF::SortModel::applyTotality( int cardinality ){
+bool SortModel::applyTotality( int cardinality ){
return options::ufssTotality() || cardinality<=options::ufssTotalityLimited();
// || ( options::ufssModelInference() && !d_totality_terms[cardinality].empty() );
}
/** get totality lemma terms */
-Node StrongSolverTheoryUF::SortModel::getTotalityLemmaTerm( int cardinality, int i ){
+Node SortModel::getTotalityLemmaTerm( int cardinality, int i ){
return d_totality_terms[0][i];
//}else{
// return d_totality_terms[cardinality][i];
//}
}
-void StrongSolverTheoryUF::SortModel::simpleCheckCardinality() {
+void SortModel::simpleCheckCardinality() {
if( d_maxNegCard.get()!=0 && d_hasCard.get() && d_cardinality.get()<d_maxNegCard.get() ){
Node lem = NodeManager::currentNM()->mkNode( AND, getCardinalityLiteral( d_cardinality.get() ),
getCardinalityLiteral( d_maxNegCard.get() ).negate() );
@@ -1400,7 +1514,7 @@ void StrongSolverTheoryUF::SortModel::simpleCheckCardinality() {
}
}
-bool StrongSolverTheoryUF::SortModel::doSendLemma( Node lem ) {
+bool SortModel::doSendLemma( Node lem ) {
if( d_lemma_cache.find( lem )==d_lemma_cache.end() ){
d_lemma_cache[lem] = true;
d_thss->getOutputChannel().lemma( lem );
@@ -1410,32 +1524,36 @@ bool StrongSolverTheoryUF::SortModel::doSendLemma( Node lem ) {
}
}
-void StrongSolverTheoryUF::SortModel::debugPrint( const char* c ){
+void SortModel::debugPrint( const char* c ){
Debug( c ) << "-- Conflict Find:" << std::endl;
Debug( c ) << "Number of reps = " << d_reps << std::endl;
Debug( c ) << "Cardinality req = " << d_cardinality << std::endl;
unsigned debugReps = 0;
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
+ Region* region = d_regions[i];
+ if( region->valid() ){
Debug( c ) << "Region #" << i << ": " << std::endl;
- d_regions[i]->debugPrint( c, true );
+ region->debugPrint( c, true );
Debug( c ) << std::endl;
- for( std::map< Node, Region::RegionNodeInfo* >::iterator it = d_regions[i]->d_nodes.begin(); it != d_regions[i]->d_nodes.end(); ++it ){
- if( it->second->d_valid ){
+ for( Region::iterator it = region->begin(); it != region->end(); ++it ){
+ if( it->second->valid() ){
if( d_regions_map[ it->first ]!=i ){
- Debug( c ) << "***Bad regions map : " << it->first << " " << d_regions_map[ it->first ].get() << std::endl;
+ Debug( c ) << "***Bad regions map : " << it->first
+ << " " << d_regions_map[ it->first ].get() << std::endl;
}
}
}
- debugReps += d_regions[i]->getNumReps();
+ debugReps += region->getNumReps();
}
}
+
if( debugReps!=d_reps ){
- Debug( c ) << "***Bad reps: " << d_reps << ", actual = " << debugReps << std::endl;
+ Debug( c ) << "***Bad reps: " << d_reps << ", "
+ << "actual = " << debugReps << std::endl;
}
}
-bool StrongSolverTheoryUF::SortModel::debugModel( TheoryModel* m ){
+bool SortModel::debugModel( TheoryModel* m ){
if( Trace.isOn("uf-ss-warn") ){
std::vector< Node > eqcs;
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( m->d_equalityEngine );
@@ -1503,27 +1621,42 @@ bool StrongSolverTheoryUF::SortModel::debugModel( TheoryModel* m ){
return true;
}
-int StrongSolverTheoryUF::SortModel::getNumRegions(){
+int SortModel::getNumRegions(){
int count = 0;
for( int i=0; i<(int)d_regions_index; i++ ){
- if( d_regions[i]->d_valid ){
+ if( d_regions[i]->valid() ){
count++;
}
}
return count;
}
-Node StrongSolverTheoryUF::SortModel::getCardinalityLiteral( int c ) {
- if( d_cardinality_literal.find( c )==d_cardinality_literal.end() ){
- d_cardinality_literal[c] = NodeManager::currentNM()->mkNode( CARDINALITY_CONSTRAINT, d_cardinality_term,
- NodeManager::currentNM()->mkConst( Rational( c ) ) );
+Node SortModel::getCardinalityLiteral( int c ) {
+ if( d_cardinality_literal.find(c) == d_cardinality_literal.end() ){
+ Node c_as_rational = NodeManager::currentNM()->mkConst(Rational(c));
+ d_cardinality_literal[c] =
+ NodeManager::currentNM()->mkNode(CARDINALITY_CONSTRAINT,
+ d_cardinality_term,
+ c_as_rational);
+
}
return d_cardinality_literal[c];
}
-StrongSolverTheoryUF::StrongSolverTheoryUF(context::Context* c, context::UserContext* u, OutputChannel& out, TheoryUF* th) :
-d_out( &out ), d_th( th ), d_conflict( c, false ), d_rep_model(), d_aloc_com_card( u, 0 ), d_com_card_assertions( c ), d_min_pos_com_card( c, -1 ),
-d_card_assertions_eqv_lemma( u ), d_min_pos_tn_master_card( c, -1 ), d_rel_eqc( c )
+StrongSolverTheoryUF::StrongSolverTheoryUF(context::Context* c,
+ context::UserContext* u,
+ OutputChannel& out,
+ TheoryUF* th)
+ : d_out( &out )
+ , d_th( th )
+ , d_conflict( c, false )
+ , d_rep_model()
+ , d_aloc_com_card( u, 0 )
+ , d_com_card_assertions( c )
+ , d_min_pos_com_card( c, -1 )
+ , d_card_assertions_eqv_lemma( u )
+ , d_min_pos_tn_master_card( c, -1 )
+ , d_rel_eqc( c )
{
if( options::ufssDiseqPropagation() ){
d_deq_prop = new DisequalityPropagator( th->getQuantifiersEngine(), this );
@@ -1899,7 +2032,7 @@ void StrongSolverTheoryUF::preRegisterTerm( TNode n ){
//}
-StrongSolverTheoryUF::SortModel* StrongSolverTheoryUF::getSortModel( Node n ){
+SortModel* StrongSolverTheoryUF::getSortModel( Node n ){
TypeNode tn = n.getType();
std::map< TypeNode, SortModel* >::iterator it = d_rep_model.find( tn );
//pre-register the type if not done already
@@ -1914,9 +2047,7 @@ StrongSolverTheoryUF::SortModel* StrongSolverTheoryUF::getSortModel( Node n ){
}
}
-void StrongSolverTheoryUF::notifyRestart(){
-
-}
+void StrongSolverTheoryUF::notifyRestart(){}
/** get cardinality for sort */
int StrongSolverTheoryUF::getCardinality( Node n ) {
@@ -2021,27 +2152,31 @@ void StrongSolverTheoryUF::checkCombinedCardinality() {
conf.push_back( d_rep_model[d_tn_mono_master]->getCardinalityLiteral( mc ) );
conf.push_back( d_rep_model[maxSlaveType]->getCardinalityLiteral( maxMonoSlave ).negate() );
Node cf = NodeManager::currentNM()->mkNode( AND, conf );
- Trace("uf-ss-lemma") << "*** Combined monotone cardinality conflict : " << cf << std::endl;
- Trace("uf-ss-com-card") << "*** Combined monotone cardinality conflict : " << cf << std::endl;
+ Trace("uf-ss-lemma") << "*** Combined monotone cardinality conflict"
+ << " : " << cf << std::endl;
+ Trace("uf-ss-com-card") << "*** Combined monotone cardinality conflict"
+ << " : " << cf << std::endl;
getOutputChannel().conflict( cf );
d_conflict.set( true );
return;
}
}
- if( d_min_pos_com_card.get()!=-1 && totalCombinedCard>d_min_pos_com_card.get() ){
+ int cc = d_min_pos_com_card.get();
+ if( cc !=-1 && totalCombinedCard > cc ){
//conflict
- int cc = d_min_pos_com_card.get();
- Assert( d_com_card_literal.find( cc )!=d_com_card_literal.end() );
+ Assert( d_com_card_literal.find( cc ) != d_com_card_literal.end() );
Node com_lit = d_com_card_literal[cc];
- Assert( d_com_card_assertions.find( com_lit )!=d_com_card_assertions.end() );
+ Assert(d_com_card_assertions.find(com_lit)!=d_com_card_assertions.end());
Assert( d_com_card_assertions[com_lit] );
std::vector< Node > conf;
conf.push_back( com_lit );
int totalAdded = 0;
- for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin(); it != d_rep_model.end(); ++it ){
+ for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin();
+ it != d_rep_model.end(); ++it ){
bool doAdd = true;
if( options::ufssFairnessMonotone() ){
- std::map< TypeNode, bool >::iterator its = d_tn_mono_slave.find( it->first );
+ std::map< TypeNode, bool >::iterator its =
+ d_tn_mono_slave.find( it->first );
if( its!=d_tn_mono_slave.end() && its->second ){
doAdd = false;
}
@@ -2058,8 +2193,10 @@ void StrongSolverTheoryUF::checkCombinedCardinality() {
}
}
Node cf = NodeManager::currentNM()->mkNode( AND, conf );
- Trace("uf-ss-lemma") << "*** Combined cardinality conflict : " << cf << std::endl;
- Trace("uf-ss-com-card") << "*** Combined cardinality conflict : " << cf << std::endl;
+ Trace("uf-ss-lemma") << "*** Combined cardinality conflict : " << cf
+ << std::endl;
+ Trace("uf-ss-com-card") << "*** Combined cardinality conflict : " << cf
+ << std::endl;
getOutputChannel().conflict( cf );
d_conflict.set( true );
}
@@ -2113,8 +2250,10 @@ StrongSolverTheoryUF::Statistics::~Statistics(){
}
-DisequalityPropagator::DisequalityPropagator(QuantifiersEngine* qe, StrongSolverTheoryUF* ufss) :
- d_qe(qe), d_ufss(ufss){
+DisequalityPropagator::DisequalityPropagator(QuantifiersEngine* qe,
+ StrongSolverTheoryUF* ufss)
+ : d_qe(qe), d_ufss(ufss)
+{
d_true = NodeManager::currentNM()->mkConst( true );
d_false = NodeManager::currentNM()->mkConst( false );
}
@@ -2182,3 +2321,7 @@ DisequalityPropagator::Statistics::Statistics():
DisequalityPropagator::Statistics::~Statistics(){
smtStatisticsRegistry()->unregisterStat(& d_propagations);
}
+
+}/* CVC4::theory namespace::uf */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
diff --git a/src/theory/uf/theory_uf_strong_solver.h b/src/theory/uf/theory_uf_strong_solver.h
index db4c50423..11f0664f3 100644
--- a/src/theory/uf/theory_uf_strong_solver.h
+++ b/src/theory/uf/theory_uf_strong_solver.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_strong_solver.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Andrew Reynolds
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Theory uf strong solver
**/
@@ -25,17 +25,19 @@
#include "util/statistics_registry.h"
namespace CVC4 {
-
class SortInference;
-
namespace theory {
-
class SubsortSymmetryBreaker;
-
namespace uf {
-
class TheoryUF;
class DisequalityPropagator;
+} /* namespace CVC4::theory::uf */
+} /* namespace CVC4::theory */
+} /* namespace CVC4 */
+
+namespace CVC4 {
+namespace theory {
+namespace uf {
class StrongSolverTheoryUF{
protected:
@@ -44,83 +46,135 @@ protected:
typedef context::CDHashMap<Node, Node, NodeHashFunction> NodeNodeMap;
typedef context::CDHashMap<TypeNode, bool, TypeNodeHashFunction> TypeNodeBoolMap;
public:
- /** information for incremental conflict/clique finding for a particular sort */
+ /**
+ * Information for incremental conflict/clique finding for a
+ * particular sort.
+ */
class SortModel {
private:
std::map< Node, std::vector< int > > d_totality_lems;
std::map< TypeNode, std::map< int, std::vector< Node > > > d_sym_break_terms;
std::map< Node, int > d_sym_break_index;
public:
- /** a partition of the current equality graph for which cliques can occur internally */
+
+ /**
+ * A partition of the current equality graph for which cliques
+ * can occur internally.
+ */
class Region {
public:
- /** conflict find pointer */
- SortModel* d_cf;
/** information stored about each node in region */
class RegionNodeInfo {
public:
/** disequality list for node */
class DiseqList {
public:
- DiseqList( context::Context* c ) : d_size( c, 0 ), d_disequalities( c ){}
+ DiseqList( context::Context* c )
+ : d_size( c, 0 ), d_disequalities( c ) {}
~DiseqList(){}
- context::CDO< unsigned > d_size;
- NodeBoolMap d_disequalities;
+
void setDisequal( Node n, bool valid ){
- Assert( d_disequalities.find( n )==d_disequalities.end() || d_disequalities[n]!=valid );
+ Assert( (!isSet(n)) || getDisequalityValue(n) != valid );
d_disequalities[ n ] = valid;
d_size = d_size + ( valid ? 1 : -1 );
}
- };
- private:
- DiseqList d_internal;
- DiseqList d_external;
+ bool isSet(Node n) const {
+ return d_disequalities.find(n) != d_disequalities.end();
+ }
+ bool getDisequalityValue(Node n) const {
+ Assert(isSet(n));
+ return (*(d_disequalities.find(n))).second;
+ }
+
+ int size() const { return d_size; }
+
+ typedef NodeBoolMap::iterator iterator;
+ iterator begin() { return d_disequalities.begin(); }
+ iterator end() { return d_disequalities.end(); }
+
+ private:
+ context::CDO< int > d_size;
+ NodeBoolMap d_disequalities;
+ }; /* class DiseqList */
public:
/** constructor */
- RegionNodeInfo( context::Context* c ) :
- d_internal( c ), d_external( c ), d_valid( c, true ){
+ RegionNodeInfo( context::Context* c )
+ : d_internal(c), d_external(c), d_valid(c, true) {
d_disequalities[0] = &d_internal;
d_disequalities[1] = &d_external;
}
~RegionNodeInfo(){}
+
+ int getNumDisequalities() const {
+ return d_disequalities[0]->size() + d_disequalities[1]->size();
+ }
+ int getNumExternalDisequalities() const {
+ return d_disequalities[0]->size();
+ }
+ int getNumInternalDisequalities() const {
+ return d_disequalities[1]->size();
+ }
+
+ bool valid() const { return d_valid; }
+ void setValid(bool valid) { d_valid = valid; }
+
+ DiseqList* get(unsigned i) { return d_disequalities[i]; }
+
+ private:
+ DiseqList d_internal;
+ DiseqList d_external;
context::CDO< bool > d_valid;
DiseqList* d_disequalities[2];
+ }; /* class RegionNodeInfo */
- int getNumDisequalities() { return d_disequalities[0]->d_size + d_disequalities[1]->d_size; }
- int getNumExternalDisequalities() { return d_disequalities[0]->d_size; }
- int getNumInternalDisequalities() { return d_disequalities[1]->d_size; }
- };
- ///** end class RegionNodeInfo */
private:
+ /** conflict find pointer */
+ SortModel* d_cf;
+
context::CDO< unsigned > d_testCliqueSize;
context::CDO< unsigned > d_splitsSize;
- public:
//a postulated clique
NodeBoolMap d_testClique;
//disequalities needed for this clique to happen
NodeBoolMap d_splits;
- private:
//number of valid representatives in this region
context::CDO< unsigned > d_reps_size;
//total disequality size (external)
context::CDO< unsigned > d_total_diseq_external;
//total disequality size (internal)
context::CDO< unsigned > d_total_diseq_internal;
- private:
/** set rep */
void setRep( Node n, bool valid );
- public:
- //constructor
- Region( SortModel* cf, context::Context* c ) : d_cf( cf ), d_testCliqueSize( c, 0 ),
- d_splitsSize( c, 0 ), d_testClique( c ), d_splits( c ), d_reps_size( c, 0 ),
- d_total_diseq_external( c, 0 ), d_total_diseq_internal( c, 0 ), d_valid( c, true ) {
- }
- virtual ~Region(){}
//region node infomation
std::map< Node, RegionNodeInfo* > d_nodes;
//whether region is valid
context::CDO< bool > d_valid;
+
public:
+ //constructor
+ Region( SortModel* cf, context::Context* c );
+ virtual ~Region();
+
+ typedef std::map< Node, RegionNodeInfo* >::iterator iterator;
+ iterator begin() { return d_nodes.begin(); }
+ iterator end() { return d_nodes.end(); }
+
+ typedef NodeBoolMap::iterator split_iterator;
+ split_iterator begin_splits() { return d_splits.begin(); }
+ split_iterator end_splits() { return d_splits.end(); }
+
+ /** Returns a RegionInfo. */
+ RegionNodeInfo* getRegionInfo(Node n) {
+ Assert(d_nodes.find(n) != d_nodes.end());
+ return (* (d_nodes.find(n))).second;
+ }
+
+ /** Returns whether or not d_valid is set in current context. */
+ bool valid() const { return d_valid; }
+
+ /** Sets d_valid to the value valid in the current context.*/
+ void setValid(bool valid) { d_valid = valid; }
+
/** add rep */
void addRep( Node n );
//take node from region
@@ -131,13 +185,14 @@ public:
void setEqual( Node a, Node b );
//set n1 != n2 to value 'valid', type is whether it is internal/external
void setDisequal( Node n1, Node n2, int type, bool valid );
- public:
//get num reps
int getNumReps() { return d_reps_size; }
//get test clique size
int getTestCliqueSize() { return d_testCliqueSize; }
// has representative
- bool hasRep( Node n ) { return d_nodes.find( n )!=d_nodes.end() && d_nodes[n]->d_valid; }
+ bool hasRep( Node n ) {
+ return d_nodes.find(n) != d_nodes.end() && d_nodes[n]->valid();
+ }
// is disequal
bool isDisequal( Node n1, Node n2, int type );
/** get must merge */
@@ -145,15 +200,18 @@ public:
/** has splits */
bool hasSplits() { return d_splitsSize>0; }
/** get external disequalities */
- void getNumExternalDisequalities( std::map< Node, int >& num_ext_disequalities );
- public:
+ void getNumExternalDisequalities(std::map< Node, int >& num_ext_disequalities );
/** check for cliques */
bool check( Theory::Effort level, int cardinality, std::vector< Node >& clique );
/** get candidate clique */
bool getCandidateClique( int cardinality, std::vector< Node >& clique );
//print debug
void debugPrint( const char* c, bool incClique = false );
- };
+
+ // Returns the first key in d_nodes.
+ Node frontKey() const { return d_nodes.begin()->first; }
+ }; /* class Region */
+
private:
/** the type this model is for */
TypeNode d_type;
@@ -173,16 +231,17 @@ public:
std::vector< Node > d_disequalities;
/** number of representatives in all regions */
context::CDO< unsigned > d_reps;
- private:
+
/** get number of disequalities from node n to region ri */
int getNumDisequalitiesToRegion( Node n, int ri );
/** get number of disequalities from Region r to other regions */
void getDisequalitiesToRegions( int ri, std::map< int, int >& regions_diseq );
/** is valid */
- bool isValid( int ri ) { return ri>=0 && ri<(int)d_regions_index && d_regions[ ri ]->d_valid; }
+ bool isValid( int ri ) {
+ return ri>=0 && ri<(int)d_regions_index && d_regions[ ri ]->valid();
+ }
/** set split score */
void setSplitScore( Node n, int s );
- private:
/** check if we need to combine region ri */
void checkRegion( int ri, bool checkCombine = true );
/** force combine region */
@@ -191,18 +250,21 @@ public:
int combineRegions( int ai, int bi );
/** move node n to region ri */
void moveNode( Node n, int ri );
- private:
/** allocate cardinality */
void allocateCardinality( OutputChannel* out );
- /** add split 0 = no split, -1 = entailed disequality added, 1 = split added */
+ /**
+ * Add splits. Returns
+ * 0 = no split,
+ * -1 = entailed disequality added, or
+ * 1 = split added.
+ */
int addSplit( Region* r, OutputChannel* out );
/** add clique lemma */
void addCliqueLemma( std::vector< Node >& clique, OutputChannel* out );
/** add totality axiom */
void addTotalityAxiom( Node n, int cardinality, OutputChannel* out );
- private:
+
class NodeTrie {
- std::map< Node, NodeTrie > d_children;
public:
bool add( std::vector< Node >& n, unsigned i = 0 ){
Assert( i<n.size() );
@@ -214,10 +276,13 @@ public:
return d_children[n[i]].add( n, i+1 );
}
}
- };
+ private:
+ std::map< Node, NodeTrie > d_children;
+ }; /* class NodeTrie */
+
std::map< int, NodeTrie > d_clique_trie;
void addClique( int c, std::vector< Node >& clique );
- private:
+
/** Are we in conflict */
context::CDO<bool> d_conflict;
/** cardinality */
@@ -232,8 +297,6 @@ public:
std::map< int, Node > d_cardinality_literal;
/** cardinality lemmas */
std::map< int, Node > d_cardinality_lemma;
- /** cardinality assertions (indexed by cardinality literals ) */
- NodeBoolMap d_cardinality_assertions;
/** whether a positive cardinality constraint has been asserted */
context::CDO< bool > d_hasCard;
/** clique lemmas that have been asserted */
@@ -246,18 +309,20 @@ public:
context::CDO< bool > d_initialized;
/** cache for lemmas */
NodeBoolMap d_lemma_cache;
- private:
+
/** apply totality */
bool applyTotality( int cardinality );
/** get totality lemma terms */
Node getTotalityLemmaTerm( int cardinality, int i );
/** simple check cardinality */
void simpleCheckCardinality();
- private:
+
bool doSendLemma( Node lem );
+
public:
- SortModel( Node n, context::Context* c, context::UserContext* u, StrongSolverTheoryUF* thss );
- virtual ~SortModel(){}
+ SortModel( Node n, context::Context* c, context::UserContext* u,
+ StrongSolverTheoryUF* thss );
+ virtual ~SortModel();
/** initialize */
void initialize( OutputChannel* out );
/** new node */
@@ -420,18 +485,7 @@ public:
Statistics d_statistics;
};/* class StrongSolverTheoryUF */
-class DisequalityPropagator
-{
-private:
- /** quantifiers engine */
- QuantifiersEngine* d_qe;
- /** strong solver */
- StrongSolverTheoryUF* d_ufss;
- /** true,false */
- Node d_true;
- Node d_false;
- /** check term t against equivalence class that t is disequal from */
- void checkEquivalenceClass( Node t, Node eqc );
+class DisequalityPropagator {
public:
DisequalityPropagator(QuantifiersEngine* qe, StrongSolverTheoryUF* ufss);
/** merge */
@@ -440,7 +494,7 @@ public:
void assertDisequal( Node a, Node b, Node reason );
/** assert predicate */
void assertPredicate( Node p, bool polarity );
-public:
+
class Statistics {
public:
IntStat d_propagations;
@@ -449,9 +503,20 @@ public:
};
/** statistics class */
Statistics d_statistics;
-};
-}
+private:
+ /** quantifiers engine */
+ QuantifiersEngine* d_qe;
+ /** strong solver */
+ StrongSolverTheoryUF* d_ufss;
+ /** true,false */
+ Node d_true;
+ Node d_false;
+ /** check term t against equivalence class that t is disequal from */
+ void checkEquivalenceClass( Node t, Node eqc );
+}; /* class DisequalityPropagator */
+
+}/* CVC4::theory namespace::uf */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/uf/theory_uf_type_rules.h b/src/theory/uf/theory_uf_type_rules.h
index 05b95e9e1..ab42aaf15 100644
--- a/src/theory/uf/theory_uf_type_rules.h
+++ b/src/theory/uf/theory_uf_type_rules.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file theory_uf_type_rules.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Christopher L. Conway, Andrew Reynolds, Morgan Deters
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Andrew Reynolds, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add brief comments here ]]
**
diff --git a/src/theory/unconstrained_simplifier.cpp b/src/theory/unconstrained_simplifier.cpp
index dda73c1d9..6a33adc56 100644
--- a/src/theory/unconstrained_simplifier.cpp
+++ b/src/theory/unconstrained_simplifier.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file unconstrained_simplifier.cpp
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Morgan Deters, Tim King, Liana Hadarean, Peter Collingbourne, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Clark Barrett, Peter Collingbourne, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simplifications based on unconstrained variables
**
diff --git a/src/theory/unconstrained_simplifier.h b/src/theory/unconstrained_simplifier.h
index e23c4853d..e10be1a8f 100644
--- a/src/theory/unconstrained_simplifier.h
+++ b/src/theory/unconstrained_simplifier.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file unconstrained_simplifier.h
** \verbatim
- ** Original author: Clark Barrett
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Clark Barrett, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simplifications based on unconstrained variables
**
diff --git a/src/theory/valuation.cpp b/src/theory/valuation.cpp
index 7407086c2..165937c13 100644
--- a/src/theory/valuation.cpp
+++ b/src/theory/valuation.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file valuation.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett, Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A "valuation" proxy for TheoryEngine
**
diff --git a/src/theory/valuation.h b/src/theory/valuation.h
index c9bff14a4..4ecdecad0 100644
--- a/src/theory/valuation.h
+++ b/src/theory/valuation.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file valuation.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Dejan Jovanovic
- ** Minor contributors (to current version): Tim King, Clark Barrett, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A "valuation" proxy for TheoryEngine
**
diff --git a/src/util/abstract_value.cpp b/src/util/abstract_value.cpp
index c9dc0251d..c80569034 100644
--- a/src/util/abstract_value.cpp
+++ b/src/util/abstract_value.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file abstract_value.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of abstract values
**
diff --git a/src/util/abstract_value.h b/src/util/abstract_value.h
index f02df2e66..d85a62c72 100644
--- a/src/util/abstract_value.h
+++ b/src/util/abstract_value.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file abstract_value.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of abstract values
**
diff --git a/src/util/bin_heap.h b/src/util/bin_heap.h
index ed6192cf7..4f2b25c39 100644
--- a/src/util/bin_heap.h
+++ b/src/util/bin_heap.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bin_heap.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An implementation of a binary heap
**
diff --git a/src/util/bitvector.h b/src/util/bitvector.h
index 041cae38e..a04cbb58f 100644
--- a/src/util/bitvector.h
+++ b/src/util/bitvector.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bitvector.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters, Liana Hadarean
- ** Minor contributors (to current version): Christopher L. Conway
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Dejan Jovanovic, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/bool.h b/src/util/bool.h
index 2d5e15777..99db6a4a6 100644
--- a/src/util/bool.h
+++ b/src/util/bool.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file bool.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A hash function for Boolean
**
diff --git a/src/util/cache.h b/src/util/cache.h
index 788c89d83..8dd3cd0ae 100644
--- a/src/util/cache.h
+++ b/src/util/cache.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cache.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A generic Cache<> template class for use by functions that
** walk the Node DAG and want to cache results for sub-DAGs
diff --git a/src/util/cardinality.cpp b/src/util/cardinality.cpp
index 07e094a38..2eea4c040 100644
--- a/src/util/cardinality.cpp
+++ b/src/util/cardinality.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file cardinality.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of cardinality
**
diff --git a/src/util/cardinality.h b/src/util/cardinality.h
index 8b0d85980..93b4ca618 100644
--- a/src/util/cardinality.h
+++ b/src/util/cardinality.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file cardinality.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Andrew Reynolds
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of cardinality
**
diff --git a/src/util/debug.h b/src/util/debug.h
index 6ef196111..665fa99a2 100644
--- a/src/util/debug.h
+++ b/src/util/debug.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file debug.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Debugging things.
**
diff --git a/src/util/dense_map.h b/src/util/dense_map.h
index 86b9f2553..7fa3832ef 100644
--- a/src/util/dense_map.h
+++ b/src/util/dense_map.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file dense_map.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This is an abstraction of a Map from unsigned integers to elements of type T.
**
diff --git a/src/util/divisible.cpp b/src/util/divisible.cpp
index 85824a77f..4e0d9815d 100644
--- a/src/util/divisible.cpp
+++ b/src/util/divisible.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file divisible.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/divisible.h b/src/util/divisible.h
index 56178e604..d5651ae41 100644
--- a/src/util/divisible.h
+++ b/src/util/divisible.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file divisible.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/dynamic_array.h b/src/util/dynamic_array.h
index 6938748a8..2ec85a025 100644
--- a/src/util/dynamic_array.h
+++ b/src/util/dynamic_array.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file dynamic_array.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/floatingpoint.cpp b/src/util/floatingpoint.cpp
index d1164133a..678d3a45a 100644
--- a/src/util/floatingpoint.cpp
+++ b/src/util/floatingpoint.cpp
@@ -1,13 +1,14 @@
/********************* */
/*! \file floatingpoint.cpp
** \verbatim
- ** Original author: Martin Brain
- ** Major contributors:
- ** Minor contributors (to current version):
- ** This file is part of the CVC4 project.
+ ** Top contributors (to current version):
+ ** Tim King, Martin Brain
** Copyright (c) 2013 University of Oxford
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Implementations of the utility functions for working with floating point theories. ]]
**
diff --git a/src/util/floatingpoint.h b/src/util/floatingpoint.h
index d8a3a65d9..7b18d542a 100644
--- a/src/util/floatingpoint.h
+++ b/src/util/floatingpoint.h
@@ -1,13 +1,14 @@
/********************* */
/*! \file floatingpoint.h
** \verbatim
- ** Original author: Martin Brain
- ** Major contributors:
- ** Minor contributors (to current version):
- ** This file is part of the CVC4 project.
+ ** Top contributors (to current version):
+ ** Martin Brain, Tim King
** Copyright (c) 2013 University of Oxford
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Utility functions for working with floating point theories. ]]
**
diff --git a/src/util/gmp_util.h b/src/util/gmp_util.h
index d3f0d09d4..776d8a38a 100644
--- a/src/util/gmp_util.h
+++ b/src/util/gmp_util.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file gmp_util.h
** \verbatim
- ** Original author: Dejan Jovanovic
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Dejan Jovanovic, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/hash.h b/src/util/hash.h
index 218cf0aab..4797b5f02 100644
--- a/src/util/hash.h
+++ b/src/util/hash.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file hash.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Morgan Deters, Christopher L. Conway, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/index.h b/src/util/index.h
index ea0802b2d..6c11343b5 100644
--- a/src/util/index.h
+++ b/src/util/index.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file index.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Liana Hadarean
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/integer.h.in b/src/util/integer.h.in
index 3db9998a7..13ae1392b 100644
--- a/src/util/integer.h.in
+++ b/src/util/integer.h.in
@@ -1,13 +1,13 @@
/********************* */
/*! \file integer.h.in
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multi-precision integer constant
**
diff --git a/src/util/integer_cln_imp.cpp b/src/util/integer_cln_imp.cpp
index 27a4b7d06..0064f2904 100644
--- a/src/util/integer_cln_imp.cpp
+++ b/src/util/integer_cln_imp.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file integer_cln_imp.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h
index 9e5e6c2ae..177fc02cf 100644
--- a/src/util/integer_cln_imp.h
+++ b/src/util/integer_cln_imp.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file integer_cln_imp.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic, Liana Hadarean
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multiprecision integer constant; wraps a CLN multiprecision
** integer.
diff --git a/src/util/integer_gmp_imp.cpp b/src/util/integer_gmp_imp.cpp
index df1bd297a..d165dbec3 100644
--- a/src/util/integer_gmp_imp.cpp
+++ b/src/util/integer_gmp_imp.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file integer_gmp_imp.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multi-precision rational constant.
**
diff --git a/src/util/integer_gmp_imp.h b/src/util/integer_gmp_imp.h
index 9cae16222..0c5665e38 100644
--- a/src/util/integer_gmp_imp.h
+++ b/src/util/integer_gmp_imp.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file integer_gmp_imp.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Liana Hadarean
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Liana Hadarean
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multiprecision integer constant; wraps a GMP multiprecision
** integer.
diff --git a/src/util/maybe.h b/src/util/maybe.h
index 2fa7c2f11..7ede6f512 100644
--- a/src/util/maybe.h
+++ b/src/util/maybe.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file maybe.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief This provides a templated Maybe construct.
**
diff --git a/src/util/ntuple.h b/src/util/ntuple.h
index b9e1100f1..21af4f423 100644
--- a/src/util/ntuple.h
+++ b/src/util/ntuple.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file ntuple.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Similar to std::pair<>, for triples and quadruples
**
diff --git a/src/util/proof.h b/src/util/proof.h
index 22d9f97d5..fc5f7f901 100644
--- a/src/util/proof.h
+++ b/src/util/proof.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file proof.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/rational.h.in b/src/util/rational.h.in
index 6f9c29c19..08c4003e9 100644
--- a/src/util/rational.h.in
+++ b/src/util/rational.h.in
@@ -1,13 +1,13 @@
/********************* */
/*! \file rational.h.in
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multi-precision rational constant
**
diff --git a/src/util/rational_cln_imp.cpp b/src/util/rational_cln_imp.cpp
index 608b33f2b..bee944531 100644
--- a/src/util/rational_cln_imp.cpp
+++ b/src/util/rational_cln_imp.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file rational_cln_imp.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Christopher L. Conway
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Christopher L. Conway, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multi-precision rational constant.
**
diff --git a/src/util/rational_cln_imp.h b/src/util/rational_cln_imp.h
index df08770e8..9b4a8efa7 100644
--- a/src/util/rational_cln_imp.h
+++ b/src/util/rational_cln_imp.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rational_cln_imp.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Multiprecision rational constants; wraps a CLN multiprecision
** rational.
diff --git a/src/util/rational_gmp_imp.cpp b/src/util/rational_gmp_imp.cpp
index 63fb8e05c..17bce0201 100644
--- a/src/util/rational_gmp_imp.cpp
+++ b/src/util/rational_gmp_imp.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file rational_gmp_imp.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters, Christopher L. Conway
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Christopher L. Conway, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief A multi-precision rational constant.
**
diff --git a/src/util/rational_gmp_imp.h b/src/util/rational_gmp_imp.h
index 59145d485..6a1c8b4b8 100644
--- a/src/util/rational_gmp_imp.h
+++ b/src/util/rational_gmp_imp.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file rational_gmp_imp.h
** \verbatim
- ** Original author: Tim King
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Dejan Jovanovic
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Multiprecision rational constants; wraps a GMP multiprecision
** rational.
diff --git a/src/util/regexp.cpp b/src/util/regexp.cpp
index 25a595613..d211aaf1b 100644
--- a/src/util/regexp.cpp
+++ b/src/util/regexp.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file regexp.cpp
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tianyi Liang, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/regexp.h b/src/util/regexp.h
index 4b26b6e91..2cfcbc4e4 100644
--- a/src/util/regexp.h
+++ b/src/util/regexp.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file regexp.h
** \verbatim
- ** Original author: Tianyi Liang
- ** Major contributors: none
- ** Minor contributors (to current version): Morgan Deters, Andrew Reynolds
+ ** Top contributors (to current version):
+ ** Tianyi Liang, Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/resource_manager.cpp b/src/util/resource_manager.cpp
index 8d6e5e6d4..7a739a779 100644
--- a/src/util/resource_manager.cpp
+++ b/src/util/resource_manager.cpp
@@ -1,17 +1,18 @@
/********************* */
/*! \file resource_manager.cpp
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: none
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief Manages and updates various resource and time limits.
-**
-** Manages and updates various resource and time limits.
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
**/
#include "util/resource_manager.h"
diff --git a/src/util/resource_manager.h b/src/util/resource_manager.h
index f3bb42a08..d21122cae 100644
--- a/src/util/resource_manager.h
+++ b/src/util/resource_manager.h
@@ -1,17 +1,18 @@
/********************* */
/*! \file resource_manager.h
-** \verbatim
-** Original author: Liana Hadarean
-** Major contributors: none
-** Minor contributors (to current version): none
-** This file is part of the CVC4 project.
-** Copyright (c) 2009-2014 New York University and The University of Iowa
-** See the file COPYING in the top-level source directory for licensing
-** information.\endverbatim
-**
-** \brief Manages and updates various resource and time limits
-**
-** Manages and updates various resource and time limits.
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King, Morgan Deters
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** [[ Add lengthier description here ]]
+
+ ** \todo document this file
+
**/
#include "cvc4_public.h"
diff --git a/src/util/result.cpp b/src/util/result.cpp
index b981164a4..51b1a8de1 100644
--- a/src/util/result.cpp
+++ b/src/util/result.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file result.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Encapsulation of the result of a query.
**
diff --git a/src/util/result.h b/src/util/result.h
index 8069f7ef9..8303ad0e8 100644
--- a/src/util/result.h
+++ b/src/util/result.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file result.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Tim King
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Encapsulation of the result of a query.
**
diff --git a/src/util/sexpr.cpp b/src/util/sexpr.cpp
index 9837a7045..efb90302f 100644
--- a/src/util/sexpr.cpp
+++ b/src/util/sexpr.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file sexpr.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simple representation of S-expressions
**
diff --git a/src/util/sexpr.h b/src/util/sexpr.h
index 40fd9dd56..9c80a1b1f 100644
--- a/src/util/sexpr.h
+++ b/src/util/sexpr.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file sexpr.h
** \verbatim
- ** Original author: Christopher L. Conway
- ** Major contributors: Tim King, Morgan Deters
- ** Minor contributors (to current version): Dejan Jovanovic
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters, Christopher L. Conway
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Simple representation of S-expressions
**
diff --git a/src/util/sexpr.i b/src/util/sexpr.i
index 4c89c5019..3c865c097 100644
--- a/src/util/sexpr.i
+++ b/src/util/sexpr.i
@@ -4,6 +4,7 @@
%ignore CVC4::operator<<(std::ostream&, const SExpr&);
%ignore CVC4::operator<<(std::ostream&, SExpr::SexprTypes);
+%ignore CVC4::operator<<(std::ostream&, PrettySExprs);
// for Java and the like
%extend CVC4::SExpr {
diff --git a/src/util/smt2_quote_string.cpp b/src/util/smt2_quote_string.cpp
index 68551bc0f..578be99e5 100644
--- a/src/util/smt2_quote_string.cpp
+++ b/src/util/smt2_quote_string.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2_quote_string.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Quotes a string if necessary for smt2.
**
diff --git a/src/util/smt2_quote_string.h b/src/util/smt2_quote_string.h
index 577f216e2..2d7f0b2f0 100644
--- a/src/util/smt2_quote_string.h
+++ b/src/util/smt2_quote_string.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file smt2_quote_string.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King, Morgan Deters
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Quotes a string if necessary for smt2.
**
diff --git a/src/util/statistics.cpp b/src/util/statistics.cpp
index 371872454..8384a7bb1 100644
--- a/src/util/statistics.cpp
+++ b/src/util/statistics.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file statistics.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/statistics.h b/src/util/statistics.h
index a0b6ed083..663d2071b 100644
--- a/src/util/statistics.h
+++ b/src/util/statistics.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file statistics.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/statistics_registry.cpp b/src/util/statistics_registry.cpp
index c9051cc0e..cb8e1ce90 100644
--- a/src/util/statistics_registry.cpp
+++ b/src/util/statistics_registry.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file statistics_registry.cpp
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): Kshitij Bansal, Tim King
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief [[ Add one-line brief description here ]]
**
diff --git a/src/util/statistics_registry.h b/src/util/statistics_registry.h
index f4f00e444..4f2c356e8 100644
--- a/src/util/statistics_registry.h
+++ b/src/util/statistics_registry.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file statistics_registry.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): Kshitij Bansal
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King, Kshitij Bansal
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Statistics utility classes
**
diff --git a/src/util/subrange_bound.cpp b/src/util/subrange_bound.cpp
index 5d66b75ad..085ecb930 100644
--- a/src/util/subrange_bound.cpp
+++ b/src/util/subrange_bound.cpp
@@ -1,13 +1,13 @@
/********************* */
/*! \file subrange_bound.cpp
** \verbatim
- ** Original author: Tim King
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2015 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of subrange bounds
**
diff --git a/src/util/subrange_bound.h b/src/util/subrange_bound.h
index d5b50bf4c..86c88e187 100644
--- a/src/util/subrange_bound.h
+++ b/src/util/subrange_bound.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file subrange_bound.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: Tim King
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Representation of subrange bounds
**
diff --git a/src/util/tuple.h b/src/util/tuple.h
index fe016db2c..14763d2d5 100644
--- a/src/util/tuple.h
+++ b/src/util/tuple.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file tuple.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Tuple operators
**
diff --git a/src/util/unsafe_interrupt_exception.h b/src/util/unsafe_interrupt_exception.h
index d7c736d64..345daf674 100644
--- a/src/util/unsafe_interrupt_exception.h
+++ b/src/util/unsafe_interrupt_exception.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file unsafe_interrupt_exception.h
** \verbatim
- ** Original author: Liana Hadarean
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Liana Hadarean, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief An exception that is thrown when the solver is out of time/resources
** and is interrupted in an unsafe state
diff --git a/src/util/utility.h b/src/util/utility.h
index 59522901a..1d51d42ee 100644
--- a/src/util/utility.h
+++ b/src/util/utility.h
@@ -1,13 +1,13 @@
/********************* */
/*! \file utility.h
** \verbatim
- ** Original author: Morgan Deters
- ** Major contributors: none
- ** Minor contributors (to current version): none
+ ** Top contributors (to current version):
+ ** Morgan Deters, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014 New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
+ ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
**
** \brief Some standard STL-related utility functions for CVC4
**
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback