//==================================================================================================
// G r a p h _ p r o b l e m                                                              Interface
// M i n _ c o s t _ t e n s i o n
// D u a l _ c o s t _ s c a l i n g
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU Library General Public License for more details (http://www.gnu.org).

/*DESCRIPTION*/
/* This module implements an algorithm to solve the minimum cost tension problem in graphs with
   integer values. It solves a Lagrangian relaxation of the minimum cost tension problem,
   which is a minimum cost flow problem. The resolution is performed with the cost-scaling
   algorithm. The cost functions of the arcs are linear as defined by the
   <CODE>clLinearArcData</CODE> class of the <CODE>Structure</CODE> module. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "graph_problem/min_cost_tension/dual_cost_scaling.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guGraphProblemMinCostTensionDualCostScaling
#define guGraphProblemMinCostTensionDualCostScaling

// Headers //---------------------------------------------------------------------------------------
#include <bpp/graph_problem/min_cost_flow.hpp> /*INCLUDE*/
#include <bpp/graph_problem/min_cost_tension/algorithm.hpp> /*INCLUDE*/
#include <bpp/graph_problem/shortest_path.hpp> /*INCLUDE*/
#include <bpp/graph_problem/tension.hpp> /*INCLUDE*/

namespace bpp {

// Importation/Exportation //-----------------------------------------------------------------------
#ifdef GRAPH_PROBLEM_MIN_COST_TENSION_DLL
 #define dll_export DLL_EXPORT
#else
 #define dll_export DLL_IMPORT
#endif

// Namespaces //------------------------------------------------------------------------------------
#define public_area  graphProblemMinCostTensionDualCostScaling
#define private_area graphProblemMinCostTensionDualCostScaling_private

namespace public_area { /*NAMESPACE*/ using namespace graphProblemMinCostTensionAlgorithm; }

namespace private_area {
 using namespace public_area;
 using namespace graphProblemShortestPath;
}

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniGraphProblemMinCostTensionDualCostScaling
has_initializer;

// Macrocommands //---------------------------------------------------------------------------------
/*ALIAS*/
#define tdGraph class prArcData,class prNodeData //

/*ALIAS*/
#define tuGraph prArcData,prNodeData //

// Types & Classes //-------------------------------------------------------------------------------
namespace public_area { template <tdGraph> class clSolveAlgo; }

namespace private_area {
 //------------------------------------------------------------------------------------------Classes
 template <tdGraph> class clPiecewiseConformity;

 class clRelaxedArcData;
 //-----------------------------------------------------------------------------------Variable Types
 typedef graphProblemMinCostTensionStructure::clNodeData clRelaxedNodeData;
 typedef clArc<clRelaxedArcData,clRelaxedNodeData>       clRelaxedArc;
 typedef clGraph<clRelaxedArcData,clRelaxedNodeData>     clRelaxedGraph;
 typedef clNode<clRelaxedArcData,clRelaxedNodeData>      clRelaxedNode;

 typedef clPiecewiseConformity<clRelaxedArcData,clRelaxedNodeData> clRelaxedConformity;
}

// Functions Interface //---------------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 function void buildResidualGraph(clLengthGraph &,clRelaxedGraph &,std_vector(clLengthArc *) &);

 template <tdGraph>
 tyBoolean relaxMinCostTension(clRelaxedGraph &,clGraph<tuGraph> &,tyNodeKey &,tyNodeKey &);

 testing_mode ( function void test(void); )
}

// Errors //----------------------------------------------------------------------------------------
namespace public_area {}

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// S o l v e A l g o  Interface //------------------------------------------------------------------
namespace public_area {
 /*CLASS clSolveAlgo */
 /* Represents an algorithm to solve the minimum cost tension problem in a graph using the
    cost-scaling method on a dual minimum cost flow problem. */
 template <tdGraph> class clSolveAlgo : public clLinearSolver<tuGraph> {
  //-----------------------------------------------------------------------------------------Private
  private_property constructor clSolveAlgo(const clSolveAlgo &);
  private_property clSolveAlgo & operator = (const clSolveAlgo &);
  //------------------------------------------------------------------------------------------Public
  public_property constructor clSolveAlgo(void);
  public_property virtual destructor clSolveAlgo(void);

  public_property virtual tyInteger run(clGraph<tuGraph> &) const;
 };
}

// P i e c e w i s e C o n f o r m i t y  Interface //----------------------------------------------
namespace private_area {
 template <tdGraph> class clPiecewiseConformity {
  //-------------------------------------------------------------------------------------------Types
  public_property typedef clArc<tuGraph> cpArc;
  //-----------------------------------------------------------------------------------------Private
  private_property constructor clPiecewiseConformity(const clPiecewiseConformity &);
  private_property clPiecewiseConformity & operator = (const clPiecewiseConformity &);
  //------------------------------------------------------------------------------------------Public
  public_property constructor clPiecewiseConformity(void) {}
  public_property destructor clPiecewiseConformity(void) {}

  public_property tyReal leftBoundary(const cpArc &) const;
  public_property tyReal rightBoundary(const cpArc &) const;
  public_property tyReal leftDerivative(const cpArc &) const;
  public_property tyReal rightDerivative(const cpArc &) const;
  public_property tyReal maximumDerivative(const cpArc &) const;
  public_property void   nullCost(cpArc &) const;
 };
}

// R e l a x e d A r c D a t a  Interface //--------------------------------------------------------
namespace private_area {
 class clRelaxedArcData {
  //-----------------------------------------------------------------------------------------Friends
  friend class private_area::clInitializer;
  //-----------------------------------------------------------------------------------------Private
  private_property static tyReal atNegativeInfinity;
  private_property static tyReal atPositiveInfinity;
  //------------------------------------------------------------------------------------------Public
  read_write_attribute(tyReal,atMinimumTension,minimumTension);
  read_write_attribute(tyReal,atMaximumTension,maximumTension);
  read_write_attribute(tyReal,atOptimumTension,optimumTension);

  read_write_attribute(tyReal,atShrinkingCost,shrinkingCost);
  read_write_attribute(tyReal,atStretchingCost,stretchingCost);

  read_write_attribute(tyReal,atMinimum,minimum);
  read_write_attribute(tyReal,atMaximum,maximum);
  read_write_attribute(tyReal,atFlow,flow);

  public_property static tyReal negativeInfinity(void) { return (atNegativeInfinity); }
  public_property static tyReal positiveInfinity(void) { return (atPositiveInfinity); }

  public_property constructor clRelaxedArcData(void);
  public_property constructor clRelaxedArcData(const clRelaxedArcData &);
  public_property constructor clRelaxedArcData(clInStream &,tyBoolean) {}
  public_property destructor  clRelaxedArcData(void) {}

  public_property void out(clOutStream &,tyBoolean) const;
 };
}

// Functions Inline //------------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// S o l v e A l g o  Inline //---------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clSolveAlgo */
 /* Builds an algorithm to solve the minimum cost tension problem in a graph. */
 template <tdGraph> inline clSolveAlgo<tuGraph>::clSolveAlgo(void) {}
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clSolveAlgo */ /* Destructs the algorithm. */
 template <tdGraph> inline clSolveAlgo<tuGraph>::~clSolveAlgo(void) {}
}

// P i e c e w i s e C o n f o r m i t y  Inline //-------------------------------------------------
namespace private_area {
 //-------------------------------------------------------------------------------------LeftBoundary
 template <tdGraph>
 inline tyReal clPiecewiseConformity<tuGraph>::leftBoundary(const cpArc & agArc) const {
  tyReal lcTension = agArc.targetNode()->data().potential()-agArc.sourceNode()->data().potential();

  if (lcTension>agArc.data().maximumTension()) return (agArc.data().maximum());
  if (lcTension>agArc.data().optimumTension()) return (agArc.data().stretchingCost());
  if (lcTension>agArc.data().minimumTension()) return (-agArc.data().shrinkingCost());
  return (agArc.data().minimum());
 }
 //------------------------------------------------------------------------------------RightBoundary
 template <tdGraph>
 inline tyReal clPiecewiseConformity<tuGraph>::rightBoundary(const cpArc & agArc) const {
  tyReal lcTension = agArc.targetNode()->data().potential()-agArc.sourceNode()->data().potential();

  if (lcTension>=agArc.data().maximumTension()) return (agArc.data().maximum());
  if (lcTension>=agArc.data().optimumTension()) return (agArc.data().stretchingCost());
  if (lcTension>=agArc.data().minimumTension()) return (-agArc.data().shrinkingCost());
  return (agArc.data().minimum());
 }
 //-----------------------------------------------------------------------------------LeftDerivative
 template <tdGraph>
 inline tyReal clPiecewiseConformity<tuGraph>::leftDerivative(const cpArc & agArc) const {
  tyReal lcFlow = agArc.data().flow();

  if (lcFlow <= -agArc.data().shrinkingCost()) return (agArc.data().minimumTension());
  if (lcFlow<=agArc.data().stretchingCost()) return (agArc.data().optimumTension());
  return (agArc.data().maximumTension());
 }
 //----------------------------------------------------------------------------------RightDerivative
 template <tdGraph>
 inline tyReal clPiecewiseConformity<tuGraph>::rightDerivative(const cpArc & agArc) const {
  tyReal lcFlow = agArc.data().flow();

  if (lcFlow < -agArc.data().shrinkingCost()) return (agArc.data().minimumTension());
  if (lcFlow<agArc.data().stretchingCost()) return (agArc.data().optimumTension());
  return (agArc.data().maximumTension());
 }
 //--------------------------------------------------------------------------------MaximumDerivative
 template <tdGraph>
 inline tyReal clPiecewiseConformity<tuGraph>::maximumDerivative(const cpArc & agArc) const
 { return (agArc.data().maximumTension()); }
 //-----------------------------------------------------------------------------------------NullCost
 template <tdGraph> inline void clPiecewiseConformity<tuGraph>::nullCost(cpArc & agArc) const {
  agArc.data().shrinkingCost()=0.0;
  agArc.data().stretchingCost()=0.0;
  agArc.data().minimumTension()=0.0;
  agArc.data().optimumTension()=0.0;
  agArc.data().maximumTension()=0.0;
 }
}

// R e l a x e d A r c D a t a  Inline //-----------------------------------------------------------
namespace private_area {
 //--------------------------------------------------------------------------------------Constructor
 inline clRelaxedArcData::clRelaxedArcData(void)
 : atMinimumTension(0.0),atMaximumTension(0.0),atOptimumTension(0.0),atShrinkingCost(0.0),
   atStretchingCost(0.0),atMinimum(0.0),atMaximum(0.0),atFlow(0.0) {}
 //--------------------------------------------------------------------------------------Constructor
 inline clRelaxedArcData::clRelaxedArcData(const clRelaxedArcData & agData)
 : atMinimumTension(agData.atMinimumTension),atMaximumTension(agData.atMaximumTension),
   atOptimumTension(agData.atOptimumTension),atShrinkingCost(agData.atShrinkingCost),
   atStretchingCost(agData.atStretchingCost),atMinimum(agData.atMinimum),
   atMaximum(agData.atMaximum),atFlow(agData.atFlow) {}
 //----------------------------------------------------------------------------------------------Out
 inline void clRelaxedArcData::out(clOutStream & agStream,tyBoolean) const {
  if (atMinimumTension==realMin()) agStream << "-oo , ";
  else agStream << atMinimumTension << " , ";

  if (atMaximumTension==realMax()) agStream << "+oo , ";
  else agStream << atMaximumTension << " , ";

  agStream << atOptimumTension << " ; " << atShrinkingCost << " , " << atStretchingCost << " ; ";
  agStream << atMinimum << " , " << atMaximum << " ; " << atFlow;
 }
}

// Functions Implementation //----------------------------------------------------------------------
namespace private_area {
 //------------------------------------------------------------------------------RelaxMinCostTension
 template <tdGraph>
 tyBoolean relaxMinCostTension(clRelaxedGraph & agRelaxedGraph,clGraph<tuGraph> & agGraph,
                               tyNodeKey & agSourceKey,tyNodeKey & agTargetKey) {
  typedef typename clGraph<tuGraph>::cpArcX::const_iterator  cpArcIterator;
  typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator1;
  typedef clRelaxedGraph::cpNodeX::const_iterator            clNodeIterator2;

  cpArcIterator   lcCurrentArc   = agGraph.arcs().begin();
  cpNodeIterator1 lcCurrentNode1 = agGraph.nodes().begin();
  cpArcIterator   lcLastArc      = agGraph.arcs().end();
  cpNodeIterator1 lcLastNode1    = agGraph.nodes().end();

  clArc<tuGraph> * lcArc1;
  clRelaxedArc *   lcArc2;
  clNodeIterator2  lcCurrentNode2;
  tyReal           lcFlowBoundary;
  clNodeIterator2  lcLastNode2;
  clRelaxedNode *  lcNode;
  clRelaxedNode *  lcSourceNode;
  clRelaxedNode *  lcTargetNode;

  // Flow Boundary Search //
  graphProblemTensionAlgorithm::clCompatibleTensionAlgo<tuGraph>::defaultRun(agGraph);
  if (not agGraph.solved()) return (false);
  agGraph.solved()=false;
  lcFlowBoundary=graphProblemMinCostTensionAlgorithm::totalCost(agGraph)+1.0;

  // Nodes Duplication //
  while (lcCurrentNode1!=lcLastNode1) {
   new_object(clRelaxedNode(agRelaxedGraph,(*lcCurrentNode1).first,clRelaxedNodeData()));
   ++lcCurrentNode1;
  }

  // Arcs Duplication //
  while (lcCurrentArc!=lcLastArc) {
   lcArc1=(*lcCurrentArc).second;

   lcArc2=new_object(clRelaxedArc(agRelaxedGraph,lcArc1->key(),clRelaxedArcData(),
                                  lcArc1->sourceNode()->key(),lcArc1->targetNode()->key()));

   lcArc2->data().minimumTension()=lcArc1->data().minimum();
   lcArc2->data().maximumTension()=lcArc1->data().maximum();
   lcArc2->data().optimumTension()=lcArc1->data().optimum();
   lcArc2->data().stretchingCost()=lcArc1->data().stretchingCost();
   lcArc2->data().shrinkingCost()=lcArc1->data().shrinkingCost();
   lcArc2->data().minimum()=-lcFlowBoundary;
   lcArc2->data().maximum()=lcFlowBoundary;
   ++lcCurrentArc;
  }

  // Source & Target Nodes Adding //
  agSourceKey=agRelaxedGraph.getNewNodeKey();
  lcSourceNode=new_object(clRelaxedNode(agRelaxedGraph,agSourceKey,clRelaxedNodeData()));
  agTargetKey=agRelaxedGraph.getNewNodeKey();
  lcTargetNode=new_object(clRelaxedNode(agRelaxedGraph,agTargetKey,clRelaxedNodeData()));

  lcCurrentNode2=agRelaxedGraph.nodes().begin();
  lcLastNode2=agRelaxedGraph.nodes().end();

  while (lcCurrentNode2!=lcLastNode2) {
   lcNode=(*lcCurrentNode2).second;

   if (lcNode!=lcSourceNode and lcNode->incomingArcs().size()==0)
    new_object(clRelaxedArc(agRelaxedGraph,agRelaxedGraph.getNewArcKey(),clRelaxedArcData(),
                            agSourceKey,lcNode->key()));

   if (lcNode!=lcTargetNode and lcNode->outgoingArcs().size()==0)
    new_object(clRelaxedArc(agRelaxedGraph,agRelaxedGraph.getNewArcKey(),clRelaxedArcData(),
                            lcNode->key(),agTargetKey));

   ++lcCurrentNode2;
  }

  return (true);
 }
}

// S o l v e A l g o  Implementation //-------------------------------------------------------------
namespace public_area {
 //----------------------------------------------------------------------------------------------Run
 /*METHOD clSolveAlgo */ /* Solves the minimum cost tension problem in a graph. */
 template <tdGraph> tyInteger clSolveAlgo<tuGraph>::run(clGraph<tuGraph> & agGraph) const {
  typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator1;
  typedef std_vector(private_area::clLengthArc *)           clArcS;
  typedef clArcS::const_iterator                            clArcIterator2;

  typedef graphProblemShortestPath::clFordAlgo<dataStructure::clLengthData,dataStructure::clNoData>
  clShortestPathAlgo;

  typedef clShortestPathAlgo::cpWorkspace clWorkspace;

  clArc<tuGraph> *                  lcArc1;
  private_area::clLengthArc *       lcArc2;
  clArcS                            lcAssociation;
  private_area::clRelaxedConformity lcConformity;
  cpArcIterator1                    lcCurrentArc1;
  clArcIterator2                    lcCurrentArc2;
  tyInteger                         lcIteration;
  cpArcIterator1                    lcLastArc1;
  clArcS                            lcPath;
  private_area::clRelaxedGraph      lcRelaxedGraph;
  private_area::clLengthGraph       lcResidualGraph;
  tyNodeKey                         lcSourceKey;
  tyNodeKey                         lcTargetKey;

  // Relaxed Problem Resolution //
  agGraph.solved()=false;

  if (not private_area::relaxMinCostTension(lcRelaxedGraph,agGraph,lcSourceKey,lcTargetKey))
   return (-1);

  lcIteration=graphProblemMinCostFlowCostScaling::findMinimumCostFlow(lcRelaxedGraph,lcConformity);

  if (lcRelaxedGraph.solved()) {
   // Integer Tension Building //
   delete_object(&(lcRelaxedGraph.node(lcSourceKey)));
   delete_object(&(lcRelaxedGraph.node(lcTargetKey)));
   private_area::buildResidualGraph(lcResidualGraph,lcRelaxedGraph,lcAssociation);

   clShortestPathAlgo(true).run(lcResidualGraph,(*(lcResidualGraph.nodes().begin())).first,
                                (*(lcResidualGraph.nodes().begin())).first,lcPath);

   // Tension Computation //
   lcCurrentArc1=agGraph.arcs().begin();
   lcLastArc1=agGraph.arcs().end();
   lcCurrentArc2=lcAssociation.begin();

   while (lcCurrentArc1!=lcLastArc1) {
    lcArc1=(*lcCurrentArc1).second;
    lcArc2=*lcCurrentArc2;

    lcArc1->data().tension()=static_cast<clWorkspace *>(lcArc2->targetNode()->work())->potential()
                             -static_cast<clWorkspace *>(lcArc2->sourceNode()->work())->potential();

    ++lcCurrentArc1;
    ++lcCurrentArc2;
   }

   deleteNodeWorkspace(lcResidualGraph,clWorkspace());
  }

  agGraph.solved()=lcRelaxedGraph.solved();
  return (lcIteration);
 }
}

// End //-------------------------------------------------------------------------------------------
}
#undef dll_export
#undef tdGraph
#undef tuGraph
#undef public_area
#undef private_area
#endif
 
//==================================================================================================
// G r a p h _ p r o b l e m                                                         Implementation
// M i n _ c o s t _ t e n s i o n
// D u a l _ c o s t _ s c a l i n g
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU Library General Public License for more details (http://www.gnu.org).

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "graph_problem/min_cost_tension/dual_cost_scaling.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define GRAPH_PROBLEM_MIN_COST_TENSION_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/graph_problem/min_cost_tension/dual_cost_scaling.hpp> /*INTERFACE*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  graphProblemMinCostTensionDualCostScaling
#define private_area graphProblemMinCostTensionDualCostScaling_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Graph_problem/Min_cost_tension/Dual_cost_scaling");

// Initialization //--------------------------------------------------------------------------------
#undef iniGraphProblemMinCostTensionDualCostScaling
static_constant(private_area::clInitializer,goInitializer);

// Errors //----------------------------------------------------------------------------------------
namespace public_area {}

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Static Members //--------------------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 property tyReal clRelaxedArcData::atNegativeInfinity;
 property tyReal clRelaxedArcData::atPositiveInfinity;
}

// Functions Implementation //----------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 //-------------------------------------------------------------------------------BuildResidualGraph
 function void buildResidualGraph(clLengthGraph & agResidualGraph,clRelaxedGraph & agGraph,
                                  std_vector(clLengthArc *) & agArcS) {
  typedef clRelaxedGraph::cpArcX::const_iterator  clArcIterator;
  typedef clRelaxedGraph::cpNodeX::const_iterator clNodeIterator;

  clRelaxedArc * lcArc1;
  clLengthArc *  lcArc2;

  private_area::clRelaxedConformity lcConformity;

  clArcIterator  lcCurrentArc  = agGraph.arcs().begin();
  clNodeIterator lcCurrentNode = agGraph.nodes().begin();
  clArcIterator  lcLastArc     = agGraph.arcs().end();
  clNodeIterator lcLastNode    = agGraph.nodes().end();

  // Nodes Duplication //
  while (lcCurrentNode!=lcLastNode) {
   new_object(clLengthNode(agResidualGraph,(*lcCurrentNode).first,dataStructure::clNoData()));
   ++lcCurrentNode;
  }

  // Arcs Duplication //
  agArcS.reserve(agGraph.arcs().size());
  lcCurrentArc=agGraph.arcs().begin();

  while (lcCurrentArc!=lcLastArc) {
   lcArc1=(*lcCurrentArc).second;

   lcArc2=new_object(clLengthArc(agResidualGraph,agResidualGraph.getNewArcKey(),
                     dataStructure::clLengthData(),lcArc1->sourceNode()->key(),
                     lcArc1->targetNode()->key()));

   lcArc2->data().length()=lcConformity.rightDerivative(*lcArc1);
   agArcS.push_back(lcArc2);

   lcArc2=new_object(clLengthArc(agResidualGraph,agResidualGraph.getNewArcKey(),
                     dataStructure::clLengthData(),lcArc1->targetNode()->key(),
                     lcArc1->sourceNode()->key()));

   lcArc2->data().length()=-(lcConformity.leftDerivative(*lcArc1));
   ++lcCurrentArc;
  }
 }
}

// X X X  Implementation //-------------------------------------------------------------------------
namespace {}

// I n i t i a l i z e r  Implementation //---------------------------------------------------------
namespace private_area {
 //--------------------------------------------------------------------------------------------Start
 property void clInitializer::start(void) {
  if (atCounter++ == 0) {
   try {
    #include <bpp/modules.hpp> /*NEED*/
    registerStop(this);
    environment::informInitialization(goModuleName);

    clRelaxedArcData::atNegativeInfinity = realMin();
    clRelaxedArcData::atPositiveInfinity = realMax();
   }

   initializer_catch;
  }
 }
 //---------------------------------------------------------------------------------------------Stop
 property void clInitializer::stop(void) { environment::informTermination(goModuleName); }
}

// End //-------------------------------------------------------------------------------------------
}