class IMPPMIEXPORT FuzzyRestraint;
class IMPPMIEXPORT FuzzyOr;
class IMPPMIEXPORT FuzzyRestraint : public Restraint {
public:
 FuzzyRestraint(Model *m, std::string name) : Restraint(m, name) {}
 virtual double unprotected_evaluate(DerivativeAccumulator *) const = 0;
 virtual ModelObjectsTemp do_get_inputs() const = 0;
 FuzzyOr *operator|(FuzzyRestraint *r);
 IMP_OBJECT_METHODS(FuzzyRestraint);
};
class IMPPMIEXPORT FuzzyOr : public FuzzyRestraint {
 FuzzyRestraint *r1_;
 FuzzyRestraint *r2_;
public:
 FuzzyOr(Model *m, FuzzyRestraint *r1, FuzzyRestraint *r2)
ÂÂÂÂÂ : FuzzyRestraint(m, "FuzzyOr %1%"), r1_(r1), r2_(r2) {
ÂÂÂ std::cerr << "Creating FuzzyOr from " << r1_->get_name() << " (" << r1_
ÂÂÂÂÂÂÂÂÂÂÂÂÂ << ") " << r2_->get_name() << " (" << r2_ << ") "
ÂÂÂÂÂÂÂÂÂÂÂÂÂ << ": " << get_name() << '\n';
 }
 virtual double unprotected_evaluate(DerivativeAccumulator *) const
ÂÂÂÂÂ IMP_OVERRIDE {
ÂÂÂ Model *m(get_model());
ÂÂÂ double const a(r1_->unprotected_evaluate(nullptr));
ÂÂÂ double const b(r2_->unprotected_evaluate(nullptr));
ÂÂÂ return exp(-a) + exp(-b) - exp(-a - b);
 }
 virtual ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE {
ÂÂÂ ModelObjectsTemp ret(r1_->get_inputs());
ÂÂÂ ModelObjectsTemp const tmp(r2_->get_inputs());
ÂÂÂ ret.insert(ret.end(), tmp.begin(), tmp.end());
ÂÂÂ return ret;
 }
 IMP_OBJECT_METHODS(FuzzyOr);
};
FuzzyOr *FuzzyRestraint::operator|(FuzzyRestraint *r) {
 IMP_NEW(IMP::pmi::FuzzyOr, ret, (get_model(), this, r));
 return ret.release();
}