Esempio n. 1
0
void QModelBuilderInstGen::constructModelUf( FirstOrderModel* fm, Node op ){
  FirstOrderModelIG* fmig = fm->asFirstOrderModelIG();
  bool setDefaultVal = true;
  Node defaultTerm = d_qe->getTermDatabase()->getModelBasisOpTerm( op );
  //set the values in the model
  for( size_t i=0; i<fmig->d_uf_terms[op].size(); i++ ){
    Node n = fmig->d_uf_terms[op][i];
    if( isTermActive( n ) ){
      Node v = fmig->getRepresentative( n );
      fmig->d_uf_model_gen[op].setValue( fm, n, v );
    }
    //also possible set as default
    if( d_term_selected.find( n )!=d_term_selected.end() || n==defaultTerm ){
      Node v = fmig->getRepresentative( n );
      fmig->d_uf_model_gen[op].setValue( fm, n, v, false );
      if( n==defaultTerm ){
        setDefaultVal = false;
      }
    }
  }
  //set the overall default value if not set already  (is this necessary??)
  if( setDefaultVal ){
    Node defaultVal = d_uf_prefs[op].getBestDefaultValue( defaultTerm, fm );
    fmig->d_uf_model_gen[op].setValue( fm, defaultTerm, defaultVal, false );
  }
  fmig->d_uf_model_gen[op].makeModel( fm, fmig->d_uf_model_tree[op] );
  d_uf_model_constructed[op] = true;
}
Esempio n. 2
0
void QModelBuilderIG::analyzeModel( FirstOrderModel* fm ) {
    FirstOrderModelIG* fmig = fm->asFirstOrderModelIG();
    d_uf_model_constructed.clear();
    //determine if any functions are constant
    for( std::map< Node, uf::UfModelTree >::iterator it = fmig->d_uf_model_tree.begin(); it != fmig->d_uf_model_tree.end(); ++it ) {
        Node op = it->first;
        TermArgBasisTrie tabt;
        for( size_t i=0; i<fmig->d_uf_terms[op].size(); i++ ) {
            Node n = fmig->d_uf_terms[op][i];
            //for calculating if op is constant
            if( !n.getAttribute(NoMatchAttribute()) ) {
                Node v = fmig->getRepresentative( n );
                if( i==0 ) {
                    d_uf_prefs[op].d_const_val = v;
                } else if( v!=d_uf_prefs[op].d_const_val ) {
                    d_uf_prefs[op].d_const_val = Node::null();
                    break;
                }
            }
            //for calculating terms that we don't need to consider
            if( !n.getAttribute(NoMatchAttribute()) || n.getAttribute(ModelBasisArgAttribute())!=0 ) {
                if( !n.getAttribute(BasisNoMatchAttribute()) ) {
                    //need to consider if it is not congruent modulo model basis
                    if( !tabt.addTerm( fmig, n ) ) {
                        BasisNoMatchAttribute bnma;
                        n.setAttribute(bnma,true);
                    }
                }
            }
        }
        if( !d_uf_prefs[op].d_const_val.isNull() ) {
            fmig->d_uf_model_gen[op].setDefaultValue( d_uf_prefs[op].d_const_val );
            fmig->d_uf_model_gen[op].makeModel( fmig, it->second );
            Debug("fmf-model-cons") << "Function " << op << " is the constant function ";
            fmig->printRepresentativeDebug( "fmf-model-cons", d_uf_prefs[op].d_const_val );
            Debug("fmf-model-cons") << std::endl;
            d_uf_model_constructed[op] = true;
        } else {
            d_uf_model_constructed[op] = false;
        }
    }
}
Esempio n. 3
0
void QModelBuilderDefault::constructModelUf( FirstOrderModel* fm, Node op ) {
    FirstOrderModelIG* fmig = fm->asFirstOrderModelIG();
    if( optReconsiderFuncConstants() ) {
        //reconsider constant functions that weren't necessary
        if( d_uf_model_constructed[op] ) {
            if( d_uf_prefs[op].d_reconsiderModel ) {
                //if we are allowed to reconsider default value, then see if the default value can be improved
                Node v = d_uf_prefs[op].d_const_val;
                if( d_uf_prefs[op].d_value_pro_con[0][v].empty() ) {
                    Debug("fmf-model-cons-debug") << "Consider changing the default value for " << op << std::endl;
                    fmig->d_uf_model_tree[op].clear();
                    fmig->d_uf_model_gen[op].clear();
                    d_uf_model_constructed[op] = false;
                }
            }
        }
    }
    if( !d_uf_model_constructed[op] ) {
        //construct the model for the uninterpretted function/predicate
        bool setDefaultVal = true;
        Node defaultTerm = d_qe->getTermDatabase()->getModelBasisOpTerm( op );
        Trace("fmf-model-cons") << "Construct model for " << op << "..." << std::endl;
        //set the values in the model
        for( size_t i=0; i<fmig->d_uf_terms[op].size(); i++ ) {
            Node n = fmig->d_uf_terms[op][i];
            if( isTermActive( n ) ) {
                Node v = fmig->getRepresentative( n );
                Trace("fmf-model-cons") << "Set term " << n << " : " << fmig->d_rep_set.getIndexFor( v ) << " " << v << std::endl;
                //if this assertion did not help the model, just consider it ground
                //set n = v in the model tree
                //set it as ground value
                fmig->d_uf_model_gen[op].setValue( fm, n, v );
                if( fmig->d_uf_model_gen[op].optUsePartialDefaults() ) {
                    //also set as default value if necessary
                    if( n.hasAttribute(ModelBasisArgAttribute()) && n.getAttribute(ModelBasisArgAttribute())!=0 ) {
                        Trace("fmf-model-cons") << "  Set as default." << std::endl;
                        fmig->d_uf_model_gen[op].setValue( fm, n, v, false );
                        if( n==defaultTerm ) {
                            //incidentally already set, we will not need to find a default value
                            setDefaultVal = false;
                        }
                    }
                } else {
                    if( n==defaultTerm ) {
                        fmig->d_uf_model_gen[op].setValue( fm, n, v, false );
                        //incidentally already set, we will not need to find a default value
                        setDefaultVal = false;
                    }
                }
            }
        }
        //set the overall default value if not set already  (is this necessary??)
        if( setDefaultVal ) {
            Trace("fmf-model-cons") << "  Choose default value..." << std::endl;
            //chose defaultVal based on heuristic, currently the best ratio of "pro" responses
            Node defaultVal = d_uf_prefs[op].getBestDefaultValue( defaultTerm, fm );
            if( defaultVal.isNull() ) {
                if (!fmig->d_rep_set.hasType(defaultTerm.getType())) {
                    Node mbt = d_qe->getTermDatabase()->getModelBasisTerm(defaultTerm.getType());
                    fmig->d_rep_set.d_type_reps[defaultTerm.getType()].push_back(mbt);
                }
                defaultVal = fmig->d_rep_set.d_type_reps[defaultTerm.getType()][0];
            }
            Assert( !defaultVal.isNull() );
            Trace("fmf-model-cons") << "Set default term : " << fmig->d_rep_set.getIndexFor( defaultVal ) << std::endl;
            fmig->d_uf_model_gen[op].setValue( fm, defaultTerm, defaultVal, false );
        }
        Debug("fmf-model-cons") << "  Making model...";
        fmig->d_uf_model_gen[op].makeModel( fm, fmig->d_uf_model_tree[op] );
        d_uf_model_constructed[op] = true;
        Debug("fmf-model-cons") << "  Finished constructing model for " << op << "." << std::endl;
    }
}
Esempio n. 4
0
void QModelBuilderDefault::analyzeQuantifier( FirstOrderModel* fm, Node f ) {
    FirstOrderModelIG* fmig = fm->asFirstOrderModelIG();
    Debug("fmf-model-prefs") << "Analyze quantifier " << f << std::endl;
    //the pro/con preferences for this quantifier
    std::vector< Node > pro_con[2];
    //the terms in the selection literal we choose
    std::vector< Node > selectionLitTerms;
    Trace("inst-gen-debug-quant") << "Inst-gen analyze " << f << std::endl;
    //for each asserted quantifier f,
    // - determine selection literals
    // - check which function/predicates have good and bad definitions for satisfying f
    if( d_phase_reqs.find( f )==d_phase_reqs.end() ) {
        d_phase_reqs[f].initialize( d_qe->getTermDatabase()->getInstConstantBody( f ), true );
    }
    int selectLitScore = -1;
    for( std::map< Node, bool >::iterator it = d_phase_reqs[f].d_phase_reqs.begin(); it != d_phase_reqs[f].d_phase_reqs.end(); ++it ) {
        //the literal n is phase-required for quantifier f
        Node n = it->first;
        Node gn = d_qe->getTermDatabase()->getModelBasis( f, n );
        Debug("fmf-model-req") << "   Req: " << n << " -> " << it->second << std::endl;
        bool value;
        //if the corresponding ground abstraction literal has a SAT value
        if( d_qe->getValuation().hasSatValue( gn, value ) ) {
            //collect the non-ground uf terms that this literal contains
            //  and compute if all of the symbols in this literal have
            //  constant definitions.
            bool isConst = true;
            std::vector< Node > uf_terms;
            if( TermDb::hasInstConstAttr(n) ) {
                isConst = false;
                if( gn.getKind()==APPLY_UF ) {
                    uf_terms.push_back( gn );
                    isConst = hasConstantDefinition( gn );
                } else if( gn.getKind()==EQUAL ) {
                    isConst = true;
                    for( int j=0; j<2; j++ ) {
                        if( TermDb::hasInstConstAttr(n[j]) ) {
                            if( n[j].getKind()==APPLY_UF &&
                                    fmig->d_uf_model_tree.find( gn[j].getOperator() )!=fmig->d_uf_model_tree.end() ) {
                                uf_terms.push_back( gn[j] );
                                isConst = isConst && hasConstantDefinition( gn[j] );
                            } else {
                                isConst = false;
                            }
                        }
                    }
                }
            }
            //check if the value in the SAT solver matches the preference according to the quantifier
            int pref = 0;
            if( value!=it->second ) {
                //we have a possible selection literal
                bool selectLit = d_quant_selection_lit[f].isNull();
                bool selectLitConstraints = true;
                //it is a constantly defined selection literal : the quantifier is sat
                if( isConst ) {
                    selectLit = selectLit || d_quant_sat.find( f )==d_quant_sat.end();
                    d_quant_sat[f] = true;
                    //check if choosing this literal would add any additional constraints to default definitions
                    selectLitConstraints = false;
                    for( int j=0; j<(int)uf_terms.size(); j++ ) {
                        Node op = uf_terms[j].getOperator();
                        if( d_uf_prefs[op].d_reconsiderModel ) {
                            selectLitConstraints = true;
                        }
                    }
                    if( !selectLitConstraints ) {
                        selectLit = true;
                    }
                }
                //also check if it is naturally a better literal
                if( !selectLit ) {
                    int score = getSelectionScore( uf_terms );
                    //Trace("inst-gen-debug") << "Check " << score << " < " << selectLitScore << std::endl;
                    selectLit = score<selectLitScore;
                }
                //see if we wish to choose this as a selection literal
                d_quant_selection_lit_candidates[f].push_back( value ? n : n.notNode() );
                if( selectLit ) {
                    selectLitScore = getSelectionScore( uf_terms );
                    Trace("inst-gen-debug") << "Choose selection literal " << gn << std::endl;
                    Trace("inst-gen-debug") << "  flags: " << isConst << " " << selectLitConstraints << " " << selectLitScore << std::endl;
                    d_quant_selection_lit[f] = value ? n : n.notNode();
                    selectionLitTerms.clear();
                    selectionLitTerms.insert( selectionLitTerms.begin(), uf_terms.begin(), uf_terms.end() );
                    if( !selectLitConstraints ) {
                        break;
                    }
                }
                pref = 1;
            } else {
                pref = -1;
            }
            //if we are not yet SAT, so we will add to preferences
            if( d_quant_sat.find( f )==d_quant_sat.end() ) {
                Debug("fmf-model-prefs") << "  It is " << ( pref==1 ? "pro" : "con" );
                Debug("fmf-model-prefs") << " the definition of " << n << std::endl;
                for( int j=0; j<(int)uf_terms.size(); j++ ) {
                    pro_con[ pref==1 ? 0 : 1 ].push_back( uf_terms[j] );
                }
            }
        }
    }
    //process information about selection literal for f
    if( !d_quant_selection_lit[f].isNull() ) {
        d_quant_selection_lit_terms[f].insert( d_quant_selection_lit_terms[f].begin(), selectionLitTerms.begin(), selectionLitTerms.end() );
        for( int i=0; i<(int)selectionLitTerms.size(); i++ ) {
            d_term_selection_lit[ selectionLitTerms[i] ] = d_quant_selection_lit[f];
            d_op_selection_terms[ selectionLitTerms[i].getOperator() ].push_back( selectionLitTerms[i] );
        }
    } else {
        Trace("inst-gen-warn") << "WARNING: " << f << " has no selection literals" << std::endl;
    }
    //process information about requirements and preferences of quantifier f
    if( d_quant_sat.find( f )!=d_quant_sat.end() ) {
        Debug("fmf-model-prefs") << "  * Constant SAT due to definition of ops: ";
        for( int i=0; i<(int)selectionLitTerms.size(); i++ ) {
            Debug("fmf-model-prefs") << selectionLitTerms[i] << " ";
            d_uf_prefs[ selectionLitTerms[i].getOperator() ].d_reconsiderModel = false;
        }
        Debug("fmf-model-prefs") << std::endl;
    } else {
        //note quantifier's value preferences to models
        for( int k=0; k<2; k++ ) {
            for( int j=0; j<(int)pro_con[k].size(); j++ ) {
                Node op = pro_con[k][j].getOperator();
                Node r = fmig->getRepresentative( pro_con[k][j] );
                d_uf_prefs[op].setValuePreference( f, pro_con[k][j], r, k==0 );
            }
        }
    }
}