20 using ::std::dynamic_pointer_cast;
 
   23 using ::std::shared_ptr;
 
   25 using ::std::stringstream;
 
   54         elem_ = other.elem_->clone();
 
   58         *elem_ = 
dynamic_cast<FConst *
>(other.elem_.get())->
asLong();
 
   66         elem_ = ::std::move(other.elem_);
 
   67     } 
else if (other.elem_->fieldType() != 
AGNOSTIC) {
 
   69             "Attempted to move assign field element of incorrect type");
 
   71         *elem_ = 
dynamic_cast<FConst *
>(other.elem_.get())->
asLong();
 
   79     if (lhsField == rhsField)
 
   92         const FConst *fConst = 
dynamic_cast<FConst *
>(elem_.get());
 
   94             fConst != NULL, 
"Cannot convert between specialized field types.");
 
  104     *elem_ *= *other.elem_;
 
  111     *elem_ += *other.elem_;
 
  118     *elem_ -= *other.elem_;
 
  125     return FElem(*(elem_->inverse()));
 
  132         return elem_->getBit(i);
 
  135             "Attempted to extract bits from incompatible field type.");
 
  142     retval.elem_->power(exponent);
 
  160     contents_ += 
dynamic_cast<const FConst &
>(other).contents_;
 
  166     contents_ -= 
dynamic_cast<const FConst &
>(other).contents_;
 
  172     contents_ *= 
dynamic_cast<const FConst &
>(other).contents_;
 
  183     contents_ = 0.5 + ::std::pow(
double(contents_), 
double(exponent));
 
  202         elem_ += 
dynamic_cast<const R1P_Elem &
>(other).elem_;
 
  214         elem_ -= 
dynamic_cast<const R1P_Elem &
>(other).elem_;
 
  226         elem_ *= 
dynamic_cast<const R1P_Elem &
>(other).elem_;
 
  239         return elem_ == pOther->elem_;
 
  241     const FConst *pConst = 
dynamic_cast<const FConst *
>(&other);
 
  243         return *
this == *pConst;
 
  245     GADGETLIB_FATAL(
"Attempted to Compare R1P_Elem with incompatible type.");
 
  256     return long(elem_.as_ulong());
 
  278             "Variable index overflow has occured, maximum number of " 
  289             "Variable index overflow has occured, maximum number of " 
  309         return assignment.at(*
this);
 
  310     } 
catch (::std::out_of_range &) {
 
  312             "Attempted to evaluate unassigned Variable \"%s\", idx:%lu",
 
  338     for (
int i = 0; i < size; ++i) {
 
  346     for (
size_t i = 0; i < size; ++i) {
 
  389     const size_t numBits, 
const FieldType &fieldType, const ::std::string &name)
 
  392     size_t packedSize = getMultipackedSize();
 
  394     VariableArray::swap(varArray);
 
  400     size_t packedSize = getMultipackedSize();
 
  401     VariableArray::resize(packedSize);
 
  404 size_t MultiPackedWord::getMultipackedSize()
 const 
  406     size_t packedSize = 0;
 
  407     if (fieldType_ == 
R1P) {
 
  417     const size_t numBits, 
const FieldType &fieldType, const ::std::string &name)
 
  418     : multipacked_(numBits, fieldType, name + 
"_p")
 
  419     , unpacked_(numBits, name + 
"_u")
 
  425     : multipacked_(multipacked), unpacked_(unpacked)
 
  431     multipacked_.
resize(newSize);
 
  432     unpacked_.resize(newSize);
 
  437     , unpackedContents_(0)
 
  445     : multipackedContents_(multipackedContents)
 
  446     , unpackedContents_(unpackedContents)
 
  447     , numElements_(multipackedContents_.size())
 
  450         multipackedContents_.size() == numElements_,
 
  451         "Dual Variable multipacked contents size mismatch");
 
  453         unpackedContents_.size() == numElements_,
 
  454         "Dual Variable packed contents size mismatch");
 
  459     return multipackedContents_;
 
  465         numElements_ == multipackedContents_.size(),
 
  466         "multipacked contents size mismatch")
 
  468     for (
size_t i = 0; i < numElements_; ++i) {
 
  469         const auto element = multipackedContents_[i];
 
  471             element.size() == 1, 
"Cannot convert from multipacked to packed");
 
  472         retval[i] = element[0];
 
  479     multipackedContents_.push_back(dualWord.
multipacked());
 
  480     unpackedContents_.push_back(dualWord.
unpacked());
 
  496         multipackedContents_.size() == numElements_,
 
  497         "Dual Variable multipacked contents size mismatch");
 
  499         unpackedContents_.size() == numElements_,
 
  500         "Dual Variable packed contents size mismatch");
 
  515         return variable_.
name();
 
  516     } 
else if (coeff_ == -1) {
 
  518     } 
else if (coeff_ == 0) {
 
  522             "%s * %s", coeff_.
asString().c_str(), variable_.
name().c_str());
 
  528     return FElem(coeff_) *= variable_.
eval(assignment);
 
  576         evaluation += lt.eval(assignment);
 
  584     ::std::string retval;
 
  589         retval += it->asString();
 
  592         retval += 
" + " + it->asString();
 
  607         retSet.insert(lt.variable());
 
  619     for (
const Variable &var : inputs) {
 
  636     : coeff_(linearTerm.coeff_), variables_()
 
  638     variables_.insert(linearTerm.variable_);
 
  643     FElem retval = coeff_;
 
  644     for (
const Variable &var : variables_) {
 
  645         retval *= var.eval(assignment);
 
  660     if (variables_.size() == 0) {
 
  667     auto iter = variables_.begin();
 
  668     retval += iter->name();
 
  669     for (++iter; iter != variables_.end(); ++iter) {
 
  670         retval += 
"*" + iter->name();
 
  681     retval.coeff_ = -retval.coeff_;
 
  687     coeff_ *= other.coeff_;
 
  688     variables_.insert(other.variables_.begin(), other.variables_.end());
 
  705     : monomials_(), constant_(linearCombination.constant_)
 
  708         monomials_.push_back(
Monomial(linearTerm));
 
  714     FElem retval = constant_;
 
  715     for (
const Monomial &monomial : monomials_) {
 
  716         retval += monomial.eval(assignment);
 
  724     for (
const Monomial &monomial : monomials_) {
 
  726         retset.insert(curSet.begin(), curSet.end());
 
  740     if (monomials_.size() == 0) {
 
  744     auto iter = monomials_.begin();
 
  745     retval += iter->asString();
 
  746     for (++iter; iter != monomials_.end(); ++iter) {
 
  747         retval += 
" + " + iter->asString();
 
  749     if (constant_ != 0) {
 
  750         retval += 
" + " + constant_.
asString();
 
  757     constant_ += other.constant_;
 
  759         monomials_.end(), other.monomials_.begin(), other.monomials_.end());
 
  765     vector<Monomial> newMonomials;
 
  766     for (
const Monomial &thisMonomial : monomials_) {
 
  767         for (
const Monomial &otherMonomial : other.monomials_) {
 
  768             newMonomials.push_back(thisMonomial * otherMonomial);
 
  770         newMonomials.push_back(thisMonomial * other.constant_);
 
  772     for (
const Monomial &otherMonomial : other.monomials_) {
 
  773         newMonomials.push_back(otherMonomial * this->constant_);
 
  775     constant_ *= other.constant_;
 
  776     monomials_ = ::std::move(newMonomials);
 
  782     constant_ -= other.constant_;
 
  783     for (
const Monomial &otherMonomial : other.monomials_) {
 
  784         monomials_.push_back(-otherMonomial);