sorts.push_back(PARSER_STATE->mkSort(*i));
}
}
- sortSymbol[t]
+ sortSymbol[t,CHECK_DECLARED]
{ PARSER_STATE->popScope();
// Do NOT call mkSort, since that creates a new sort!
// This name is not its own distinct sort, it's an alias.
| /* function declaration */
DECLARE_FUN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
LPAREN_TOK sortList[sorts] RPAREN_TOK
- sortSymbol[t]
+ sortSymbol[t,CHECK_DECLARED]
{ Debug("parser") << "declare fun: '" << name << "'" << std::endl;
if( sorts.size() > 0 ) {
t = EXPR_MANAGER->mkFunctionType(sorts, t);
| /* function definition */
DEFINE_FUN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
- sortSymbol[t]
+ sortSymbol[t,CHECK_DECLARED]
{ /* add variables to parser state before parsing term */
Debug("parser") << "define fun: '" << name << "'" << std::endl;
if( sortedVarNames.size() > 0 ) {
kind = CVC4::kind::APPLY;
} else {
expr = PARSER_STATE->getVariable(name);
- kind = CVC4::kind::APPLY_UF;
+ Type t = expr.getType();
+ if( t.isConstructor() ){
+ kind = CVC4::kind::APPLY_CONSTRUCTOR;
+ }else if( t.isSelector() ){
+ kind = CVC4::kind::APPLY_SELECTOR;
+ }else if( t.isTester() ){
+ kind = CVC4::kind::APPLY_TESTER;
+ }else{
+ kind = CVC4::kind::APPLY_UF;
+ }
}
args.push_back(expr);
}
PARSER_STATE->getFunction(name));
} else {
expr = PARSER_STATE->getVariable(name);
+ Type t = PARSER_STATE->getType(name);
+ if(t.isConstructor() && ConstructorType(t).getArity() == 0) {
+ // don't require parentheses, immediately turn it into an apply
+ expr = MK_EXPR(CVC4::kind::APPLY_CONSTRUCTOR, expr);
+ }
}
}
@declarations {
Type t;
}
- : ( sortSymbol[t] { sorts.push_back(t); } )*
+ : ( sortSymbol[t,CHECK_DECLARED] { sorts.push_back(t); } )*
;
/**
std::string name;
Type t;
}
- : ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] sortSymbol[t] RPAREN_TOK
+ : ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] sortSymbol[t,CHECK_DECLARED] RPAREN_TOK
{ sortedVars.push_back(make_pair(name, t)); }
)*
;
: symbol[name,check,SYM_SORT]
;
-sortSymbol[CVC4::Type& t]
+sortSymbol[CVC4::Type& t, CVC4::parser::DeclarationCheck check]
@declarations {
std::string name;
std::vector<CVC4::Type> args;
std::vector<uint64_t> numerals;
}
: sortName[name,CHECK_NONE]
- { t = PARSER_STATE->getSort(name); }
+ {
+ if( check == CHECK_DECLARED || PARSER_STATE->isDeclared(name, SYM_SORT) ){
+ t = PARSER_STATE->getSort(name);
+ }else{
+ t = PARSER_STATE->mkUnresolvedType(name);
+ }
+ }
| LPAREN_TOK INDEX_TOK symbol[name,CHECK_NONE,SYM_SORT] nonemptyNumeralList[numerals] RPAREN_TOK
{
if( name == "BitVec" ) {
std::string id;
Type t, t2;
}
- : symbol[id,CHECK_UNDECLARED,SYM_SORT] sortSymbol[t]
+ : symbol[id,CHECK_UNDECLARED,SYM_SORT] sortSymbol[t,CHECK_NONE]
{ ctor.addArg(id, t);
Debug("parser-idt") << "selector: " << id.c_str() << std::endl;
}
<< std::endl;
return RewriteResponse(REWRITE_DONE, in[0][selectorIndex]);
} else {
- TNode gt = in.getType().mkGroundTerm();
+ Node gt = in.getType().mkGroundTerm();
TypeNode gtt = gt.getType();
- Assert( gtt.isDatatype() || gtt.isParametricDatatype() );
+ //Assert( gtt.isDatatype() || gtt.isParametricDatatype() );
if( !gtt.isInstantiatedDatatype() ){
- gt = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
+ gt = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
NodeManager::currentNM()->mkConst(AscriptionType(in.getType().toType())), gt);
}
Debug("datatypes-rewrite") << "DatatypesRewriter::postRewrite: "
size_t selIndex = Datatype::indexOf( sel.toExpr() );
const Datatype& dt = ((DatatypeType)((sel.getType()[0]).toType())).getDatatype();
for( unsigned i = 0; i<dt.getNumConstructors(); i++ ){
- if( dt[i].getNumArgs()>selIndex &&
+ if( dt[i].getNumArgs()>selIndex &&
Node::fromExpr( dt[i][selIndex].getSelector() )==sel ){
return Node::fromExpr( dt[i].getConstructor() );
}
void TheoryDatatypes::notifyEq(TNode lhs, TNode rhs) {
Debug("datatypes") << "TheoryDatatypes::notifyEq(): "
<< lhs << " = " << rhs << endl;
-
+
}
void TheoryDatatypes::notifyCongruent(TNode lhs, TNode rhs) {
Debug("datatypes-debug") << "TheoryDatatypes::notifyCongruent(): done." << endl;
}
-void TheoryDatatypes::preRegisterTerm(TNode n) {
+void TheoryDatatypes::preRegisterTerm(TNode n) {
Debug("datatypes-prereg") << "TheoryDatatypes::preRegisterTerm() " << n << endl;
}
}
//Debug("datatypes-conflict") << d_cc << std::endl;
Node conflict = d_em.getConflict();
- if( Debug.isOn("datatypes") || Debug.isOn("datatypes-split") ||
+ if( Debug.isOn("datatypes") || Debug.isOn("datatypes-split") ||
Debug.isOn("datatypes-cycles") || Debug.isOn("datatypes-conflict") ){
cout << "Conflict constructed : " << conflict << endl;
}
- //if( conflict.getKind()!=kind::AND ){
- // conflict = NodeManager::currentNM()->mkNode(kind::AND, conflict, conflict);
- //}
+ if( conflict.getKind()!=kind::AND ){
+ conflict = NodeManager::currentNM()->mkNode(kind::AND, conflict, conflict);
+ }
d_out->conflict(conflict);
return;
}
//check if empty label (no possible constructors for term)
for( EqList::const_iterator i = lbl->begin(); i != lbl->end(); i++ ) {
Node leqn = (*i);
+ Debug("datatypes-debug") << "checking " << leqn << std::endl;
if( leqn.getKind() == kind::NOT ) {
if( leqn[0].getOperator() == tassertion.getOperator() ) {
if( assertion.getKind() != NOT ) {
Debug("datatypes-gt") << "constructor is " << dtc << std::endl;
Type tspec = dtc.getSpecializedConstructorType(te.getType().toType());
Debug("datatypes-gt") << "tpec is " << tspec << std::endl;
- selectorVals[0] = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
+ selectorVals[0] = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
NodeManager::currentNM()->mkConst(AscriptionType(tspec)), cons);
val = NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, selectorVals );
}
bool TheoryDatatypes::collapseSelector( Node t ) {
if( !hasConflict() && t.getKind() == APPLY_SELECTOR ) {
//collapse constructor
- TypeNode retTyp = t.getType();
+ TypeNode retTyp = t.getType();
TypeNode typ = t[0].getType();
Node sel = t.getOperator();
TypeNode selType = sel.getType();
//check for clash
NodeBuilder<> explanation(kind::AND);
- if( a.getKind() == kind::APPLY_CONSTRUCTOR && b.getKind() == kind::APPLY_CONSTRUCTOR
+ if( a.getKind() == kind::APPLY_CONSTRUCTOR && b.getKind() == kind::APPLY_CONSTRUCTOR
&& a.getOperator()!=b.getOperator() ){
Node ccEq = NodeManager::currentNM()->mkNode( EQUAL, a, b );
d_em.addNode( ccEq, &d_cce );
d_em.addNodeConflict( ccEq, Reason::idt_clash );
Debug("datatypes") << "Clash " << a << " " << b << endl;
- return;
+ return;
}
Debug("datatypes-debug") << "Done clash" << endl;
}
void TheoryDatatypes::addTermToLabels( Node t ) {
- if( ( t.getKind() == VARIABLE || t.getKind() == APPLY_SELECTOR ) &&
- t.getType().isDatatype() ) {
+ if( t.getType().isDatatype() ) {
+ Debug("datatypes-debug") << "Add term to labels " << t << std::endl;
Node tmp = find( t );
if( tmp == t ) {
//add to labels
addTermToLabels( n );
}
}
-
+
void TheoryDatatypes::appendToDiseqList(TNode of, TNode eq) {
Debug("datatypes") << "appending " << eq << endl
<< " to diseq list of " << of << endl;
//record which nodes are waiting to be merged
vector< pair< Node, Node > > mp;
- mp.insert( mp.begin(),
- d_merge_pending[d_merge_pending.size()-1].begin(),
+ mp.insert( mp.begin(),
+ d_merge_pending[d_merge_pending.size()-1].begin(),
d_merge_pending[d_merge_pending.size()-1].end() );
d_merge_pending.pop_back();