diff --git a/cplex-hs.cabal b/cplex-hs.cabal
--- a/cplex-hs.cabal
+++ b/cplex-hs.cabal
@@ -1,5 +1,5 @@
 name:                cplex-hs
-version:             0.5.0.0
+version:             0.5.0.2
 synopsis:            high-level CPLEX interface
 -- description:
 License:             BSD3
diff --git a/src/Data/LP.hs b/src/Data/LP.hs
--- a/src/Data/LP.hs
+++ b/src/Data/LP.hs
@@ -1,12 +1,19 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE DeriveGeneric #-}
 
 module Data.LP( -- Variable(..)
                        Constraint(..)
                        ,Constraints(..)
                        ,Algebra(..)
                        ,Optimization(..)
+                       ,(<:)
+                       ,(=:)
+                       ,(>:)
                        ,sum
+                       ,sumc
                        ,forall
                        ,I.Type(..)
                        ,MixedIntegerProblem(..)
@@ -14,6 +21,7 @@
                        ,I.MIPSolution(..)
                        ,I.LPSolution(..)
                        ,simplify
+                       ,buildConstraint
                        ,buildConstraints
                        ,buildObjective
                        ) where
@@ -22,9 +30,12 @@
 import Data.List (intercalate)
 import qualified Prelude as P
 import qualified Data.HashMap.Strict as M
+import qualified Prelude as P
 import Prelude hiding ((*), sum)
 import qualified Data.Internal as I
 import Data.Hashable
+import GHC.Generics
+import Unsafe.Coerce (unsafeCoerce)
 
 data Algebra x = Constant Double
                | Double :* x
@@ -37,6 +48,7 @@
     deriving (Show)
 
 data Constraints x = Constraints [Constraint x]
+    deriving (Show)
 
 instance Monoid (Constraints a) where
   (Constraints xs) `mappend` (Constraints ys) = Constraints $ xs ++ ys
@@ -48,10 +60,6 @@
   show l = intercalate " + " $ map show xs
     where LinearCombination xs = simplify l
 
-
-(*) :: Double -> x -> Algebra x
-a * b = a :* b
-
 instance Num (Algebra x) where
   fromInteger i = Constant $ fromIntegral i
   (LinearCombination xs) + (LinearCombination ys) = LinearCombination $ xs ++ ys
@@ -71,6 +79,7 @@
 sum xs f = P.sum $ map f xs
 
 forall = flip map
+sumc xs f = Constant $ P.sum $ map f xs
 
 simplify :: (Eq a, Hashable a) => Algebra a -> Algebra a
 simplify a@(Constant d) = a
@@ -86,6 +95,7 @@
 
 getVars :: Algebra x -> [(x,Double)]
 getVars (d :* v) = [(v,d)]
+getVars (Constant d) = []
 getVars (LinearCombination xs) = map aux $ filter (\u -> case u of
                                                                   d :* v -> True
                                                                   _ -> False) xs
@@ -132,3 +142,55 @@
 data MixedIntegerProblem a = MILP (Optimization a) (Constraints a) [(a, Maybe Double, Maybe Double)]
                                     [(a,I.Type)] 
     -- deriving Show
+
+
+
+-- class Algabraic a b | a -> b where
+--   liftAlg :: a -> Algebra b   
+-- 
+-- (+:) :: forall a b c. (Algabraic a, Algabraic b) => a -> b -> Algebra c
+-- a +: b = (liftAlg a :: Algebra c) + (liftAlg b :: Algebra c)
+-- 
+data Var = X
+         | Y
+  deriving (Eq, Show)
+instance Generic Var
+-- 
+-- instance forall b. Algabraic Double b where
+--   liftAlg d = (Constant d :: Algebra b)
+-- 
+-- -- instance Algabraic (Algebra x) where
+-- --   liftAlg a = unsafeCoerce a
+-- 
+-- test1 = (1 :* X) :< 3.0
+--
+class Constrainable a b c | a b -> c where
+  (<:) :: a -> b -> c
+  (>:) :: a -> b -> c
+  (=:) :: a -> b -> c
+
+instance (Real a, Num a) => Constrainable (Algebra x) (a) (Constraint x) where
+  lhs <: rhs = lhs :< (Constant $ realToFrac rhs)
+  lhs >: rhs = lhs :> (Constant $ realToFrac rhs)
+  lhs =: rhs = lhs := (Constant $ realToFrac rhs)
+
+instance (Real a, Num a) => Constrainable a (Algebra x) (Constraint x) where
+  lhs <: rhs = (Constant $ realToFrac lhs) :< rhs
+  lhs >: rhs = (Constant $ realToFrac lhs) :> rhs
+  lhs =: rhs = (Constant $ realToFrac lhs) := rhs
+
+class Mult a b c | a b -> c where
+  (*) :: a -> b -> c
+
+instance Mult Double Double Double where
+  a * b = a P.* b
+
+-- instance Mult a Double (Algebra a) where
+--   v * b = b :* v
+
+instance Mult (Algebra a) Double (Algebra a) where
+   (Constant c) * b = Constant (b P.* c)
+   (c :* x) * b = (c P.* b) :* x
+   (LinearCombination xs) * b = LinearCombination $ map (*b) xs 
+
+test = 1 :* X <: (3.0 :: Double)
diff --git a/src/Data/LP/Backend/Cplex.hs b/src/Data/LP/Backend/Cplex.hs
--- a/src/Data/LP/Backend/Cplex.hs
+++ b/src/Data/LP/Backend/Cplex.hs
@@ -118,10 +118,10 @@
     gap <- liftIO $ getMipBestInteger env cbdata wherefrom 
     return gap
 
-addCallBackCut :: (Eq a, Hashable a) => Bound [Variable a] -> CutCallBackM a (Maybe String)
+addCallBackCut :: (Eq a, Hashable a) => LP.Constraint a -> CutCallBackM a (Maybe String)
 addCallBackCut st_ = do
     CutCallBackArgs{..} <- ask
-    let st = tokenizeVars st_ vardic
+    let st = tokenizeVars (LP.buildConstraint st_) vardic
     let (cnstrs,rhs) = toForm st
     liftIO $ addCutFromCallback env cbdata wherefrom (fromIntegral $ length cnstrs) rhs cnstrs CPX_USECUT_FORCE
   where
