Skip to content

Commit

Permalink
docs: finished commenting Variable, changed logging calculating cost
Browse files Browse the repository at this point in the history
  • Loading branch information
Casper Bollen authored and Casper Bollen committed Oct 13, 2023
1 parent 51757a7 commit 7d3e74f
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 28 deletions.
14 changes: 8 additions & 6 deletions src/Informedica.GenSolver.Lib/Equation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,13 @@ module Equation =
else true


let calculationToString b op1 op2 x y xs =
let calculationToString b op1 op2 y xs =
let varToStr = Variable.toString b
let opToStr op = $" {op |> Variable.Operators.toString} "
let filter x xs = xs |> List.filter (Variable.eqName x >> not)
let cost = xs |> List.map Variable.count |> List.reduce (*)
let x1 = xs |> List.head

$"""{x |> varToStr} = {y |> varToStr}{op2 |> opToStr}{xs |> filter x |> List.map varToStr |> String.concat (op1 |> opToStr)} """
$"""{y |> varToStr} = {x1 |> varToStr}{op2 |> opToStr}{xs |> List.map varToStr |> String.concat (op1 |> opToStr)} (cost: {cost})"""


/// Solve an equation **e**, return a list of
Expand Down Expand Up @@ -275,12 +276,13 @@ module Equation =
| _ ->
if x |> Variable.isSolved then x
else
let xs = xs |> without x
// log the calculation
(op1, op2, x, y, xs)
(op1, op2, x, y::xs)
|> Events.EquationStartCalculation
|> Logging.logInfo log
// recalculate x
x <== (y |> op2 <| (xs |> without x |> List.reduce op1))
x <== (y |> op2 <| (xs |> List.reduce op1))

(xChanged || (x.Values |> ValueRange.eqs newX.Values |> not))
|> calcXs op1 op2 y (xs |> replAdd newX) tail
Expand All @@ -290,7 +292,7 @@ module Equation =
y, false
else
// log the calculation
(op1, op1, y, (xs |> List.head), (xs |> List.tail))
(op1, op1, y, xs)
|> Events.EquationStartCalculation
|> Logging.logInfo log
// recalculate y
Expand Down
15 changes: 7 additions & 8 deletions src/Informedica.GenSolver.Lib/Scripts/Tests.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ module Tests =
| Some min', Some max' ->
let min = min' |> BigRational.fromInt |> ValueUnit.singleWithUnit Units.Count.times |> Minimum.create minIncl
let max = max' |> BigRational.fromInt |> ValueUnit.singleWithUnit Units.Count.times |> Maximum.create maxIncl
min |> ValueRange.minSTEmax max
min |> minSTEmax max

let min1Options = [None, false; Some -2, true; Some -2, false; Some 0, true; Some 0, false; Some 2, true; Some 2, false]
let max1Options = [None, false; Some -1, true; Some -1, false; Some 0, true; Some 0, false; Some 3, true; Some 3, false]
Expand Down Expand Up @@ -745,10 +745,10 @@ module Tests =
|> List.distinct


let mult = Variable.ValueRange.MinMaxCalculator.multiplication
let div = Variable.ValueRange.MinMaxCalculator.division
let add = Variable.ValueRange.MinMaxCalculator.addition
let sub = Variable.ValueRange.MinMaxCalculator.subtraction
let mult = MinMaxCalculator.multiplication
let div = MinMaxCalculator.division
let add = MinMaxCalculator.addition
let sub = MinMaxCalculator.subtraction


let createVuOpt (intOpt, b) =
Expand All @@ -772,7 +772,7 @@ module Tests =
(min2 |> createVuOpt)
(max2 |> createVuOpt)
|> fun (min, max) -> Variable.ValueRange.create true min None max None
|> Variable.ValueRange.toString true
|> toString true
|> String.replace "x" ""
|> String.replace "<" "< "
|> String.replace ">" " >"
Expand Down Expand Up @@ -1358,7 +1358,7 @@ module Tests =
|> Expect.isTrue "should all be Zero"
}

test "when add/, sub is applied to x1 = Zero and x2 = Unrestricted" {
test "when add, sub is applied to x1 = Zero and x2 = Unrestricted" {
let x1 = 0N |> ValueUnit.singleWithUnit Units.Count.times |> ValueRange.createValSet
let x2 = ValueRange.Unrestricted
[
Expand Down Expand Up @@ -1732,7 +1732,6 @@ Tests.tests

module MinMaxTestScenarios =

open Informedica.Utils.Lib
open Informedica.Utils.Lib.BCL
open Informedica.GenUnits.Lib
open Informedica.GenSolver.Lib
Expand Down
4 changes: 2 additions & 2 deletions src/Informedica.GenSolver.Lib/SolverLogging.fs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ module SolverLogging =
| EquationStartedSolving eq ->
$"=== Start solving Equation ===\n{eq |> toString}"

| EquationStartCalculation (op1, op2, y, x, xs) ->
$"start calculating: {Equation.calculationToString true op1 op2 y x xs}"
| EquationStartCalculation (op1, op2, y, xs) ->
$"start calculating: {Equation.calculationToString true op1 op2 y xs}"

| EquationFinishedCalculation (xs, changed) ->
if not changed then "No Changes"
Expand Down
1 change: 0 additions & 1 deletion src/Informedica.GenSolver.Lib/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ module rec Types =
| EquationStartCalculation of
op1: (Variable -> Variable -> Variable) *
op2: (Variable -> Variable -> Variable) *
x: Variable *
y: Variable *
xs: Variable List
| EquationFinishedCalculation of Variable list * changed : bool
Expand Down
107 changes: 107 additions & 0 deletions src/Informedica.GenSolver.Lib/Variable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2747,6 +2747,19 @@ module Variable =
/// <param name="op">The infix operator</param>
/// <param name="vr1">The first `ValueRange`</param>
/// <param name="vr2">The second `ValueRange`</param>
/// <returns>The resulting `ValueRange`</returns>
/// <example>
/// <code>
/// let vs1 = [| 1N; 2N; 3N |] |> ValueUnit.withUnit Units.Count.times |> ValueSet.create
/// let vs2 = [| 4N; 5N; 6N |] |> ValueUnit.withUnit Units.Count.times |> ValueSet.create
/// let vr1 = create true None None None (Some vs1)
/// let vr2 = create true None None None (Some vs2)
/// calc true (*) (vr1, vr2)
/// // returns a ValueRange with a Minimum = 4 and a Maximum = 18
/// calc false (*) (vr1, vr2)
/// // returns a ValueRange [|4N; 5N; 6N; 8N; 10N; 12N; 15N; 18N|]
/// </code>
/// </example>
let calc onlyMinIncrMax op (vr1, vr2) =

let calcMinMax min1 max1 min2 max2 =
Expand Down Expand Up @@ -2837,14 +2850,50 @@ module Variable =
| _ -> create onlyMinIncrMax min incr max None


/// <summary>
/// Checks whether a `ValueRange` vr1 is a subset of
/// `ValueRange` vr2.
/// </summary>
/// <param name="vr1">The first `ValueRange`</param>
/// <param name="vr2">The second `ValueRange`</param>
/// <remarks>
/// Only checks whether the `ValueSet` of vr1 is a subset of
/// the `ValueSet` of vr2.
/// </remarks>
/// <example>
/// <code>
/// let vs1 = [| 1N; 2N; 3N |] |> ValueUnit.withUnit Units.Count.times |> ValueSet.create
/// let vs2 = [| 2N; 3N |] |> ValueUnit.withUnit Units.Count.times |> ValueSet.create
/// let vr1 = create true None None None (Some vs1)
/// let vr2 = create true None None None (Some vs2)
/// vr1 |> isSubSetOf vr2 // returns false
/// vr2 |> isSubSetOf vr1 // returns true
/// </code>
/// </example>
let isSubSetOf vr2 vr1 =
match vr1, vr2 with
| ValSet s1, ValSet s2 -> s2 |> ValueSet.isSubsetOf s1
| _ -> false


/// <summary>
/// Create a set of `Properties` from a `ValueRange`.
/// </summary>
/// <param name="vr"></param>
/// <example>
/// <code>
/// let min = 2N |> ValueUnit.singleWithUnit Units.Count.times |> Minimum.create true
/// let incr = 2N |> ValueUnit.singleWithUnit Units.Count.times |> Increment.create
/// let max = 8N |> ValueUnit.singleWithUnit Units.Count.times |> Maximum.create false
/// let vr = create true (Some min) (Some incr) (Some max) None
/// vr |> toProperties
/// // returns
/// // set
/// // [MinProp (MinIncl (ValueUnit ([|2N|], Count (Times 1N))));
/// // MaxProp (MaxIncl (ValueUnit ([|6N|], Count (Times 1N))));
/// // IncrProp (Increment (ValueUnit ([|2N|], Count (Times 1N))))]
/// </code>
/// </example>
let toProperties vr =
let unr = set []

Expand Down Expand Up @@ -2877,14 +2926,51 @@ module Variable =
|> apply unr nonZero fMin fMax fMinMax fIncr fMinIncr fIncrMax fMinIncrMax fVs


/// <summary>
/// Get the difference between two `ValueRange`s.
/// </summary>
/// <param name="vr1">The first ValueRange</param>
/// <param name="vr2">The second ValueRange</param>
/// <returns>The difference between the two ValueRanges</returns>
/// <example>
/// <code>
/// let min = 2N |> ValueUnit.singleWithUnit Units.Count.times |> Minimum.create true
/// let incr = 2N |> ValueUnit.singleWithUnit Units.Count.times |> Increment.create
/// let max = 8N |> ValueUnit.singleWithUnit Units.Count.times |> Maximum.create false
/// let vr1 = create true (Some min) (Some incr) None None
/// let vr2 = create true None None (Some max) None
/// vr1 |> diffWith vr2
/// </code>
/// </example>
let diffWith vr1 vr2 =
vr1
|> toProperties
|> Set.difference (vr2 |> toProperties)


/// <summary>
/// Set a `ValueRange` expr to a `ValueRange` y.
/// So, the result is equal to or more restrictive than the original `y`.
/// </summary>
/// <param name="onlyMinIncrMax">Whether only min incr max are calculated</param>
/// <param name="y">The `ValueRange` to apply to</param>
/// <param name="expr">The `ValueRange` to apply</param>
/// <returns>The resulting (restricted) `ValueRange`</returns>
/// <example>
/// <code>
/// let min = 2N |> ValueUnit.singleWithUnit Units.Count.times |> Minimum.create true
/// let incr = 2N |> ValueUnit.singleWithUnit Units.Count.times |> Increment.create
/// let max = 8N |> ValueUnit.singleWithUnit Units.Count.times |> Maximum.create false
/// let vr1 = create true (Some min) (Some incr) None None
/// let vr2 = create true None None (Some max) None
/// vr1 |> applyExpr true vr2
/// // returns
/// // MinIncrMax
/// // (MinIncl (ValueUnit ([|2N|], Count (Times 1N))),
/// // Increment (ValueUnit ([|2N|], Count (Times 1N))),
/// // MaxIncl (ValueUnit ([|6N|], Count (Times 1N))))
/// </code>
/// </example>
let applyExpr onlyMinIncrMax y expr =
let appl _ get set vr =
//printfn $"{s}"
Expand Down Expand Up @@ -2943,6 +3029,7 @@ module Variable =
let createSucc = create id


/// A Variable with a Unrestricted `ValueRange`
let empty n = Unrestricted |> createSucc n


Expand All @@ -2962,6 +3049,7 @@ module Variable =
let get = apply id


/// Get the string representation of a `Variable`.
let toString exact ({ Name = n; Values = vs }: Variable) =
vs
|> ValueRange.toString exact
Expand All @@ -2976,6 +3064,8 @@ module Variable =
let getValueRange v = (v |> get).Values


/// Check whether a `Variable` **v** contains
/// a value **v**.
let contains v vr =
vr |> getValueRange |> ValueRange.contains v

Expand Down Expand Up @@ -3024,6 +3114,8 @@ module Variable =
let eqName v1 v2 = v1 |> getName = (v2 |> getName)


/// Check whether the `ValueRange` of **v1**
/// and **v2** are equal.
let eqValues var1 var2 =
var1 |> getValueRange = (var2 |> getValueRange)

Expand All @@ -3047,6 +3139,8 @@ module Variable =
getValueRange >> ValueRange.isUnrestricted


/// Checks whether the ValueRange of a Variable
/// is a MinIncrMax
let isMinIncrMax = getValueRange >> ValueRange.isMinIncrMax


Expand Down Expand Up @@ -3081,6 +3175,12 @@ module Variable =
Values = var.Values |> ValueRange.increaseIncrement lim incr
}

/// <summary>
/// Calculate a ValueSet for a Variable if the Value of the
/// Variable is a MinIncrMax
/// </summary>
/// <param name="var"></param>
/// <returns>A Variable with a ValueSet if this can be calculated</returns>
let minIncrMaxToValues var =
if var |> isMinIncrMax |> not then var
else
Expand All @@ -3099,12 +3199,19 @@ module Variable =
raise e


/// <summary>
/// 'Prunes' the ValueRange of a Variable
/// </summary>
/// <param name="var"></param>
let prune var =
{ var with
Values = var.Values |> ValueRange.prune
}


/// <summary>
/// Set the unit of a Variable
/// </summary>
let setUnit unit var =
{ var with
Values = var.Values |> ValueRange.setUnit unit
Expand Down
22 changes: 11 additions & 11 deletions tests/Informedica.GenSolver.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ module TestSolver =
open Informedica.GenUnits.Lib
open Informedica.GenSolver.Lib

module Api = Informedica.GenSolver.Lib.Api
module Solver = Informedica.GenSolver.Lib.Solver
module Api = Api
module Solver = Solver
module Name = Variable.Name
module ValueRange = Variable.ValueRange
module Minimum = ValueRange.Minimum
Expand All @@ -118,12 +118,12 @@ module TestSolver =

let printEqs = function
| Ok eqs -> eqs |> Solver.printEqs true procss
| Error errs -> failwith "errors"
| Error _ -> failwith "errors"


let printEqsWithUnits = function
| Ok eqs -> eqs |> Solver.printEqs false procss
| Error errs -> failwith "errors"
| Error _ -> failwith "errors"


let setProp n p eqs =
Expand Down Expand Up @@ -160,7 +160,7 @@ module TestSolver =
let setValues u n vals = vals |> createValSet u |> ValsProp |> setProp n

let logger =
fun (s : string) ->
fun (_ : string) ->
() //File.AppendAllLines("examples.log", [s])
|> SolverLogging.logger

Expand Down Expand Up @@ -701,7 +701,7 @@ module Tests =
| Some min', Some max' ->
let min = min' |> BigRational.fromInt |> ValueUnit.singleWithUnit Units.Count.times |> Minimum.create minIncl
let max = max' |> BigRational.fromInt |> ValueUnit.singleWithUnit Units.Count.times |> Maximum.create maxIncl
min |> ValueRange.minSTEmax max
min |> minSTEmax max

let min1Options = [None, false; Some -2, true; Some -2, false; Some 0, true; Some 0, false; Some 2, true; Some 2, false]
let max1Options = [None, false; Some -1, true; Some -1, false; Some 0, true; Some 0, false; Some 3, true; Some 3, false]
Expand Down Expand Up @@ -732,10 +732,10 @@ module Tests =
|> List.distinct


let mult = Variable.ValueRange.MinMaxCalculator.multiplication
let div = Variable.ValueRange.MinMaxCalculator.division
let add = Variable.ValueRange.MinMaxCalculator.addition
let sub = Variable.ValueRange.MinMaxCalculator.subtraction
let mult = MinMaxCalculator.multiplication
let div = MinMaxCalculator.division
let add = MinMaxCalculator.addition
let sub = MinMaxCalculator.subtraction


let createVuOpt (intOpt, b) =
Expand All @@ -759,7 +759,7 @@ module Tests =
(min2 |> createVuOpt)
(max2 |> createVuOpt)
|> fun (min, max) -> Variable.ValueRange.create true min None max None
|> Variable.ValueRange.toString true
|> toString true
|> String.replace "x" ""
|> String.replace "<" "< "
|> String.replace ">" " >"
Expand Down

0 comments on commit 7d3e74f

Please sign in to comment.