Files
ortools-clone/ortools/constraint_solver/csharp/NetDecisionBuilder.cs
Corentin Le Molgat a66a6daac7 Bump Copyright to 2025
2025-01-10 11:35:44 +01:00

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