={      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m nopqrstuvwxyzNone!"(*234=BHKM-Give reason for being infeasible, if possibleLThe bound on a variable or constraint is empty - lower bound is above upper.;An integer variable is constrained to be equal to a non-intNone!"(*234=BHKM fA representation that uses native 64-bit ints and 64-bit doubles. Really, this should be 32-bit ints.iAn assignment from variables to values. Maps integer variables to integers, and real variables to reals./The Representation class. Requires its members Z c and R c to be Num, Ord and Eq.AFor some reason, for type inference to work, the members must be data instead of type=. This gives some minor annoyances when unpacking them. See  below.Integers Real numbers LConvert an integer to a real. This should not lose any precision. (whereas fromIntegral 1000 :: Word8 would lose precision) @Retrieve value of integer variable - or 0, if there is no value. =Retrieve value of real variable - or 0, if there is no value.URetrieve value of an integer or real variable, with result cast to a real regardless.4Convert a wrapped (R IntDouble) to an actual Double..Define show manually, so we can strip out the Z and R prefixes.          None!"(*234=BHKM CMaybe a lower bound, the variable's name, and maybe an upper bound.Define upper and lower bounds of program variables. Bounds may be specified multiple times: the intersection of all bounds is used.7Create a lower and upper bound for an integer variable.3Create only a lower bound for an integer variable. 4Create only an upper bound for an integer variable. 'A binary integer variable: can only be 0 or 1.3Create a lower and upper bound for a real variable. /Create only a lower bound for a real variable. !0Create only an upper bound for a real variable.  !  !  !  !None!"(*234=BHKM" Convert a K to its actual representation (Z or R).#Find the result type of merging, or adding, two linear functions: adding two integers produces an integer, while adding a real on either side produces a real.$|Representation of either integral of real linear functions: a list of variables with coefficients, plus a constant summand.'IClassify the result type of a linear function to either integral or real:(Real or mixed R) Integral Z"#$%&'()"#$%&'()')($&%#""#$&%')(None!"(*234=BHKM*AAny linear function can be converted into a real linear function.+Integral variable,$Integral variable with coefficient 1- Real variable. Real variable with coefficient 1/An integral constant summand0An integral constant summand1 Constant 02 Constant 13A real constant{7Helper for applying function to second element of tuple4=Negate a linear function. Negation does not change the kind.5,Multiply a linear function by some constant.uNote that you cannot multiply a linear function by another linear function, as the result would likely be non-linear!6,Multiply a linear function by some constant.7HAdd two linear functions together. They can have different result types.8PSubtract one linear function from another. They can have different result types.*+,-./0123{45678$%&*+,-./012345678$&%*+,-./031245678*+,-./0123{456785678None!"(*234=BHKM9Different kind of constraints.iThese are not all necessary, but I have a hunch that keeping some structure may be helpful in the future. Constructors: :==Equality constraint:<=Less than or equal:<EStrictly less than: this is only allowed for purely integer functions:>=Greater than or equal:>HStrictly greater than: this is only allowed for purely integer functionsBetween Between a b c is equivalent to a :<= b :&& b :<= c:&&Conjunction of two constraints:!"name" :! constr@ Annotate a constraint with a name, or other useless informationCTrueTrivially true constraint 9:;<=>?@ABC 9:;<=>?@AB 9BA@?>=<;:C9 BA@?>=<;:C;<>?@ABNone!"(*234=BHKMD Whole program, parameterised by: ztype of integer variablesrtype of real variablesc*representation of integers and reals (see )FOptimisation directionGThe objective functionH All constraints bundled up with :&&.IUpper and lower bounds of variables. Not all variables need to be mentioned, and if variables are mentioned multiple times, the intersection is used.J7Direction to optimise program in: minimise or maximise. DEFGHIJKLMNO DEFGHIJKLMNO JLKDEFGHIMNODEFGHIJLKMNONone!"(*234=BHKMP`Evaluate a linear function with given assignment. If the linear function is purely integral, a Z will be returned; otherwise, R.QGEvaluate a linear function with given assignment, returning real value.R.Check whether assignment satisfies constraint.SJCheck whether an assignment satisfies the program's constraints and boundsPQRSTPQRSTPQRSTPQRSTNone!"(*234=BHKM= !"#$%&'()*+,-./0123456789:;<=>?@ABDEFGHIJKLMNOPQRST None!"(*234=BHKMUsLinear function is represented as a map from either a integral variable or an real variable, to a real coefficient.W>Create linear function from list of variables and coefficientsX.Evaluate linear function with given assignmentY/Find set of all variables mentioned in functionUVWXYUVWXYUVWXYUVWXY None!"(*234=BHKMZA simple constraint[AMaybe a lower bound, a linear function, and maybe an upper bound.JIn order to be meaningful, at least one of lower or upper bound should be Just.\!Conjunction of simple constraints^4Check whether an assignment satisfies the constraint_"Get set of variables in constraintZ[\]^_Z[\]^_\]Z[^_Z[\]^_ None!"(*234=BHKM`A program represented by objective, constraints and bounds. There is no need for an optimisation direction; the objective is just negated.e.Find set of all variables mentioned in programf!Merge some lower and upper boundsgJCheck whether an assignment satisfies the program's constraints and bounds `abcdefgh `abcdefgh `abcdefgh`abcdefgh None!"(*234=BHKMiConvert a Frontend $ into a Canon UK. Returns the constant summand as well, as Canon Linear do not have these.Should satisfy that Fforall a l. P.evalR a l == evalR a (fst $ linear l) + (snd $ linear l)jConvert a Frontend 9 into a Canon \.Should satisfy that 1forall a c. P.check a c == check a (constraint c)kConvert a Frontend D into a Canon `.LIf we had a solve function that worked on either, it would ideally satisfy (forall p. P.solve p == solve (program p)However, due to potential non-determinism in solving functions, it could be possible to get a different, but still optimal, solution: forall p. let aP = P.solve p p' = program p a = solve p' in P.eval aP (P._objective p) == eval a (_objective p') && check a (P._constraints p) && check ...ijkijkijkijkNone!"(*234=BHKMUVWXYZ[\]^_`abcdefghijk None!"(*234=BHKMlmlmllmNone!"(*234=BHKMnRFind the constants in a program, only by looking at the bounds with lo==up. (See "Numeric.Limp.Canon.Simplify.Stride" to convert constraints to bounds)nnnnNone!"(*234=BHKMp6Convert a single constraint into a bound, if possible. Abounder $ Constraint (5 <= y <= 10) == Bound (Just 5) y (Just 10) Cbounder $ Constraint (5 <= 2y <= 10) == Bound (Just 2.5) y (Just 5) Abounder $ Constraint (10 <= 2y <= 5) == Left InfeasibleBoundEmptyopqropqropqropqrNone!"(*234=BHKMs&Crunch the constraints in some programtICrunch some constraints. Constraints with the same function, for example J 2x + y < 5 && 0 < 2x + y && 2x + y < 10becomes  0 < 2x + y < 5This should satisfy: hforall a c. check a c == check a (crunchConstraint c) forall a. length (checkConstraint c) <= length cststststNone!"(*234=BHKMu6Substitute assignment into linear function. However, U} isn't quite a linear function! That is, it doesn't have a constant summand. So we must return the constant summand we lose. Satisfies: Rforall a b f. let (f', c') = substLinear a f in eval (a <> b) f == eval b f' + c'  subst (x := 5) in 2x + y (y, 10)v<Substitute assignment into a single linear constraint. See w. 15 <= 2x + y <= 10 subst (y := 3) 2 <= 2x <= 7wCSubstitute assignment into a set of linear constraints. Satisfies: Mforall a b f. let c' = substConstraint a c in check (a <> b) c == check b c' 1subst (x := 5) in 15 <= 2x + y <= 20 5 <= y <= 10xBSubstitute assignment into a program. What does this satisfy? Hm.uvwxuvwxuvwxuvwxNone!"(*234=BHKMyzyzyzyz| !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVVWXYZ[\]^_`abcde 6 6 f b g h i K K c j V V X Y Z k l d e m n ^ o pqrstuvwxyz{|}~ limp-0.3.2.0Numeric.Limp.ErrorNumeric.Limp.RepNumeric.Limp.Program.BoundsNumeric.Limp.Program.ResultKindNumeric.Limp.Program.LinearNumeric.Limp.Program.ConstraintNumeric.Limp.Program.ProgramNumeric.Limp.Program.EvalNumeric.Limp.Canon.LinearNumeric.Limp.Canon.ConstraintNumeric.Limp.Canon.ProgramNumeric.Limp.Canon.ConvertNumeric.Limp.Canon.Pretty$Numeric.Limp.Canon.Analyse.Constants#Numeric.Limp.Canon.Simplify.Bounder"Numeric.Limp.Canon.Simplify.Crunch!Numeric.Limp.Canon.Simplify.SubstNumeric.Limp.Canon.SimplifyNumeric.Limp.ProgramNumeric.Limp.Canon InfeasibleInfeasibleBoundEmptyInfeasibleNotIntegral IntDouble AssignmentRepZRfromZzOfrOfzrOfassSizeunwrapR$fShowR$fShowZTFCo:R:ZIntDoubleTFCo:R:RIntDouble$fRepIntDouble$fMonoidAssignmentBBoundsBoundRBoundZ lowerUpperZlowerZupperZbinary lowerUpperRlowerRupperRKRepKMergeLinearLRLZKKRKZtoRzz1rr1conconZc0c1conRneg.**..+..-. ConstraintCTrue:!:&&Between:>:>=:<:<=:==$fMonoidConstraintProgram _direction _objective _constraints_bounds DirectionMaximiseMinimiseprogramminimisemaximiseevalevalRcheck checkProgram checkBoundsmkLinear varsOfLinear Constraint1C1varsOfConstraint varsOfProgram mergeBoundslinear constraintppr $fShowProgramconstantsProgramBoundbounderConstraint1bounderConstraintbounderProgram crunchProgramcrunchConstraint substLinearsubstConstraint1substConstraint substProgramsimplify simplify'on2