235 lines
5.5 KiB
C#
235 lines
5.5 KiB
C#
// Copyright 2010-2025 Google LLC
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
using System;
|
|
using System.Collections;
|
|
|
|
namespace Google.OrTools.ConstraintSolver
|
|
{
|
|
/**
|
|
* This class acts as a intermediate step between a c++ decision builder and a
|
|
* .Net one. Its main purpose is to catch the .Net application exception
|
|
* launched when a failure occurs during the Next() call, and to return
|
|
* silently a System.ApplicationException that will propagate the failure back
|
|
* to the C++ code.
|
|
*
|
|
*/
|
|
public class NetDecisionBuilder : DecisionBuilder
|
|
{
|
|
/**
|
|
* This methods wraps the calls to next() and catches fail exceptions.
|
|
* It currently catches all application exceptions.
|
|
*/
|
|
public override Decision NextWrapper(Solver solver)
|
|
{
|
|
try
|
|
{
|
|
return Next(solver);
|
|
}
|
|
catch (ApplicationException /*e*/)
|
|
{
|
|
// TODO(user): Catch only fail exceptions.
|
|
return solver.MakeFailDecision();
|
|
}
|
|
}
|
|
/**
|
|
* This is the new method to subclass when defining a .Net decision builder.
|
|
*/
|
|
public virtual Decision Next(Solver solver)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This class acts as a intermediate step between a c++ decision and a
|
|
* .Net one. Its main purpose is to catch the .Net application
|
|
* exception launched when a failure occurs during the
|
|
* Apply()/Refute() calls, and to set the ShouldFail() flag on the
|
|
* solver that will propagate the failure back to the C++ code.
|
|
*
|
|
*/
|
|
public class NetDecision : Decision
|
|
{
|
|
/**
|
|
* This methods wraps the calls to Apply() and catches fail exceptions.
|
|
* It currently catches all application exceptions.
|
|
*/
|
|
public override void ApplyWrapper(Solver solver)
|
|
{
|
|
try
|
|
{
|
|
Apply(solver);
|
|
}
|
|
catch (ApplicationException /*e*/)
|
|
{
|
|
// TODO(user): Catch only fail exceptions.
|
|
solver.ShouldFail();
|
|
}
|
|
}
|
|
/**
|
|
* This is a new method to subclass when defining a .Net decision.
|
|
*/
|
|
public virtual void Apply(Solver solver)
|
|
{
|
|
// By default, do nothing
|
|
}
|
|
|
|
public override void RefuteWrapper(Solver solver)
|
|
{
|
|
try
|
|
{
|
|
Refute(solver);
|
|
}
|
|
catch (ApplicationException /*e*/)
|
|
{
|
|
// TODO(user): Catch only fail exceptions.
|
|
solver.ShouldFail();
|
|
}
|
|
}
|
|
/**
|
|
* This is a new method to subclass when defining a .Net decision.
|
|
*/
|
|
public virtual void Refute(Solver solver)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class NetDemon : Demon
|
|
{
|
|
/**
|
|
* This methods wraps the calls to next() and catches fail exceptions.
|
|
*/
|
|
public override void RunWrapper(Solver solver)
|
|
{
|
|
try
|
|
{
|
|
Run(solver);
|
|
}
|
|
catch (ApplicationException /*e*/)
|
|
{
|
|
// TODO(user): Check that this is indeed a fail. Try implementing
|
|
// custom exceptions (hard).
|
|
solver.ShouldFail();
|
|
}
|
|
}
|
|
/**
|
|
* This is the new method to subclass when defining a .Net decision builder.
|
|
*/
|
|
public virtual void Run(Solver solver)
|
|
{
|
|
}
|
|
public override int Priority()
|
|
{
|
|
return Solver.NORMAL_PRIORITY;
|
|
}
|
|
public override string ToString()
|
|
{
|
|
return "NetDemon";
|
|
}
|
|
}
|
|
|
|
public class NetConstraint : Constraint
|
|
{
|
|
public NetConstraint(Solver s) : base(s)
|
|
{
|
|
}
|
|
|
|
public override void InitialPropagateWrapper()
|
|
{
|
|
try
|
|
{
|
|
InitialPropagate();
|
|
}
|
|
catch (ApplicationException /*e*/)
|
|
{
|
|
solver().ShouldFail();
|
|
}
|
|
}
|
|
public virtual void InitialPropagate()
|
|
{
|
|
}
|
|
public override string ToString()
|
|
{
|
|
return "NetConstraint";
|
|
}
|
|
}
|
|
|
|
public class IntVarEnumerator : IEnumerator
|
|
{
|
|
private IntVarIterator iterator_;
|
|
|
|
// Enumerators are positioned before the first element
|
|
// until the first MoveNext() call.
|
|
private bool first_ = true;
|
|
|
|
public IntVarEnumerator(IntVarIterator iterator)
|
|
{
|
|
iterator_ = iterator;
|
|
}
|
|
|
|
public bool MoveNext()
|
|
{
|
|
if (first_)
|
|
{
|
|
iterator_.Init();
|
|
first_ = false;
|
|
}
|
|
else
|
|
{
|
|
iterator_.Next();
|
|
}
|
|
return iterator_.Ok();
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
first_ = true;
|
|
}
|
|
|
|
object IEnumerator.Current
|
|
{
|
|
get {
|
|
return Current;
|
|
}
|
|
}
|
|
|
|
public long Current
|
|
{
|
|
get {
|
|
if (!first_ && iterator_.Ok())
|
|
{
|
|
return iterator_.Value();
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public partial class IntVarIterator : BaseObject, IEnumerable
|
|
{
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return (IEnumerator)GetEnumerator();
|
|
}
|
|
|
|
public IntVarEnumerator GetEnumerator()
|
|
{
|
|
return new IntVarEnumerator(this);
|
|
}
|
|
}
|
|
} // namespace Google.OrTools.ConstraintSolver
|