mirror of
https://github.com/Z3Prover/z3
synced 2025-08-13 14:40:55 +00:00
fixing labels in duality
This commit is contained in:
parent
193e255387
commit
9d611997b3
4 changed files with 114 additions and 22 deletions
|
@ -434,6 +434,7 @@ namespace Duality {
|
||||||
hash_map<func_decl,int> relMap;
|
hash_map<func_decl,int> relMap;
|
||||||
hash_map<ast,Term> varMap;
|
hash_map<ast,Term> varMap;
|
||||||
Edge *map;
|
Edge *map;
|
||||||
|
Term labeled;
|
||||||
|
|
||||||
Edge(Node *_Parent, const Transformer &_F, const std::vector<Node *> &_Children, RPFP *_owner, int _number)
|
Edge(Node *_Parent, const Transformer &_F, const std::vector<Node *> &_Children, RPFP *_owner, int _number)
|
||||||
: F(_F), Parent(_Parent), Children(_Children), dual(expr(_owner->ctx)) {
|
: F(_F), Parent(_Parent), Children(_Children), dual(expr(_owner->ctx)) {
|
||||||
|
@ -634,8 +635,7 @@ namespace Duality {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
#endif
|
#endif
|
||||||
void FromClauses(const std::vector<Term> &clauses,
|
void FromClauses(const std::vector<Term> &clauses);
|
||||||
std::vector<std::vector<label_struct> > &clause_labels);
|
|
||||||
|
|
||||||
void FromFixpointContext(fixedpoint fp, std::vector<Term> &queries);
|
void FromFixpointContext(fixedpoint fp, std::vector<Term> &queries);
|
||||||
|
|
||||||
|
@ -674,6 +674,10 @@ namespace Duality {
|
||||||
|
|
||||||
int EvalTruth(hash_map<ast,int> &memo, Edge *e, const Term &f);
|
int EvalTruth(hash_map<ast,int> &memo, Edge *e, const Term &f);
|
||||||
|
|
||||||
|
void GetLabels(Edge *e, std::vector<symbol> &labels);
|
||||||
|
|
||||||
|
int GetLabelsRec(hash_map<ast,int> *memo, const Term &f, std::vector<symbol> &labels, bool labpos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -838,6 +838,95 @@ namespace Duality {
|
||||||
return SubtermTruth(memo,tl);
|
return SubtermTruth(memo,tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Compute truth values of all boolean subterms in current model.
|
||||||
|
Assumes formulas has been simplified by Z3, so only boolean ops
|
||||||
|
ands and, or, not. Returns result in memo.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int RPFP::GetLabelsRec(hash_map<ast,int> *memo, const Term &f, std::vector<symbol> &labels, bool labpos){
|
||||||
|
if(memo[labpos].find(f) != memo[labpos].end()){
|
||||||
|
return memo[labpos][f];
|
||||||
|
}
|
||||||
|
int res;
|
||||||
|
if(f.is_app()){
|
||||||
|
int nargs = f.num_args();
|
||||||
|
decl_kind k = f.decl().get_decl_kind();
|
||||||
|
if(k == Implies){
|
||||||
|
res = GetLabelsRec(memo,!f.arg(0) || f.arg(1), labels, labpos);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if(k == And) {
|
||||||
|
res = 1;
|
||||||
|
for(int i = 0; i < nargs; i++){
|
||||||
|
int ar = GetLabelsRec(memo,f.arg(i), labels, labpos);
|
||||||
|
if(ar == 0){
|
||||||
|
res = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if(ar == 2)res = 2;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if(k == Or) {
|
||||||
|
res = 0;
|
||||||
|
for(int i = 0; i < nargs; i++){
|
||||||
|
int ar = GetLabelsRec(memo,f.arg(i), labels, labpos);
|
||||||
|
if(ar == 1){
|
||||||
|
res = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if(ar == 2)res = 2;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if(k == Not) {
|
||||||
|
int ar = GetLabelsRec(memo,f.arg(0), labels, !labpos);
|
||||||
|
res = (ar == 0) ? 1 : ((ar == 1) ? 0 : 2);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
bool pos; std::vector<symbol> names;
|
||||||
|
if(f.is_label(pos,names)){
|
||||||
|
res = GetLabelsRec(memo,f.arg(0), labels, labpos);
|
||||||
|
if(pos == labpos && res == (pos ? 1 : 0))
|
||||||
|
for(unsigned i = 0; i < names.size(); i++)
|
||||||
|
labels.push_back(names[i]);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
expr bv = dualModel.eval(f);
|
||||||
|
if(bv.is_app() && bv.decl().get_decl_kind() == Equal &&
|
||||||
|
bv.arg(0).is_array()){
|
||||||
|
bv = EvalArrayEquality(bv);
|
||||||
|
}
|
||||||
|
// Hack!!!! array equalities can occur negatively!
|
||||||
|
if(bv.is_app() && bv.decl().get_decl_kind() == Not &&
|
||||||
|
bv.arg(0).decl().get_decl_kind() == Equal &&
|
||||||
|
bv.arg(0).arg(0).is_array()){
|
||||||
|
bv = dualModel.eval(!EvalArrayEquality(bv.arg(0)));
|
||||||
|
}
|
||||||
|
if(eq(bv,ctx.bool_val(true)))
|
||||||
|
res = 1;
|
||||||
|
else if(eq(bv,ctx.bool_val(false)))
|
||||||
|
res = 0;
|
||||||
|
else
|
||||||
|
res = 2;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
memo[labpos][f] = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RPFP::GetLabels(Edge *e, std::vector<symbol> &labels){
|
||||||
|
if(!e->map || e->map->labeled.null())
|
||||||
|
return;
|
||||||
|
Term tl = Localize(e, e->map->labeled);
|
||||||
|
hash_map<ast,int> memo[2];
|
||||||
|
GetLabelsRec(memo,tl,labels,true);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Z3OPS
|
#ifdef Z3OPS
|
||||||
static Z3_subterm_truth *stt;
|
static Z3_subterm_truth *stt;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1742,8 +1831,7 @@ namespace Duality {
|
||||||
arg.decl().get_decl_kind() == Uninterpreted);
|
arg.decl().get_decl_kind() == Uninterpreted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPFP::FromClauses(const std::vector<Term> &unskolemized_clauses,
|
void RPFP::FromClauses(const std::vector<Term> &unskolemized_clauses){
|
||||||
std::vector<std::vector<label_struct> > &clause_labels){
|
|
||||||
hash_map<func_decl,Node *> pmap;
|
hash_map<func_decl,Node *> pmap;
|
||||||
func_decl fail_pred = ctx.fresh_func_decl("@Fail", ctx.bool_sort());
|
func_decl fail_pred = ctx.fresh_func_decl("@Fail", ctx.bool_sort());
|
||||||
|
|
||||||
|
@ -1810,7 +1898,6 @@ namespace Duality {
|
||||||
|
|
||||||
// create the edges
|
// create the edges
|
||||||
|
|
||||||
clause_labels.resize(clauses.size());
|
|
||||||
for(unsigned i = 0; i < clauses.size(); i++){
|
for(unsigned i = 0; i < clauses.size(); i++){
|
||||||
Term clause = clauses[i];
|
Term clause = clauses[i];
|
||||||
Term body = clause.arg(0);
|
Term body = clause.arg(0);
|
||||||
|
@ -1841,13 +1928,15 @@ namespace Duality {
|
||||||
hash_map<ast,Term> scan_memo;
|
hash_map<ast,Term> scan_memo;
|
||||||
std::vector<Node *> Children;
|
std::vector<Node *> Children;
|
||||||
body = ScanBody(scan_memo,body,pmap,Relparams,Children);
|
body = ScanBody(scan_memo,body,pmap,Relparams,Children);
|
||||||
body = RemoveLabels(body,clause_labels[i]);
|
Term labeled = body;
|
||||||
|
std::vector<label_struct > lbls; // TODO: throw this away for now
|
||||||
|
body = RemoveLabels(body,lbls);
|
||||||
body = body.simplify();
|
body = body.simplify();
|
||||||
|
|
||||||
// Create the edge
|
// Create the edge
|
||||||
Transformer T = CreateTransformer(Relparams,Indparams,body);
|
Transformer T = CreateTransformer(Relparams,Indparams,body);
|
||||||
// Edge *edge =
|
Edge *edge = CreateEdge(Parent,T,Children);
|
||||||
CreateEdge(Parent,T,Children);
|
edge->labeled = labeled;; // remember for label extraction
|
||||||
// edges.push_back(edge);
|
// edges.push_back(edge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ Revision History:
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
#include "expr_abstract.h"
|
#include "expr_abstract.h"
|
||||||
#include "stopwatch.h"
|
#include "stopwatch.h"
|
||||||
|
#include "model_smt2_pp.h"
|
||||||
|
|
||||||
namespace Duality {
|
namespace Duality {
|
||||||
|
|
||||||
|
@ -534,18 +535,20 @@ expr context::make_quant(decl_kind op, const std::vector<sort> &_sorts, const st
|
||||||
std::cout << mk_pp(raw(), m()) << std::endl;
|
std::cout << mk_pp(raw(), m()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void model::show() const {
|
void model::show() const {
|
||||||
std::cout << Z3_model_to_string(ctx(), m_model) << std::endl;
|
model_smt2_pp(std::cout, m(), *m_model, 0);
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Z3_ast ast_to_track = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void include_ast_show(ast &a){
|
void include_ast_show(ast &a){
|
||||||
a.show();
|
a.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void include_model_show(model &a){
|
||||||
|
a.show();
|
||||||
|
}
|
||||||
|
|
||||||
bool expr::is_label (bool &pos,std::vector<symbol> &names) const {
|
bool expr::is_label (bool &pos,std::vector<symbol> &names) const {
|
||||||
buffer< ::symbol> _names;
|
buffer< ::symbol> _names;
|
||||||
bool res = m().is_label(to_expr(raw()),pos,_names);
|
bool res = m().is_label(to_expr(raw()),pos,_names);
|
||||||
|
|
|
@ -161,7 +161,7 @@ void dl_interface::check_reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates 1-1 map between clauses and rpfp edges
|
// creates 1-1 map between clauses and rpfp edges
|
||||||
_d->rpfp->FromClauses(clauses,_d->clause_labels);
|
_d->rpfp->FromClauses(clauses);
|
||||||
|
|
||||||
// populate the edge-to-clause map
|
// populate the edge-to-clause map
|
||||||
for(unsigned i = 0; i < _d->rpfp->edges.size(); ++i)
|
for(unsigned i = 0; i < _d->rpfp->edges.size(); ++i)
|
||||||
|
@ -265,16 +265,12 @@ static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexamp
|
||||||
out << " )\n";
|
out << " )\n";
|
||||||
|
|
||||||
out << " (labels";
|
out << " (labels";
|
||||||
std::vector<RPFP::label_struct> &labels = d->dd()->clause_labels[orig_clause];
|
std::vector<symbol> labels;
|
||||||
{
|
cex.tree->GetLabels(&edge,labels);
|
||||||
hash_map<ast,int> memo;
|
|
||||||
for(unsigned j = 0; j < labels.size(); j++){
|
for(unsigned j = 0; j < labels.size(); j++){
|
||||||
RPFP::label_struct &lab = labels[j];
|
out << " " << labels[j];
|
||||||
int truth = cex.tree->EvalTruth(memo,&edge,lab.value);
|
|
||||||
if(truth == 1 && lab.pos || truth == 0 && !lab.pos)
|
|
||||||
out << " " << lab.name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " )\n";
|
out << " )\n";
|
||||||
|
|
||||||
// reference the proofs of all the children, in syntactic order
|
// reference the proofs of all the children, in syntactic order
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue