Skip to content

Commit 19e7f8c

Browse files
committed
wip
1 parent f5c1035 commit 19e7f8c

File tree

7 files changed

+128
-31
lines changed

7 files changed

+128
-31
lines changed

src/Comparison/Types.hs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
-- License : BSD-3
66
-- Maintainer : jrasheed178@gmail.com
77
-- Stability : experimental
8-
module Comparison.Types where
8+
module Comparison.Types
9+
( MixedComparison (..),
10+
getLHS,
11+
getRHS,
12+
)
13+
where
914

1015
import Control.Applicative (liftA2)
1116
import Foreign.C.Types (CBool)
@@ -18,21 +23,27 @@ data MixedComparison a b = a :<= b | a :>= b | a :== b
1823
instance (Arbitrary a, Arbitrary b) => Arbitrary (MixedComparison a b) where
1924
arbitrary =
2025
oneof
21-
[ liftA2 (:<=) arbitrary arbitrary
22-
, liftA2 (:>=) arbitrary arbitrary
23-
, liftA2 (:==) arbitrary arbitrary
26+
[ liftA2 (:<=) arbitrary arbitrary,
27+
liftA2 (:>=) arbitrary arbitrary,
28+
liftA2 (:==) arbitrary arbitrary
2429
]
2530

26-
getMixedComparisonLHS :: MixedComparison a b -> a
27-
getMixedComparisonLHS (a :<= _) = a
28-
getMixedComparisonLHS (a :>= _) = a
29-
getMixedComparisonLHS (a :== _) = a
31+
getLHS :: MixedComparison a b -> a
32+
getLHS (a :<= _) = a
33+
getLHS (a :>= _) = a
34+
getLHS (a :== _) = a
3035

31-
getMixedComparisonRHS :: MixedComparison a b -> b
32-
getMixedComparisonRHS (_ :<= b) = b
33-
getMixedComparisonRHS (_ :>= b) = b
34-
getMixedComparisonRHS (_ :== b) = b
36+
getRHS :: MixedComparison a b -> b
37+
getRHS (_ :<= b) = b
38+
getRHS (_ :>= b) = b
39+
getRHS (_ :== b) = b
3540

41+
{- Using a class here and staying 'generic' (as in, be permissive on allowed
42+
types) is awkward. I think it's simpler to just stick with the data type.
43+
If we want a class, how do we best define the comparison ops? We'd need a way
44+
for LhsType and RhsType to be compared. Maybe we can use something like
45+
MixedTypesNum, but that's going to take some work.
46+
-}
3647
class MixedComparison2 c where
3748
type LhsType c :: *
3849
type RhsType c :: *

src/Linear/Constraint/Types.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
-- Stability: experimental
88
module Linear.Constraint.Types where
99

10-
import Comparison.Types (MixedComparison)
10+
import Comparison.Types
11+
( MixedComparison,
12+
getLHS,
13+
getRHS,
14+
)
1115
import qualified Data.Set as Set
1216
import GHC.Generics (Generic)
1317
import Linear.Expr.Types (Expr)

src/Linear/Simplex/Solver/Types.hs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ module Linear.Simplex.Solver.Types where
33
import qualified Data.Map as Map
44
import GHC.Generics (Generic)
55
import Linear.Expr.Types (ExprVarsOnly)
6+
import Linear.System.Linear.Types (LinearSystem)
67
import Linear.Var.Types (SimplexNum, Var)
8+
import Linear.SlackForm.Types (SlackForm)
9+
import System.Posix.Types (CMode)
710

811
data OptimisationDirection = Minimize | Maximize
912
deriving (Show, Eq, GHC.Generics.Generic)
@@ -16,10 +19,62 @@ data Objective = Objective
1619

1720
-- TODO: Is it useful to include the system in the result?
1821
data Result = Result
22+
23+
-- TODO: Include the canonical form?
24+
data OptimisationResult = OptimisationResult
1925
{ varMap :: Map.Map Var SimplexNum
2026
, objVal :: SimplexNum
2127
}
2228
deriving (Show, Read, Eq, GHC.Generics.Generic)
2329

2430
-- class (CanBeLinearSystem s) => Solver s where
2531
-- solve :: s -> Objective -> Result
32+
class TwoPhaseSolver inputSystem where
33+
firstPhase :: inputSystem -> Maybe SlackForm
34+
35+
twoPhaseSolve :: inputSystem -> Objective -> Maybe OptimisationResult
36+
twoPhaseSolve inputSystem obj =
37+
let mSf = firstPhase inputSystem
38+
in case mSf of
39+
Nothing -> Nothing
40+
Just sf -> Just $ systemResult $ secondPhase obj sf
41+
where
42+
secondPhase :: Objective -> SlackForm -> SlackForm
43+
secondPhase = undefined
44+
45+
-- This will probably be a proper function
46+
systemResult :: SlackForm -> OptimisationResult
47+
systemResult = undefined
48+
49+
class CanBeStandardForm problem where
50+
findSolution :: problem -> Maybe SlackForm
51+
52+
-- solveStandardForm :: StandardForm -> Objective -> Maybe Result
53+
54+
class LinearSystemProcessor s where
55+
type System s :: *
56+
57+
data FeasibleSystem = FeasibleSystem
58+
{ varVals :: Map.Map Var SimplexNum
59+
, system :: LinearSystem
60+
}
61+
62+
data Model = Model { model :: Map.Map Var SimplexNum }
63+
64+
data SatResult model = Unsat | Sat model
65+
66+
-- s is a system
67+
class (Monad (SatSolverMonad s)) => SatSolver s where
68+
type SatSolverOptions s :: *
69+
type SatSolverMonad s :: * -> *
70+
71+
solve :: SatSolverOptions s -> s -> (SatSolverMonad s) (SatResult Model)
72+
73+
class (Monad (OptSolverMonad s)) => OptSolver s where
74+
type OptSolverOptions s :: *
75+
type OptSolverMonad s :: * -> *
76+
77+
optimise :: OptSolverOptions s -> s -> Objective -> (OptSolverMonad s) (SatResult Model)
78+
79+
-- class (CanBeLinearSystem s) => Solver2 s where
80+
-- solve2 :: s -> Objective -> Result

src/Linear/SlackForm/Types.hs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,24 @@ import qualified Data.Map as Map
1919

2020
-- Expr == SimplexNum
2121
-- TODO: think about a better name for this type, CanonicalForm?
22+
-- TODO: Rename decision: StandardForm? Or, AugmentedForm
23+
-- https://en.wikipedia.org/wiki/Linear_programming#Augmented_form_(slack_form)
2224
data SlackForm = SlackForm
23-
{ maxObjective :: ExprVarsOnly
24-
, constraints :: LinearSystem
25-
, vars :: Set.Set Var -- all vars are non-negative
25+
{ constraints :: LinearSystem
26+
, originalVars :: Set.Set Var -- all vars are non-negative
27+
, slackVars :: Set.Set Var -- all vars are non-negative
28+
, artificialVarsMap :: Map.Map Var Expr -- all vars are non-negative
29+
-- , articialVars :: Set.Set Var -- all vars are non-negative
30+
-- , systemVars :: Set.Set Var -- all vars are non-negative
2631
}
2732
deriving (Show, Eq, Read, Generic)
2833

34+
-- data CanonicalForm = CanonicalForm
35+
-- { maxObjective :: ExprVarsOnly
36+
-- , slackForm :: SlackForm
37+
-- }
38+
-- deriving (Show, Eq, Read, Generic)
39+
2940
data CanonicalForm = CanonicalForm
3041
{ constraints :: LinearSystem
3142
, originalVars :: Set.Set Var
@@ -35,12 +46,12 @@ data CanonicalForm = CanonicalForm
3546
}
3647
deriving (Show, Eq, Read, Generic)
3748

38-
class CanBeSlackForm a where
39-
toSlackForm :: a -> ExprVarsOnly -> SlackForm
49+
-- class CanBeSlackForm a where
50+
-- toSlackForm :: a -> ExprVarsOnly -> SlackForm
4051

41-
instance CanBeSlackForm LinearSystem where
42-
toSlackForm ls obj =
43-
SlackForm
44-
obj
45-
ls
46-
(Set.unions $ map (exprVarsOnlyVars . lhs) ls.unLinearSystem)
52+
-- instance CanBeSlackForm LinearSystem where
53+
-- toSlackForm ls obj =
54+
-- SlackForm
55+
-- obj
56+
-- ls
57+
-- (Set.unions $ map (exprVarsOnlyVars . lhs) ls.unLinearSystem)

src/Linear/SlackForm/Util.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import Linear.Term.Types
3434
)
3535
import Linear.Var.Types (Bounds (..), Var, VarBounds)
3636
import Linear.System.Simple.Util (deriveBounds)
37-
import Linear.SlackForm.Types (CanonicalForm(..))
37+
import Linear.SlackForm.Types (CanonicalForm(..), SlackForm (..))
3838
import qualified Data.Set as Set
3939

4040
-- | Eliminate non-zero lower bounds via substitution
@@ -147,7 +147,23 @@ simpleSystemToCanonicalForm system =
147147
systemVars = SLU.linearSystemVars finalSystem,
148148
systemSlackVars = Set.fromList slackVars,
149149
eliminatedVarsMap = eliminatedVarsMap
150+
}
151+
where
152+
(eliminatedNonZeroLowerBoundVarsMap, system1) = eliminateNonZeroLowerBounds system Map.empty
153+
system1Bounds = deriveBounds system1
154+
(slackVars, linearSystem) = addSlackVars system1
155+
(eliminatedVarsMap, finalSystem)= eliminateUnrestrictedLowerBounds linearSystem system1Bounds eliminatedNonZeroLowerBoundVarsMap
156+
150157
}
158+
simpleSystemToSlackForm :: SimpleSystem -> SlackForm
159+
simpleSystemToSlackForm system =
160+
SlackForm {
161+
constraints = finalSystem,
162+
originalVars = SST.simpleSystemVars system,
163+
-- systemVars = SLU.linearSystemVars finalSystem,
164+
slackVars = Set.fromList slackVars,
165+
artificialVarsMap = eliminatedVarsMap
166+
}
151167
where
152168
(eliminatedNonZeroLowerBoundVarsMap, system1) = eliminateNonZeroLowerBounds system Map.empty
153169
system1Bounds = deriveBounds system1

src/Linear/System/Simple/Types.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
-- Stability: experimental
88
module Linear.System.Simple.Types where
99

10-
import Comparison.Types (getMixedComparisonLHS)
10+
import Comparison.Types (getLHS)
1111
import qualified Data.Set as Set
1212
import GHC.Generics (Generic)
1313
import Linear.Constraint.Simple.Types (SimpleConstraint)
1414
import Linear.Constraint.Simple.Util
15-
( simpleConstraintVars
16-
, simplifySimpleConstraint
15+
( simpleConstraintVars,
16+
simplifySimpleConstraint,
1717
)
1818
import Linear.Expr.Util (exprVarsOnlyToList)
1919
import Linear.System.Types (System)
@@ -37,7 +37,7 @@ simpleSystemVars = Set.unions . map simpleConstraintVars . unSimpleSystem
3737
findHighestVar :: SimpleSystem -> Maybe Var
3838
findHighestVar simpleSystem =
3939
let vars = simpleSystemVars simpleSystem
40-
in if Set.null vars
40+
in if Set.null vars
4141
then Nothing
4242
else Just $ Set.findMax vars
4343

test/Linear/SlackForm/UtilSpec.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Linear.SlackForm.UtilSpec where
22

33
import Comparison.Types
44
( MixedComparison ((:<=), (:==), (:>=))
5-
, getMixedComparisonLHS
5+
, getLHS
66
)
77
import Control.Monad (forM)
88
import Data.Functor ((<&>))
@@ -137,7 +137,7 @@ spec = describe "Slack Form Transformations" $ do
137137
any
138138
( \(SimpleConstraint constraint) ->
139139
let getVars _a = []
140-
lhs = getMixedComparisonLHS constraint
140+
lhs = getLHS constraint
141141
allVars = getVars lhs
142142
in var `notElem` allVars
143143
)

0 commit comments

Comments
 (0)