private static void AddFluentClauses(Problem problem, bool requireActivationSupport, bool requireDeactivationSupport, FluentInstantiation before, FluentInstantiation after) { var activate = Activate(before); if (requireActivationSupport) { activate.RequireHaveSupport(); } var deactivate = Deactivate(before); if (requireDeactivationSupport) { deactivate.RequireHaveSupport(); } // TODO - optimize these to generate signed indices directly; this will reduce garbage // activate => after problem.AddClause(after, Not(activate)); // deactivate => not after problem.AddClause(Not(after), Not(deactivate)); // before => after | deactivate problem.AddClause(Not(before), after, deactivate); // not before => not after | activate problem.AddClause(before, Not(after), activate); // Can't simultaneously activate and deactivate problem.AddClause(0, 1, activate, deactivate); }
/// <summary> /// Add clauses that follow from user-defined bounds, e.g. from transitivity. /// </summary> /// <returns></returns> public override string Preprocess() { void PreprecessBounds(List <ConstantBound> constraints, int sign) { foreach (var p in Propositions) { p.Validate(); } constraints.Sort((a, b) => sign * Comparer.Default.Compare(a.Bound, b.Bound)); // Add forward inferences: if v < bounds[i], then v < bounds[i+1] for (int i = 0; i < constraints.Count - 1; i++) { var stronger = constraints[i]; var weaker = constraints[i + 1]; Problem.AddClause(Language.Not(stronger), weaker); } } foreach (var v in Variables) { PreprecessBounds(v.UpperConstantBounds, 1); PreprecessBounds(v.LowerConstantBounds, -1); // Make sure there aren't any propositions dependent on the truth of functional constraint. // We *could* allow this, but given that functional constraint have measure zero, the only // way it's possible for them to be unsatisfied with non-zero probability is through // floating-point quantization. That suggests that someone trying to make a proposition // dependent on a != b+C is probably making a mistake. if (v.AllFunctionalConstraints != null) { foreach (var f in v.AllFunctionalConstraints) { if (f.IsDependency) { throw new InvalidOperationException($"{f.Name}: Inferences dependent on the truth of functional constraint are not supported."); } } } } return(null); }