Ejemplo n.º 1
0
/**
 * Tests the Term subsumption
 *
 * @param[in] t:    term we are testing subsumption against
 * @return:         true if this is subsumed by @p t
 */
SubsumptionResult Term::IsSubsumed(Term *t, bool unfoldAll) {
    // unfold the continuation
    if(this == t) {
        return E_TRUE;
    }

    if(t->type == TERM_CONTINUATION) {
        TermContinuation *continuation = reinterpret_cast<TermContinuation *>(t);
        Term* unfoldedContinuation = continuation->unfoldContinuation(UnfoldedInType::E_IN_SUBSUMPTION);
        return this->IsSubsumed(unfoldedContinuation, unfoldAll);
    } else if(this->type == TERM_CONTINUATION) {
        TermContinuation *continuation = reinterpret_cast<TermContinuation *>(this);
        Term* unfoldedContinuation = continuation->unfoldContinuation(UnfoldedInType::E_IN_SUBSUMPTION);
        return unfoldedContinuation->IsSubsumed(t, unfoldAll);
    }
    if(this->_inComplement != t->_inComplement) {
        this->dump(); std::cout << " and ";t->dump(); std::cout << "\n";
    }
    assert(this->_inComplement == t->_inComplement);
    assert(this->type != TERM_CONTINUATION && t->type != TERM_CONTINUATION);

    // Else if it is not continuation we first look into cache and then recompute if needed
    SubsumptionResult result;
    #if (OPT_CACHE_SUBSUMES == true)
    if(this->type != TERM_FIXPOINT || !this->_isSubsumedCache.retrieveFromCache(t, result)) {
    #endif
        if (this->_inComplement) {
            if(this->type == TERM_EMPTY) {
                result = (t->type == TERM_EMPTY ? E_TRUE : E_FALSE);
            } else {
                result = t->_IsSubsumedCore(this, unfoldAll);
            }
        } else {
            if(t->type == TERM_EMPTY) {
                result = (this->type == TERM_EMPTY ? E_TRUE : E_FALSE);
            } else {
                result = this->_IsSubsumedCore(t, unfoldAll);
            }
        }
    #if (OPT_CACHE_SUBSUMES == true)
        if(result != E_PARTIALLY && this->type == TERM_FIXPOINT)
            this->_isSubsumedCache.StoreIn(t, result);
    }
    #endif
    assert(!unfoldAll || result != E_PARTIALLY);
#   if (DEBUG_TERM_SUBSUMPTION == true)
    this->dump();
    std::cout << (result == E_TRUE ? " \u2291 " : " \u22E2 ");
    t->dump();
    std::cout << " = " << (result == E_TRUE ? "true" : "false") << "\n\n";
#   endif
    return result;
}
Ejemplo n.º 2
0
SubsumptionResult TermProduct::_IsSubsumedCore(Term* t, bool unfoldAll) {
    assert(t->type == TERM_PRODUCT);

    // Retype and test the subsumption component-wise
    TermProduct *rhs = reinterpret_cast<TermProduct*>(t);
    Term *lhsl = this->left;
    Term *lhsr = this->right;
    Term *rhsl = rhs->left;
    Term *rhsr = rhs->right;

    if(!unfoldAll && (lhsr->IsNotComputed() && rhsr->IsNotComputed())) {
        #if (OPT_EARLY_PARTIAL_SUB == true)
        if(lhsr->type == TERM_CONTINUATION && rhsr->type == TERM_CONTINUATION) {
            return (lhsl->IsSubsumed(rhsl, unfoldAll) == E_FALSE ? E_FALSE : E_PARTIALLY);
        } else {
            SubsumptionResult leftIsSubsumed = lhsl->IsSubsumed(rhsl, unfoldAll);
            if(leftIsSubsumed == E_TRUE) {
                return lhsr->IsSubsumed(rhsr, unfoldAll);
            } else {
                return leftIsSubsumed;
            }
        }
        #else
        return (lhsl->IsSubsumed(rhsl) != E_FALSE && lhsr->IsSubsumed(rhsr) != E_FALSE) ? E_TRUE : E_FALSE;
        #endif
    } if(!unfoldAll && lhsl == rhsl) {
        return lhsr->IsSubsumed(rhsr, unfoldAll);
    } else if(!unfoldAll && lhsr == rhsr) {
        return lhsl->IsSubsumed(rhsl, unfoldAll);
    } else {
        if(lhsl->stateSpaceApprox < lhsr->stateSpaceApprox || unfoldAll) {
            return (lhsl->IsSubsumed(rhsl, unfoldAll) != E_FALSE && lhsr->IsSubsumed(rhsr, unfoldAll) != E_FALSE) ? E_TRUE : E_FALSE;
        } else {
            return (lhsr->IsSubsumed(rhsr, unfoldAll) != E_FALSE && lhsl->IsSubsumed(rhsl, unfoldAll) != E_FALSE) ? E_TRUE : E_FALSE;
        }
    }
}