Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * This file is part of the cvc5 project. 3 : : * 4 : : * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS 5 : : * in the top-level source directory and their institutional affiliations. 6 : : * All rights reserved. See the file COPYING in the top-level source 7 : : * directory for licensing information. 8 : : * **************************************************************************** 9 : : * 10 : : * A field-specific theory. 11 : : * That is, the sub-theory for GF(p) for some fixed p. 12 : : * Implements Figure 2, "DecisionProcedure" from [OKTB23]. 13 : : * 14 : : * [OKTB23]: https://doi.org/10.1007/978-3-031-37703-7_8 15 : : */ 16 : : 17 : : #ifdef CVC5_USE_COCOA 18 : : 19 : : #include "theory/ff/sub_theory.h" 20 : : 21 : : #include <numeric> 22 : : 23 : : #include "expr/node_traversal.h" 24 : : #include "options/ff_options.h" 25 : : #include "smt/env_obj.h" 26 : : #include "theory/ff/cocoa_encoder.h" 27 : : #include "theory/ff/core.h" 28 : : #include "theory/ff/gb.h" 29 : : #include "theory/ff/multi_roots.h" 30 : : #include "theory/ff/split_gb.h" 31 : : #include "theory/ff/util.h" 32 : : #include "util/cocoa_globals.h" 33 : : #include "util/finite_field_value.h" 34 : : #include "util/resource_manager.h" 35 : : 36 : : namespace cvc5::internal { 37 : : namespace theory { 38 : : namespace ff { 39 : : 40 : 245 : SubTheory::SubTheory(Env& env, FfStatistics* stats, const Integer& modulus) 41 : : : EnvObj(env), 42 : : FieldObj(nodeManager(), modulus), 43 : 245 : d_facts(context()), 44 : 490 : d_stats(stats) 45 : : { 46 [ - + ][ - + ]: 245 : AlwaysAssert(modulus.isProbablePrime()) << "non-prime fields are unsupported"; [ - - ] 47 : : // must be initialized before using CoCoA. 48 : 245 : initCocoaGlobalManager(); 49 : 245 : } 50 : : 51 : 23849 : void SubTheory::notifyFact(TNode fact) { d_facts.emplace_back(fact); } 52 : : 53 : 12856 : Result SubTheory::postCheck(Theory::Effort e) 54 : : { 55 : 12856 : d_conflict.clear(); 56 : 12856 : d_model.clear(); 57 [ + + ]: 12856 : if (d_facts.empty()) return Result::SAT; 58 [ + + ]: 12840 : if (e != Theory::EFFORT_FULL) 59 : : { 60 : 10227 : return {Result::UNKNOWN, UnknownExplanation::REQUIRES_FULL_CHECK, ""}; 61 : : } 62 : : try 63 : : { 64 : 2613 : std::vector<Node> facts{}; 65 : 2613 : std::copy(d_facts.begin(), d_facts.end(), std::back_inserter(facts)); 66 : 2613 : FfResult result; 67 [ + + ]: 2613 : if (options().ff.ffSolver == options::FfSolver::SPLIT_GB) 68 : : { 69 : 840 : result = split(facts, size(), d_env, d_stats); 70 : : } 71 [ + - ]: 1773 : else if (options().ff.ffSolver == options::FfSolver::GB) 72 : : { 73 : 1773 : result = gb(facts, size(), d_env, d_stats); 74 : : } 75 : : else 76 : : { 77 : 0 : Unreachable() << options().ff.ffSolver << std::endl; 78 : : } 79 : : 80 [ + + ]: 2613 : if (std::holds_alternative<FfModel>(result)) 81 : : { 82 : 116 : const auto nm = nodeManager(); 83 : 116 : auto& model = std::get<FfModel>(result); 84 [ + - ]: 116 : Trace("ff::model") << "Model GF(" << size() << "):" << std::endl; 85 [ + + ]: 494 : for (const auto& [var, val] : model) 86 : : { 87 : 378 : auto value = nm->mkConst<FiniteFieldValue>(val); 88 [ + - ]: 378 : Trace("ff::model") << " " << var << " = " << value << std::endl; 89 : 378 : d_model.insert({var, value}); 90 : 378 : } 91 : 116 : return Result::SAT; 92 : : } 93 [ + - ]: 2497 : else if (std::holds_alternative<FfCore>(result)) 94 : : { 95 : 2497 : d_conflict = std::get<FfCore>(result); 96 : 2497 : return Result::UNSAT; 97 : : } 98 : : else 99 : : { 100 : 0 : return {Result::UNKNOWN, UnknownExplanation::INCOMPLETE, ""}; 101 : : } 102 : 2613 : } 103 [ - - ]: 0 : catch (FfTimeoutException& exc) 104 : : { 105 : 0 : return {Result::UNKNOWN, UnknownExplanation::TIMEOUT, exc.getMessage()}; 106 : 0 : } 107 : : } 108 : : 109 : 2497 : bool SubTheory::inConflict() const { return !d_conflict.empty(); } 110 : : 111 : 2497 : const std::vector<Node>& SubTheory::conflict() const { return d_conflict; } 112 : : 113 : 34 : const std::unordered_map<Node, Node>& SubTheory::model() const 114 : : { 115 : 34 : return d_model; 116 : : } 117 : : 118 : : } // namespace ff 119 : : } // namespace theory 120 : : } // namespace cvc5::internal 121 : : 122 : : #endif /* CVC5_USE_COCOA */