#ifndef PROOFLOGGER_H
#define PROOFLOGGER_H
#include <iostream>
#include <ostream>
#include <unordered_map>
#include <map>
#include <vector>
#include "global.hpp"
namespace maxPreprocessor {
class ProofLogger {
private:
std::ostream& out;
std::string s;
int add_comments;
int nb_original_vars;
int nb_ver_clauses;
std::vector<int> lit_to_zlit; std::vector<int> lit_to_blit;
int nb_zvars;
std::string subst_separ;
bool isxlit(int l); public:
std::string gl(int l); std::string get_substitution(int l); std::string get_substitution(int l1, int l2); private:
void out_l(int l); inline void out_raw_l(int l, char c) {if (!litValue(l)) s+='~'; s+=c; s+=std::to_string(litVariable(l)+1);}
void out_nl(int l) {out_l(litNegation(l)); }
void out_substitution(int l); void out_substitution(int l1, int l2);
void out_raw_substitution(int l, char c);
void out_bvar_substitution(int cid);
void out_nbvar_substitution(int cid);
void out_bvar_substitution(int cid, int lit);
void out_nbvar_substitution(int cid, int lit);
void out_zsubstitution1(int z){s+=" z"; s+=std::to_string(z); s+=subst_separ; s+='1';}
void out_zsubstitution0(int z){s+=" z"; s+=std::to_string(z); s+=subst_separ; s+='0';}
inline void out_w(int64_t w) {s+=' ';if (w>0)s+="+";s+=std::to_string(w);s+=' ';}
inline void out_ge(int rhs) {s+=" >= ";s+=std::to_string(rhs);}
inline void out_term(int l) {s+=" +1 "; out_l(l);}
inline void out_nterm(int l) {s+=" +1 "; out_l(litNegation(l));}
inline void out_term(int64_t w, int l) { out_w(w); out_l(l);}
inline void out_term(int64_t w, std::string l) { out_w(w); s+=' '; s+=l; }
inline void out_nterm(int64_t w, int l) { out_w(w); out_l(litNegation(l));}
inline void out_raw_term(int l, char c) { s+=" +1 "; out_raw_l(l, c);}
inline void out_raw_term(int64_t w, int l, char c) { out_w(w); out_raw_l(l, c);}
inline void out_zterm(int z) {s+=" +1 z";s+=std::to_string(z);}
inline void out_zterm(int64_t w, int z) {out_w(w); s+="z"; s+=std::to_string(z);}
inline void out_nzterm(int z) {s+=" +1 ~z"; s+=std::to_string(z);}
inline void out_nzterm(int64_t w, int z) {out_w(w); s+="~z"; s+=std::to_string(z);}
inline void out_bvar_term(int cid) {s+=" +1 "; s+=get_bvar(cid); }
inline void out_nbvar_term(int cid) {s+=" +1 "; s+=get_nbvar(cid); }
inline void out_bvar_term(int64_t w, int cid) {out_w(w); s+=get_bvar(cid); }
inline void out_nbvar_term(int64_t w, int cid) {out_w(w); s+=get_nbvar(cid); }
inline void out_add_to_core(int vid) {s+="core id "; s+=std::to_string(vid); s+='\n';}
inline void out_del_id(int vid){s+="del id "; s+=std::to_string(vid); s+='\n';}
inline void out_del_id_pp(int vid){s+="del id "; s+=std::to_string(vid); s+=" ;";}
inline void outnl() {s+='\n'; }
inline void outflush() {out << s; s.clear(); }
private:
struct Clause {
bool is_hard = 0; bool unit_soft = 0; int ulit = 0; int vid = 0; bool deleted = 0;
std::string bvar, nbvar, bvar_substitution, nbvar_substitution;
};
std::vector<Clause> clauses;
std::string compute_bvar(int cid);
std::string compute_nbvar(int cid);
std::string compute_bvar_substitution(int cid);
std::string compute_nbvar_substitution(int cid);
const std::string& get_bvar(int cid);
const std::string& get_nbvar(int cid);
const std::string& get_bvar_substitution(int cid);
const std::string& get_nbvar_substitution(int cid);
std::string get_bvar_substitution(int cid, int lit);
std::string get_nbvar_substitution(int cid, int lit);
void reset_clause_computed_strs(int cid);
std::unordered_map<int, uint64_t> soft_clause_weights;
uint64_t objective_constant;
public:
std::string strclause(std::vector<int>& clause); std::string strsubsts(std::vector<std::pair<int, int> >& substs); private:
void log_objective(bool include_constant = 1, bool negated = 0);
public:
void begin_proof();
void set_nb_clauses(int nbclauses);
void end_proof(bool output_file);
void flush(){ out.flush();}
void set_soft_clause_weight(int cid, uint64_t w);
uint64_t get_soft_clause_weight(int cid);
void add_to_obj_constant(int64_t w);
void log_current_objective();
void set_blocking_lit(int cid, int lit, int label_cid);
void map_clause(int cid, int vid, bool is_hard);
void map_unit_soft(int cid, int lit);
void make_objective_variable(int lit, int cid);
bool is_clause_deleted(int cid1);
void move_to_core(int vid);
int get_vid(int cid);
int add_pol_clause(std::vector<std::pair<int, char> >& operations, bool add_to_core);
int add_pol_clause_(std::vector<std::pair<int, char> > operations, bool add_to_core) {return add_pol_clause(operations, add_to_core); }
int add_rup_clause(std::vector<int>& clause, bool add_to_core);
int add_rup_clause_(std::vector<int> clause, bool add_to_core) {return add_rup_clause(clause, add_to_core);}
int add_red_cc(std::vector<int>& lits, int rhs, int witness_lit, bool add_to_cpre);
int add_red_cc_(std::vector<int> lits, int rhs, int witness_lit, bool add_to_core) {return add_red_cc(lits, rhs, witness_lit, add_to_core);}
int add_red_clause(std::vector<int>& clause, int witness_lit, bool add_to_core) {return add_red_cc(clause, 1, witness_lit, add_to_core);}
int add_red_clause_(std::vector<int> clause, int witness_lit, bool add_to_core) {return add_red_clause(clause, witness_lit, add_to_core);}
int add_red_cc(std::vector<int>& clause, int rhs, std::vector<std::pair<int, int> > witness, bool add_to_core);
int add_red_cc_(std::vector<int> clause, int rhs, std::vector<std::pair<int, int> > witness, bool add_to_core) {return add_red_cc(clause, rhs, witness, add_to_core);}
int add_red_clause(std::vector<int>& clause, std::vector<std::pair<int, int> > witness, bool add_to_core) {return add_red_cc(clause, 1, witness, add_to_core);}
int add_red_clause_(std::vector<int> clause, std::vector<std::pair<int, int> > witness, bool add_to_core) {return add_red_clause(clause, witness, add_to_core);}
int resolve_clauses_vid(int vid1, int vid2, bool add_to_core);
int resolve_clauses(int cid1, int cid2, bool add_to_core);
int add_ub_constraint_on_weight(uint64_t ub, std::vector<std::pair<int, int> >& witness, bool add_to_core);
void delete_clause_vid(int vid, int witness_lit = -1);
void delete_clause_vid(int vid, std::vector<std::pair<int, int> >& witness);
void delete_clause_vid_(int vid, std::vector<std::pair<int, int> > witness) { delete_clause_vid(vid, witness); }
void delete_clause_vid_pol(int vid, std::vector<std::pair<int, char> >& pol_proof);
void delete_clause_vid_pol_(int vid, std::vector<std::pair<int, char> > pol_proof) { delete_clause_vid_pol(vid, pol_proof); }
void soft_clause_satisfied(int cid);
void soft_clause_falsified(int cid);
void delete_red_clause(int cid, int witness_lit=-1);
void delete_red_clause(int cid, std::vector<std::pair<int, int> >& witness);
void delete_red_clause_(int cid, std::vector<std::pair<int, int> > witness) {delete_red_clause(cid, witness);}
void delete_unsat_clause(int cid);
void clause_updated(int cid, std::vector<int>& clause);
void unit_strengthen(int cid, int vid);
void substitute_soft_clause(int cid1, int cid2);
void contradictory_soft_clauses(int cid1, int cid2, int witness_lit);
void labels_matched(std::vector<int>& clause1, std::vector<int>& clause2, int cid1, int cid2, int lb1, int lb2, int witness_lit);
void at_most_one(std::vector<std::pair<int, int> >& soft_clauses, int am1_cid, int label_cid, uint64_t w);
void binary_core_removal1(int cid1, int cid2, int core_cid, std::vector<std::pair<int, std::vector<int> > >& clauses1, std::vector<std::pair<int, std::vector<int> > >& clauses2, std::vector<int>& new_clauses);
void binary_core_removal2(int cid1, int cid2, int core_cid, std::vector<std::pair<int, std::vector<int> > >& clauses1, std::vector<std::pair<int, std::vector<int> > >& clauses2, std::vector<int>& new_clauses);
void binary_core_removal(int cid1, int cid2, int core_cid, std::vector<std::pair<int, std::vector<int> > >& clauses1, std::vector<std::pair<int, std::vector<int> > >& clauses2, std::vector<int>& new_clauses) {
binary_core_removal2(cid1, cid2, core_cid, clauses1, clauses2, new_clauses);
}
void clause_check(int cid, std::vector<int>& clause);
void clause_check(std::vector<int>& clause);
void obju_remove_constant(int cid);
void remap_variables(std::vector<std::pair<int, std::vector<int> > >& original_clauses, std::vector<std::pair<int, int> >& mapping, std::vector<std::pair<uint64_t, int> >& objective);
private:
template<typename T> void error_(T t) {
if (add_comments==0) return;
out << t;
std::cerr << t;
}
template<typename T, typename... Args> void error_(T t, Args... args) {
if (add_comments==0) return;
out << t;
std::cerr << t;
error_(args...);
}
public:
template<typename T> void raw_print(T t) {
out << t;
}
template<typename T, typename... Args> void raw_print(T t, Args... args) {
out << t;
raw_print(args...);
}
template<typename T> void comment(T t) {
if (add_comments==0) return;
out << "* " << t << '\n';
}
template<typename T, typename... Args> void comment(T t, Args... args) {
if (add_comments==0) return;
out << "* " << t;
raw_print(args...);
out << '\n';
}
template<typename T> void error(T t) {
if (add_comments) out << "* ProofLogger Error in " << t << '\n';
std::cerr << "ProofLogger Error in " << t << std::endl;
}
template<typename T, typename... Args> void error(T t, Args... args) {
if (add_comments) out << "* ProofLogger Error in " << t;
std::cerr << "ProofLogger Error in " << t;
error_(args...);
out << '\n';
std::cerr << std::endl;
}
ProofLogger(std::ostream& o, int nbvars, int comments_level);
};
}
#endif