#ifndef _internal_hpp_INCLUDED
#define _internal_hpp_INCLUDED
#include "inttypes.hpp"
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <cstring>
extern "C" {
#include <unistd.h>
}
#include <algorithm>
#include <queue>
#include <string>
#include <unordered_set>
#include <vector>
#include "arena.hpp"
#include "averages.hpp"
#include "bins.hpp"
#include "block.hpp"
#include "cadical.hpp"
#include "checker.hpp"
#include "clause.hpp"
#include "config.hpp"
#include "contract.hpp"
#include "cover.hpp"
#include "decompose.hpp"
#include "drattracer.hpp"
#include "elim.hpp"
#include "ema.hpp"
#include "external.hpp"
#include "file.hpp"
#include "flags.hpp"
#include "format.hpp"
#include "frattracer.hpp"
#include "heap.hpp"
#include "idruptracer.hpp"
#include "instantiate.hpp"
#include "internal.hpp"
#include "level.hpp"
#include "lidruptracer.hpp"
#include "limit.hpp"
#include "logging.hpp"
#include "lratbuilder.hpp"
#include "lratchecker.hpp"
#include "lrattracer.hpp"
#include "message.hpp"
#include "occs.hpp"
#include "options.hpp"
#include "parse.hpp"
#include "phases.hpp"
#include "profile.hpp"
#include "proof.hpp"
#include "queue.hpp"
#include "radix.hpp"
#include "random.hpp"
#include "range.hpp"
#include "reap.hpp"
#include "reluctant.hpp"
#include "resources.hpp"
#include "score.hpp"
#include "stats.hpp"
#include "terminal.hpp"
#include "tracer.hpp"
#include "util.hpp"
#include "var.hpp"
#include "veripbtracer.hpp"
#include "version.hpp"
#include "vivify.hpp"
#include "watch.hpp"
namespace CaDiCaL {
using namespace std;
struct Coveror;
struct External;
struct Walker;
class Tracer;
class FileTracer;
class StatTracer;
struct CubesWithStatus {
int status = 0;
std::vector<std::vector<int>> cubes;
};
struct Internal {
enum Mode {
BLOCK = (1 << 0),
CONDITION = (1 << 1),
COVER = (1 << 2),
DECOMP = (1 << 3),
DEDUP = (1 << 4),
ELIM = (1 << 5),
LUCKY = (1 << 6),
PROBE = (1 << 7),
SEARCH = (1 << 8),
SIMPLIFY = (1 << 9),
SUBSUME = (1 << 10),
TERNARY = (1 << 11),
TRANSRED = (1 << 12),
VIVIFY = (1 << 13),
WALK = (1 << 14),
};
bool in_mode (Mode m) const { return (mode & m) != 0; }
void set_mode (Mode m) {
assert (!(mode & m));
mode |= m;
}
void reset_mode (Mode m) {
assert (mode & m);
mode &= ~m;
}
void require_mode (Mode m) const { assert (mode & m), (void) m; }
int mode; bool unsat; bool iterating; bool localsearching; bool lookingahead; bool preprocessing; bool protected_reasons; bool force_saved_phase; bool searching_lucky_phases; bool stable; bool reported; bool external_prop; bool did_external_prop; bool external_prop_is_lazy; bool forced_backt_allowed; bool private_steps; char rephased; Reluctant reluctant; size_t vsize; int max_var; uint64_t clause_id; uint64_t original_id; uint64_t reserved_ids; uint64_t conflict_id; bool concluded; vector<uint64_t> conclusion; vector<uint64_t>
unit_clauses_idx; vector<uint64_t> lrat_chain; vector<uint64_t> mini_chain; vector<uint64_t> minimize_chain; vector<uint64_t> unit_chain; vector<Clause *> inst_chain; vector<vector<vector<uint64_t>>>
probehbr_chains; bool lrat; bool frat; int level; Phases phases; signed char *vals; vector<signed char> marks; vector<unsigned> frozentab; vector<int> i2e; vector<unsigned> relevanttab; Queue queue; Links links; double score_inc; ScoreSchedule scores; vector<double> stab; vector<Var> vtab; vector<int> parents; vector<Flags> ftab; vector<int64_t> btab; vector<int64_t> gtab; vector<Occs> otab; vector<int> ptab; vector<int64_t> ntab; vector<Bins> big; vector<Watches> wtab; Clause *conflict; Clause *ignore; Clause *dummy_binary; Clause *external_reason; Clause *newest_clause; bool force_no_backtrack; bool from_propagator; bool ext_clause_forgettable; int tainted_literal; size_t notified; Clause *probe_reason; size_t propagated; size_t propagated2; size_t propergated; size_t best_assigned; size_t target_assigned; size_t no_conflict_until; vector<int> trail; vector<int> clause; vector<int> assumptions; vector<int> constraint; bool unsat_constraint; bool marked_failed; vector<int> original; vector<int> levels; vector<int> analyzed; vector<int> unit_analyzed; vector<int> decomposed; vector<int> minimized; vector<int> shrinkable; Reap reap;
size_t num_assigned;
vector<int> probes; vector<Level> control; vector<Clause *> clauses; Averages averages; Limit lim; Last last; Inc inc;
Proof *proof; LratBuilder *lratbuilder; vector<Tracer *>
tracers; vector<FileTracer *>
file_tracers; vector<StatTracer *> stat_tracers;
Options opts; Stats stats; #ifndef QUIET
Profiles profiles; bool force_phase_messages; #endif
Arena arena; Format error_message; string prefix;
Internal *internal; External *external;
volatile bool termination_forced;
const Range vars; const Sange lits;
Internal ();
~Internal ();
void init_vars (int new_max_var);
void init_enqueue (int idx);
void init_queue (int old_max_var, int new_max_var);
void init_scores (int old_max_var, int new_max_var);
void add_original_lit (int lit);
void finish_added_clause_with_id (uint64_t lit, bool restore = false);
void reserve_ids (int number);
void enlarge_vals (size_t new_vsize);
void enlarge (int new_max_var);
bool active (int lit) { return flags (lit).active (); }
int active () const {
int res = stats.active;
#ifndef NDEBUG
int tmp = max_var;
tmp -= stats.unused;
tmp -= stats.now.fixed;
tmp -= stats.now.eliminated;
tmp -= stats.now.substituted;
tmp -= stats.now.pure;
assert (tmp >= 0);
assert (tmp == res);
#endif
return res;
}
void reactivate (int lit);
int64_t redundant () const { return stats.current.redundant; }
int64_t irredundant () const { return stats.current.irredundant; }
double clause_variable_ratio () const {
return relative (irredundant (), active ());
}
double scale (double v) const;
int vidx (int lit) const {
int idx;
assert (lit);
assert (lit != INT_MIN);
idx = abs (lit);
assert (idx <= max_var);
return idx;
}
unsigned vlit (int lit) { return (lit < 0) + 2u * (unsigned) vidx (lit); }
int u2i (unsigned u) {
assert (u > 1);
int res = u / 2;
assert (res <= max_var);
if (u & 1)
res = -res;
return res;
}
inline uint64_t &unit_clauses (int lit) {
assert (lrat || frat);
return unit_clauses_idx[lit];
}
Var &var (int lit) { return vtab[vidx (lit)]; }
Link &link (int lit) { return links[vidx (lit)]; }
Flags &flags (int lit) { return ftab[vidx (lit)]; }
int64_t &bumped (int lit) { return btab[vidx (lit)]; }
int &propfixed (int lit) { return ptab[vlit (lit)]; }
double &score (int lit) { return stab[vidx (lit)]; }
const Flags &flags (int lit) const { return ftab[vidx (lit)]; }
bool occurring () const { return !otab.empty (); }
bool watching () const { return !wtab.empty (); }
Bins &bins (int lit) { return big[vlit (lit)]; }
Occs &occs (int lit) { return otab[vlit (lit)]; }
int64_t &noccs (int lit) { return ntab[vlit (lit)]; }
Watches &watches (int lit) { return wtab[vlit (lit)]; }
bool use_scores () const { return opts.score && stable; }
void bump_variable_score (int lit);
void bump_variable_score_inc ();
void rescale_variable_scores ();
signed char marked (int lit) const {
signed char res = marks[vidx (lit)];
if (lit < 0)
res = -res;
return res;
}
void mark (int lit) {
assert (!marked (lit));
marks[vidx (lit)] = sign (lit);
assert (marked (lit) > 0);
assert (marked (-lit) < 0);
}
void unmark (int lit) {
marks[vidx (lit)] = 0;
assert (!marked (lit));
}
signed char marked67 (int lit) const {
signed char res = marks[vidx (lit)] >> 6;
if (lit < 0)
res = -res;
return res;
}
void mark67 (int lit) {
signed char &m = marks[vidx (lit)];
const signed char mask = 0x3f;
#ifndef NDEBUG
const signed char bits = m & mask;
#endif
m = (m & mask) | (sign (lit) << 6);
assert (marked (lit) > 0);
assert (marked (-lit) < 0);
assert ((m & mask) == bits);
assert (marked67 (lit) > 0);
assert (marked67 (-lit) < 0);
}
void unmark67 (int lit) {
signed char &m = marks[vidx (lit)];
const signed char mask = 0x3f;
#ifndef NDEBUG
const signed bits = m & mask;
#endif
m &= mask;
assert ((m & mask) == bits);
}
void unmark (vector<int> &lits) {
for (const auto &lit : lits)
unmark (lit);
}
bool getbit (int lit, int bit) const {
assert (0 <= bit), assert (bit < 6);
return marks[vidx (lit)] & (1 << bit);
}
void setbit (int lit, int bit) {
assert (0 <= bit), assert (bit < 6);
assert (!getbit (lit, bit));
marks[vidx (lit)] |= (1 << bit);
assert (getbit (lit, bit));
}
void unsetbit (int lit, int bit) {
assert (0 <= bit), assert (bit < 6);
assert (getbit (lit, bit));
marks[vidx (lit)] &= ~(1 << bit);
assert (!getbit (lit, bit));
}
bool marked2 (int lit) const {
unsigned res = marks[vidx (lit)];
assert (res <= 3);
unsigned bit = bign (lit);
return (res & bit) != 0;
}
void mark2 (int lit) {
marks[vidx (lit)] |= bign (lit);
assert (marked2 (lit));
}
void mark_clause (); void mark (Clause *);
void mark2 (Clause *);
void unmark_clause (); void unmark (Clause *);
inline void watch_literal (int lit, int blit, Clause *c) {
assert (lit != blit);
Watches &ws = watches (lit);
ws.push_back (Watch (blit, c));
LOG (c, "watch %d blit %d in", lit, blit);
}
inline void watch_clause (Clause *c) {
const int l0 = c->literals[0];
const int l1 = c->literals[1];
watch_literal (l0, l1, c);
watch_literal (l1, l0, c);
}
inline void unwatch_clause (Clause *c) {
const int l0 = c->literals[0];
const int l1 = c->literals[1];
remove_watch (watches (l0), c);
remove_watch (watches (l1), c);
}
inline void update_queue_unassigned (int idx) {
assert (0 < idx);
assert (idx <= max_var);
queue.unassigned = idx;
queue.bumped = btab[idx];
LOG ("queue unassigned now %d bumped %" PRId64 "", idx, btab[idx]);
}
void bump_queue (int idx);
void mark_eliminated (int);
void mark_substituted (int);
void mark_active (int);
void mark_fixed (int);
void mark_pure (int);
Clause *new_clause (bool red, int glue = 0);
void promote_clause (Clause *, int new_glue);
size_t shrink_clause (Clause *, int new_size);
void minimize_sort_clause ();
void shrink_and_minimize_clause ();
void reset_shrinkable ();
void mark_shrinkable_as_removable (int, std::vector<int>::size_type);
int shrink_literal (int, int, unsigned);
unsigned shrunken_block_uip (int, int,
std::vector<int>::reverse_iterator &,
std::vector<int>::reverse_iterator &,
std::vector<int>::size_type, const int);
void shrunken_block_no_uip (const std::vector<int>::reverse_iterator &,
const std::vector<int>::reverse_iterator &,
unsigned &, const int);
void push_literals_of_block (const std::vector<int>::reverse_iterator &,
const std::vector<int>::reverse_iterator &,
int, unsigned);
unsigned shrink_next (int, unsigned &, unsigned &);
std::vector<int>::reverse_iterator
minimize_and_shrink_block (std::vector<int>::reverse_iterator &,
unsigned int &, unsigned int &, const int);
unsigned shrink_block (std::vector<int>::reverse_iterator &,
std::vector<int>::reverse_iterator &, int,
unsigned &, unsigned &, const int, unsigned);
unsigned shrink_along_reason (int, int, bool, bool &, unsigned);
void deallocate_clause (Clause *);
void delete_clause (Clause *);
void mark_garbage (Clause *);
void assign_original_unit (uint64_t, int);
void add_new_original_clause (uint64_t);
Clause *new_learned_redundant_clause (int glue);
Clause *new_hyper_binary_resolved_clause (bool red, int glue);
Clause *new_clause_as (const Clause *orig);
Clause *new_resolved_irredundant_clause ();
int assignment_level (int lit, Clause *);
void build_chain_for_units (int lit, Clause *reason, bool forced);
void build_chain_for_empty ();
void search_assign (int lit, Clause *);
void search_assign_driving (int lit, Clause *reason);
void search_assign_external (int lit);
void search_assume_decision (int decision);
void assign_unit (int lit);
bool propagate ();
void propergate ();
void unassign (int lit);
void update_target_and_best ();
void backtrack (int target_level = 0);
bool minimize_literal (int lit, int depth = 0);
void minimize_clause ();
void calculate_minimize_chain (int lit, std::vector<int> &stack);
void learn_empty_clause ();
void learn_unit_clause (int lit);
void bump_variable (int lit);
void bump_variables ();
int recompute_glue (Clause *);
void bump_clause (Clause *);
void clear_unit_analyzed_literals ();
void clear_analyzed_literals ();
void clear_analyzed_levels ();
void clear_minimized_literals ();
bool bump_also_reason_literal (int lit);
void bump_also_reason_literals (int lit, int limit);
void bump_also_all_reason_literals ();
void analyze_literal (int lit, int &open, int &resolvent_size,
int &antecedent_size);
void analyze_reason (int lit, Clause *, int &open, int &resolvent_size,
int &antecedent_size);
Clause *new_driving_clause (const int glue, int &jump);
int find_conflict_level (int &forced);
int determine_actual_backtrack_level (int jump);
void otfs_strengthen_clause (Clause *, int, int,
const std::vector<int> &);
void otfs_subsume_clause (Clause *subsuming, Clause *subsumed);
int otfs_find_backtrack_level (int &forced);
Clause *on_the_fly_strengthen (Clause *conflict, int lit);
void analyze ();
void iterate ();
bool external_propagate ();
bool external_check_solution ();
void add_external_clause (int propagated_lit = 0,
bool no_backtrack = false);
Clause *learn_external_reason_clause (int lit, int falsified_elit = 0,
bool no_backtrack = false);
Clause *wrapped_learn_external_reason_clause (int lit);
void explain_external_propagations ();
void explain_reason (int lit, Clause *, int &open);
void move_literals_to_watch ();
void handle_external_clause (Clause *);
void notify_assignments ();
void notify_decision ();
void notify_backtrack (size_t new_level);
void force_backtrack (size_t new_level);
int ask_decision ();
bool ask_external_clause ();
void add_observed_var (int ilit);
void remove_observed_var (int ilit);
bool observed (int ilit) const;
bool is_decision (int ilit);
void check_watched_literal_invariants ();
void set_tainted_literal ();
void renotify_trail_after_ilb ();
void renotify_trail_after_local_search ();
void renotify_full_trail ();
void connect_propagator ();
void mark_garbage_external_forgettable (int64_t id);
bool is_external_forgettable (int64_t id);
#ifndef NDEBUG
bool get_merged_literals (std::vector<int> &);
void get_all_fixed_literals (std::vector<int> &);
#endif
void eagerly_subsume_recently_learned_clauses (Clause *);
bool stabilizing ();
bool restarting ();
int reuse_trail ();
void restart ();
void clear_phases (vector<signed char> &); void copy_phases (vector<signed char> &);
bool rephasing ();
char rephase_best ();
char rephase_flipping ();
char rephase_inverted ();
char rephase_original ();
char rephase_random ();
char rephase_walk ();
void shuffle_scores ();
void shuffle_queue ();
void rephase ();
int unlucky (int res);
int trivially_false_satisfiable ();
int trivially_true_satisfiable ();
int forward_false_satisfiable ();
int forward_true_satisfiable ();
int backward_false_satisfiable ();
int backward_true_satisfiable ();
int positive_horn_satisfiable ();
int negative_horn_satisfiable ();
bool terminated_asynchronously (int factor = 1);
bool search_limits_hit ();
void terminate () {
LOG ("forcing asynchronous termination");
termination_forced = true;
}
bool flushing ();
bool reducing ();
void protect_reasons ();
void mark_clauses_to_be_flushed ();
void mark_useless_redundant_clauses_as_garbage ();
bool propagate_out_of_order_units ();
void unprotect_reasons ();
void reduce ();
int clause_contains_fixed_literal (Clause *);
void remove_falsified_literals (Clause *);
void mark_satisfied_clauses_as_garbage ();
void copy_clause (Clause *);
void flush_watches (int lit, Watches &);
size_t flush_occs (int lit);
void flush_all_occs_and_watches ();
void update_reason_references ();
void copy_non_garbage_clauses ();
void delete_garbage_clauses ();
void check_clause_stats ();
void check_var_stats ();
bool arenaing ();
void garbage_collection ();
void remove_garbage_binaries ();
void init_occs ();
void init_bins ();
void init_noccs ();
void reset_occs ();
void reset_bins ();
void reset_noccs ();
void init_watches ();
void connect_watches (bool irredundant_only = false);
void sort_watches ();
void clear_watches ();
void reset_watches ();
bool subsuming ();
void strengthen_clause (Clause *, int);
void subsume_clause (Clause *subsuming, Clause *subsumed);
int subsume_check (Clause *subsuming, Clause *subsumed);
int try_to_subsume_clause (Clause *, vector<Clause *> &shrunken);
void reset_subsume_bits ();
bool subsume_round ();
void subsume (bool update_limits = true);
void covered_literal_addition (int lit, Coveror &);
void asymmetric_literal_addition (int lit, Coveror &);
void cover_push_extension (int lit, Coveror &);
bool cover_propagate_asymmetric (int lit, Clause *ignore, Coveror &);
bool cover_propagate_covered (int lit, Coveror &);
bool cover_clause (Clause *c, Coveror &);
int64_t cover_round ();
bool cover ();
void flush_vivification_schedule (Vivifier &);
bool consider_to_vivify_clause (Clause *candidate, bool redundant_mode);
void vivify_analyze_redundant (Vivifier &, Clause *start, bool &);
void vivify_build_lrat (int, Clause *,
std::vector<std::tuple<int, Clause *, bool>> &);
void vivify_chain_for_units (int lit, Clause *reason);
bool vivify_all_decisions (Clause *candidate, int subsume);
void vivify_post_process_analysis (Clause *candidate, int subsume);
void vivify_strengthen (Clause *candidate);
void vivify_assign (int lit, Clause *);
void vivify_assume (int lit);
bool vivify_propagate ();
void vivify_clause (Vivifier &, Clause *candidate);
void vivify_round (bool redundant_mode, int64_t delta);
void vivify ();
bool compacting ();
void compact ();
void transred ();
bool likely_to_be_kept_clause (Clause *c) {
if (!c->redundant)
return true;
if (c->keep)
return true;
if (c->glue > lim.keptglue)
return false;
if (c->size > lim.keptsize)
return false;
return true;
}
void mark_subsume (int lit) {
Flags &f = flags (lit);
if (f.subsume)
return;
LOG ("marking %d as subsuming literal candidate", abs (lit));
stats.mark.subsume++;
f.subsume = true;
}
void mark_ternary (int lit) {
Flags &f = flags (lit);
if (f.ternary)
return;
LOG ("marking %d as ternary resolution literal candidate", abs (lit));
stats.mark.ternary++;
f.ternary = true;
}
void mark_added (int lit, int size, bool redundant);
void mark_added (Clause *);
bool marked_subsume (int lit) const { return flags (lit).subsume; }
void mark_elim (int lit) {
Flags &f = flags (lit);
if (f.elim)
return;
LOG ("marking %d as elimination literal candidate", lit);
stats.mark.elim++;
f.elim = true;
}
void mark_block (int lit) {
Flags &f = flags (lit);
const unsigned bit = bign (lit);
if (f.block & bit)
return;
LOG ("marking %d as blocking literal candidate", lit);
stats.mark.block++;
f.block |= bit;
}
void mark_removed (int lit) {
mark_elim (lit);
mark_block (-lit);
}
void mark_removed (Clause *, int except = 0);
bool marked_block (int lit) const {
const Flags &f = flags (lit);
const unsigned bit = bign (lit);
return (f.block & bit) != 0;
}
void unmark_block (int lit) {
Flags &f = flags (lit);
const unsigned bit = bign (lit);
f.block &= ~bit;
}
void mark_skip (int lit) {
Flags &f = flags (lit);
const unsigned bit = bign (lit);
if (f.skip & bit)
return;
LOG ("marking %d to be skipped as blocking literal", lit);
f.skip |= bit;
}
bool marked_skip (int lit) {
const Flags &f = flags (lit);
const unsigned bit = bign (lit);
return (f.skip & bit) != 0;
}
void mark_decomposed (int lit) {
Flags &f = flags (lit);
const unsigned bit = bign (lit);
assert ((f.decompose & bit) == 0);
LOG ("marking LRAT chain of %d to be skipped", lit);
decomposed.push_back (lit);
f.decompose |= bit;
}
void unmark_decompose (int lit) {
Flags &f = flags (lit);
const unsigned bit = bign (lit);
f.decompose &= ~bit;
}
bool marked_decompose (int lit) {
const Flags &f = flags (lit);
const unsigned bit = bign (lit);
return (f.decompose & bit) != 0;
}
void clear_decomposed_literals ();
bool is_blocked_clause (Clause *c, int pivot);
void block_schedule (Blocker &);
size_t block_candidates (Blocker &, int lit);
Clause *block_impossible (Blocker &, int lit);
void block_literal_with_at_least_two_negative_occs (Blocker &, int lit);
void block_literal_with_one_negative_occ (Blocker &, int lit);
void block_pure_literal (Blocker &, int lit);
void block_reschedule_clause (Blocker &, int lit, Clause *);
void block_reschedule (Blocker &, int lit);
void block_literal (Blocker &, int lit);
bool block ();
int second_literal_in_binary_clause_lrat (Clause *, int first);
int second_literal_in_binary_clause (Eliminator &, Clause *, int first);
void mark_binary_literals (Eliminator &, int pivot);
void find_and_gate (Eliminator &, int pivot);
void find_equivalence (Eliminator &, int pivot);
bool get_ternary_clause (Clause *, int &, int &, int &);
bool match_ternary_clause (Clause *, int, int, int);
Clause *find_ternary_clause (int, int, int);
bool get_clause (Clause *, vector<int> &);
bool is_clause (Clause *, const vector<int> &);
Clause *find_clause (const vector<int> &);
void find_xor_gate (Eliminator &, int pivot);
void find_if_then_else (Eliminator &, int pivot);
Clause *find_binary_clause (int, int);
void find_gate_clauses (Eliminator &, int pivot);
void unmark_gate_clauses (Eliminator &);
bool eliminating ();
double compute_elim_score (unsigned lit);
void mark_redundant_clauses_with_eliminated_variables_as_garbage ();
void unmark_binary_literals (Eliminator &);
bool resolve_clauses (Eliminator &, Clause *, int pivot, Clause *, bool);
void mark_eliminated_clauses_as_garbage (Eliminator &, int pivot, bool &);
bool elim_resolvents_are_bounded (Eliminator &, int pivot);
void elim_update_removed_lit (Eliminator &, int lit);
void elim_update_removed_clause (Eliminator &, Clause *, int except = 0);
void elim_update_added_clause (Eliminator &, Clause *);
void elim_add_resolvents (Eliminator &, int pivot);
void elim_backward_clause (Eliminator &, Clause *);
void elim_backward_clauses (Eliminator &);
void elim_propagate (Eliminator &, int unit);
void elim_on_the_fly_self_subsumption (Eliminator &, Clause *, int);
void try_to_eliminate_variable (Eliminator &, int pivot, bool &);
void increase_elimination_bound ();
int elim_round (bool &completed, bool &);
void elim (bool update_limits = true);
void inst_assign (int lit);
bool inst_propagate ();
void collect_instantiation_candidates (Instantiator &);
bool instantiate_candidate (int lit, Clause *);
void instantiate (Instantiator &);
void new_trail_level (int lit);
bool ternary_find_binary_clause (int, int);
bool ternary_find_ternary_clause (int, int, int);
Clause *new_hyper_ternary_resolved_clause (bool red);
bool hyper_ternary_resolve (Clause *, int, Clause *);
void ternary_lit (int pivot, int64_t &steps, int64_t &htrs);
void ternary_idx (int idx, int64_t &steps, int64_t &htrs);
bool ternary_round (int64_t &steps, int64_t &htrs);
bool ternary ();
bool probing ();
void failed_literal (int lit);
void probe_lrat_for_units (int lit);
void probe_assign_unit (int lit);
void probe_assign_decision (int lit);
void probe_assign (int lit, int parent);
void mark_duplicated_binary_clauses_as_garbage ();
int get_parent_reason_literal (int lit);
void set_parent_reason_literal (int lit, int reason);
void clean_probehbr_lrat ();
void init_probehbr_lrat ();
void get_probehbr_lrat (int lit, int uip);
void set_probehbr_lrat (int lit, int uip);
void probe_post_dominator_lrat (vector<Clause *> &, int, int);
void probe_dominator_lrat (int dom, Clause *reason);
int probe_dominator (int a, int b);
int hyper_binary_resolve (Clause *);
void probe_propagate2 ();
bool probe_propagate ();
bool is_binary_clause (Clause *c, int &, int &);
void generate_probes ();
void flush_probes ();
int next_probe ();
bool probe_round ();
void probe (bool update_limits = true);
void walk_save_minimum (Walker &);
Clause *walk_pick_clause (Walker &);
unsigned walk_break_value (int lit);
int walk_pick_lit (Walker &, Clause *);
void walk_flip_lit (Walker &, int lit);
int walk_round (int64_t limit, bool prev);
void walk ();
void decompose_conflicting_scc_lrat (DFS *dfs, vector<int> &);
void build_lrat_for_clause (const vector<vector<Clause *>> &dfs_chains,
bool invert = false);
vector<Clause *> decompose_analyze_binary_clauses (DFS *dfs, int from);
void decompose_analyze_binary_chain (DFS *dfs, int);
bool decompose_round ();
void decompose ();
void reset_limits ();
bool flip (int lit);
bool flippable (int lit);
void assume_analyze_literal (int lit);
void assume_analyze_reason (int lit, Clause *reason);
void assume (int); bool failed (int lit); void reset_assumptions (); void sort_and_reuse_assumptions (); void failing ();
bool assumed (int lit) { Flags &f = flags (lit);
const unsigned bit = bign (lit);
return (f.assumed & bit) != 0;
}
void constrain (int); bool
failed_constraint (); void reset_constraint ();
int propagate_assumptions ();
void get_entrailed_literals (std::vector<int> &entrailed);
void phase (int lit);
void unphase (int lit);
bool is_autarky_literal (int lit) const;
bool is_conditional_literal (int lit) const;
void mark_as_conditional_literal (int lit);
void unmark_as_conditional_literal (int lit);
bool is_in_candidate_clause (int lit) const;
void mark_in_candidate_clause (int lit);
void unmark_in_candidate_clause (int lit);
void condition_assign (int lit);
void condition_unassign (int lit);
bool conditioning ();
long condition_round (long unassigned_literal_propagation_limit);
void condition (bool update_limits = true);
bool satisfied ();
int next_decision_variable_on_queue ();
int next_decision_variable_with_best_score ();
int next_decision_variable ();
int decide_phase (int idx, bool target);
int likely_phase (int idx);
bool better_decision (int lit, int other);
int decide ();
void limit_terminate (int);
void limit_decisions (int); void limit_conflicts (int); void limit_preprocessing (int); void limit_local_search (int);
static bool is_valid_limit (const char *name);
bool limit (const char *name, int);
void init_report_limits ();
void init_preprocessing_limits ();
void init_search_limits ();
void init_averages ();
void swap_averages ();
int try_to_satisfy_formula_by_saved_phases ();
void produce_failed_assumptions ();
int already_solved ();
int restore_clauses ();
bool preprocess_round (int round);
int preprocess ();
int local_search_round (int round);
int local_search ();
int lucky_phases ();
int cdcl_loop_with_inprocessing ();
void reset_solving ();
int solve (bool preprocess_only = false);
void finalize (int);
int lookahead ();
CubesWithStatus generate_cubes (int, int);
int most_occurring_literal ();
int lookahead_probing ();
int lookahead_next_probe ();
void lookahead_flush_probes ();
void lookahead_generate_probes ();
std::vector<int> lookahead_populate_locc ();
int lookahead_locc (const std::vector<int> &);
bool terminating_asked ();
#ifndef QUIET
void start_profiling (Profile &p, double);
void stop_profiling (Profile &p, double);
double update_profiles (); void print_profile ();
#endif
signed char val (int lit) const {
assert (-max_var <= lit);
assert (lit);
assert (lit <= max_var);
return vals[lit];
}
void set_val (int lit, signed char val) {
assert (-1 <= val);
assert (val <= 1);
assert (-max_var <= lit);
assert (lit);
assert (lit <= max_var);
vals[lit] = val;
vals[-lit] = -val;
}
int fixed (int lit) {
assert (-max_var <= lit);
assert (lit);
assert (lit <= max_var);
const int idx = vidx (lit);
int res = vals[idx];
if (res && vtab[idx].level)
res = 0;
if (lit < 0)
res = -res;
return res;
}
int externalize (int lit) {
assert (lit != INT_MIN);
const int idx = abs (lit);
assert (idx);
assert (idx <= max_var);
int res = i2e[idx];
if (lit < 0)
res = -res;
return res;
}
void freeze (int lit) {
int idx = vidx (lit);
if ((size_t) idx >= frozentab.size ()) {
size_t new_vsize = vsize ? 2 * vsize : 1 + (size_t) max_var;
while (new_vsize <= (size_t) max_var)
new_vsize *= 2;
frozentab.resize (new_vsize);
}
unsigned &ref = frozentab[idx];
if (ref < UINT_MAX) {
ref++;
LOG ("variable %d frozen %u times", idx, ref);
} else
LOG ("variable %d remains frozen forever", idx);
}
void melt (int lit) {
int idx = vidx (lit);
unsigned &ref = frozentab[idx];
if (ref < UINT_MAX) {
if (!--ref) {
if (relevanttab[idx]) {
LOG ("variable %d is observed, can not be completely molten",
idx);
ref++;
} else
LOG ("variable %d completely molten", idx);
} else
LOG ("variable %d melted once but remains frozen %u times", lit,
ref);
} else
LOG ("variable %d remains frozen forever", idx);
}
bool frozen (int lit) {
return (size_t) vidx (lit) < frozentab.size () &&
frozentab[vidx (lit)] > 0;
}
const char *parse_dimacs (FILE *);
const char *parse_dimacs (const char *);
const char *parse_solution (const char *);
void new_proof_on_demand ();
void setup_lrat_builder (); void force_lrat (); void resize_unit_clauses_idx (); void close_trace (bool stats = false); void flush_trace (bool stats = false); void trace (File *); void check ();
void connect_proof_tracer (Tracer *tracer, bool antecedents,
bool finalize_clauses = false);
void connect_proof_tracer (InternalTracer *tracer, bool antecedents,
bool finalize_clauses = false);
void connect_proof_tracer (StatTracer *tracer, bool antecedents,
bool finalize_clauses = false);
void connect_proof_tracer (FileTracer *tracer, bool antecedents,
bool finalize_clauses = false);
bool disconnect_proof_tracer (Tracer *tracer);
bool disconnect_proof_tracer (StatTracer *tracer);
bool disconnect_proof_tracer (FileTracer *tracer);
void conclude_unsat ();
void reset_concluded ();
void dump (Clause *);
void dump ();
bool traverse_clauses (ClauseIterator &);
bool traverse_constraint (ClauseIterator &);
double solve_time ();
double process_time () const; double real_time () const;
double time () { return opts.realtime ? real_time () : process_time (); }
void report (char type, int verbose_level = 0);
void report_solving (int);
void print_statistics ();
void print_resource_usage ();
#ifndef QUIET
void print_prefix ();
void vmessage (const char *, va_list &);
void message (const char *, ...) CADICAL_ATTRIBUTE_FORMAT (2, 3);
void message ();
void vverbose (int level, const char *fmt, va_list &);
void verbose (int level, const char *fmt, ...)
CADICAL_ATTRIBUTE_FORMAT (3, 4);
void verbose (int level);
void section (const char *title);
void phase (const char *phase, const char *, ...)
CADICAL_ATTRIBUTE_FORMAT (3, 4);
void phase (const char *phase, int64_t count, const char *, ...)
CADICAL_ATTRIBUTE_FORMAT (4, 5);
#endif
void error_message_end ();
void verror (const char *, va_list &);
void error (const char *, ...) CADICAL_ATTRIBUTE_FORMAT (2, 3);
void error_message_start ();
void warning (const char *, ...) CADICAL_ATTRIBUTE_FORMAT (2, 3);
};
void fatal_message_start ();
void fatal_message_end ();
void fatal (const char *, ...) CADICAL_ATTRIBUTE_FORMAT (1, 2);
inline bool score_smaller::operator() (unsigned a, unsigned b) {
assert (1 <= a);
assert (a <= (unsigned) internal->max_var);
assert (1 <= b);
assert (b <= (unsigned) internal->max_var);
double s = internal->stab[a];
double t = internal->stab[b];
if (s < t)
return true;
if (s > t)
return false;
return a > b;
}
inline int External::fixed (int elit) const {
assert (elit);
assert (elit != INT_MIN);
int eidx = abs (elit);
if (eidx > max_var)
return 0;
int ilit = e2i[eidx];
if (!ilit)
return 0;
if (elit < 0)
ilit = -ilit;
return internal->fixed (ilit);
}
inline bool Internal::terminated_asynchronously (int factor) {
if (termination_forced) {
LOG ("termination asynchronously forced");
return true;
}
if (lim.terminate.forced) {
assert (lim.terminate.forced > 0);
if (lim.terminate.forced-- == 1) {
LOG ("internally forcing termination");
termination_forced = true;
return true;
}
LOG ("decremented internal forced termination limit to %d",
lim.terminate.forced);
}
if (external->terminator && !lim.terminate.check--) {
assert (factor > 0);
assert (INT_MAX / factor > opts.terminateint);
lim.terminate.check = factor * opts.terminateint;
if (external->terminator->terminate ()) {
termination_forced = true; LOG ("connected terminator forces termination");
return true;
}
}
return false;
}
inline bool Internal::search_limits_hit () {
assert (!preprocessing);
assert (!localsearching);
if (lim.conflicts >= 0 && stats.conflicts >= lim.conflicts) {
LOG ("conflict limit %" PRId64 " reached", lim.conflicts);
return true;
}
if (lim.decisions >= 0 && stats.decisions >= lim.decisions) {
LOG ("decision limit %" PRId64 " reached", lim.decisions);
return true;
}
return false;
}
}
#endif