--  Copyright (2008-2013) Cédric Coussinet (cedric.coussinet@nomoseed.net)
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU Affero General Public License as published
--  by the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  This program 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 Affero General Public License for more details.

--  You should have received a copy of the GNU Affero General Public License
--  along with this program. If not, see <http://www.gnu.org/licenses/>

with Nomo.Numerics.Reals;

with Nomo.Numerics.Accurately;

with Nomo.Numerics.Fitting;

private with Nomo.Integrations;

private with Nomo.Tolerances;

private with Nomo.Numerics.Reals.Long;

package Nomo.Internal_Messages.Premises is

   pragma Pure;

   use Numerics.Reals;

   use Numerics.Accurately;

   use Numerics.Fitting;

   type Internal_Premise is new Internal_Message with private;

   function Get_Specificity_Log (This : in Internal_Premise) return Real_Accurately;
   pragma Inline (Get_Specificity_Log);

   procedure Maximize (This        : in out Internal_Premise;
                       Fitting_Nbr : in Count);

   function Measure_Distance (This : in Internal_Premise;
                              Sign : in Internal_Message) return Positive_Real;

   procedure Note (This : out Internal_Premise;
                   Sign : in Internal_Message);

private

   use Tolerances;
   use Integrations;

   type Internal_Premise is new Internal_Message with record
      Credibility_Tolerance : Strictly_Positive_Real := Strictly_Positive_Real'First;
      Actuator_Credibility  : Real_0_To_1 := Real_0_To_1'Last;
      Credibility_Trend     : Real_Integration;
      Time_Span_Tolerance   : Strictly_Positive_Real := Strictly_Positive_Real'First;
      Actuator_Time_Span    : Time_Interval := Time_Interval'First;
      Time_Span_Trend       : Time_Integration;
      Specificity_Log       : Real_Accurately := Real_Accurately'First;
      Tolerance             : Tolerance_Flag := Tolerance_Flag'First;
   end record;
   --  La tolérance correspond à 2 fois la variance.

   use Long;

   procedure Maximize_Time_Span (Actuator        : in Time_Interval;
                                 Fitting_Nbr     : in Count;
                                 Time_Span       : out Time_Interval;
                                 Specificity_Log : in out Real_Accurately;
                                 Squares_Sum     : in out Positive_Time;
                                 Tolerance       : in out Strictly_Positive_Real;
                                 Values_Sum      : in out Time);

   procedure Maximize_Credibility (Actuator        : in Real_0_To_1;
                                   Fitting_Nbr     : in Count;
                                   Credibility     : out Real_0_To_1;
                                   Specificity_Log : in out Real_Accurately;
                                   Squares_Sum     : in out Long_Real;
                                   Tolerance       : in out Strictly_Positive_Real;
                                   Values_Sum      : in out Long_Real);
   pragma Precondition (Tolerance > Zero_Plus);
   pragma Postcondition (Tolerance > Zero_Plus);

end Nomo.Internal_Messages.Premises;
