{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} module Language.Haskell.Liquid.Constraint.Constraint where import Data.Monoid import Data.Maybe import Control.Applicative import Language.Haskell.Liquid.Types import Language.Haskell.Liquid.Constraint.Types import Language.Fixpoint.Types instance Monoid LConstraint where mempty = LC [] mappend (LC cs1) (LC cs2) = LC (cs1 ++ cs2) typeToConstraint t = LC [t] addConstraints t γ = γ {lcs = mappend (typeToConstraint t) (lcs γ)} constraintToLogic γ (LC ts) = pAnd (constraintToLogicOne γ <$> ts) constraintToLogicOne γ env = pAnd [subConstraintToLogicOne (zip xs xts) (last xs, (last $ (fst <$> xts), r)) | xts <- xss] where xts = init env (xs, ts) = unzip xts r = snd $ last env xss = combinations ((\t -> [(x, t) | x <- grapBindsWithType t γ]) <$> ts) subConstraintToLogicOne xts (x', (x, t)) = PImp (pAnd rs) r where (rs , su) = foldl go ([], []) xts ([r], _ ) = go ([], su) (x', (x, t)) go (acc, su) (x', (x, t)) = let (Reft(v, Refa p)) = toReft (fromMaybe mempty (stripRTypeBase t)) su' = (x', EVar x):(v, EVar x) : su in (subst (mkSubst su') p : acc, su') combinations :: [[a]] -> [[a]] combinations [] = [[]] combinations ([]:_) = [] combinations ((y:ys):yss) = [y:xs | xs <- combinations yss] ++ combinations (ys:yss)