never executed always true always false
    1 {-# LANGUAGE QuasiQuotes #-}
    2 
    3 module Conjure.Representations.Function.Function1DPartial ( function1DPartial ) where
    4 
    5 -- conjure
    6 import Conjure.Prelude
    7 import Conjure.Language
    8 import Conjure.Language.ZeroVal ( zeroVal, EnumerateDomain )
    9 import Conjure.Representations.Internal
   10 import Conjure.Representations.Common
   11 import Conjure.Representations.Function.Function1D ( domainValues )
   12 
   13 -- unordered-containers
   14 import qualified Data.HashMap.Strict as M
   15 
   16 
   17 function1DPartial :: forall m . (MonadFailDoc m, NameGen m, EnumerateDomain m) => Representation m
   18 function1DPartial = Representation chck downD structuralCons downC up symmetryOrdering
   19 
   20     where
   21 
   22         chck :: TypeOf_ReprCheck m
   23         chck f (DomainFunction _
   24                     attrs@(FunctionAttr _ PartialityAttr_Partial _)
   25                     innerDomainFr
   26                     innerDomainTo) | domainCanIndexMatrix innerDomainFr = do
   27             innerDomainFr' <- f innerDomainFr
   28             innerDomainTo' <- f innerDomainTo
   29             return [ DomainFunction Function_1DPartial attrs fr to
   30                    | fr <- innerDomainFr'
   31                    , to <- innerDomainTo'
   32                    ]
   33         chck _ _ = return []
   34 
   35         nameFlags  = mkOutName (Just "Flags")
   36         nameValues = mkOutName (Just "Values")
   37 
   38         downD :: TypeOf_DownD m
   39         downD (name, domain@(DomainFunction Function_1DPartial
   40                     (FunctionAttr _ PartialityAttr_Partial _)
   41                     innerDomainFr
   42                     innerDomainTo)) | domainCanIndexMatrix innerDomainFr = return $ Just
   43             [ ( nameFlags domain name
   44               , DomainMatrix
   45                   (forgetRepr innerDomainFr)
   46                   DomainBool
   47               )
   48             , ( nameValues domain name
   49               , DomainMatrix
   50                   (forgetRepr innerDomainFr)
   51                   innerDomainTo
   52               )
   53             ]
   54         downD _ = na "{downD} Function1DPartial"
   55 
   56         structuralCons :: TypeOf_Structural m
   57         structuralCons f downX1
   58             (DomainFunction Function_1DPartial
   59                 (FunctionAttr sizeAttr PartialityAttr_Partial jectivityAttr)
   60                 innerDomainFr
   61                 innerDomainTo) | domainCanIndexMatrix innerDomainFr = do
   62 
   63             let injectiveCons flags values = do
   64                     (iPat, i) <- quantifiedVar
   65                     (jPat, j) <- quantifiedVar
   66                     return $ return $ -- list
   67                         [essence|
   68                             and([ &values[&i] != &values[&j]
   69                                 | &iPat : &innerDomainFr
   70                                 , &jPat : &innerDomainFr
   71                                 , &i .< &j
   72                                 , &flags[&i]
   73                                 , &flags[&j]
   74                                 ])
   75                         |]
   76 
   77             let surjectiveCons flags values = do
   78                     (iPat, i) <- quantifiedVar
   79                     (jPat, j) <- quantifiedVar
   80                     return $ return $ -- list
   81                         [essence|
   82                             forAll &iPat : &innerDomainTo .
   83                                 exists &jPat : &innerDomainFr .
   84                                     &flags[&j] /\ &values[&j] = &i
   85                         |]
   86 
   87             let jectivityCons flags values = case jectivityAttr of
   88                     JectivityAttr_None       -> return []
   89                     JectivityAttr_Injective  -> injectiveCons  flags values
   90                     JectivityAttr_Surjective -> surjectiveCons flags values
   91                     JectivityAttr_Bijective  -> (++) <$> injectiveCons  flags values
   92                                                      <*> surjectiveCons flags values
   93 
   94             let cardinality flags = do
   95                     (iPat, i) <- quantifiedVar
   96                     return [essence| sum &iPat : &innerDomainFr . toInt(&flags[&i]) |]
   97 
   98             let dontCareInactives flags values = do
   99                     (iPat, i) <- quantifiedVar
  100                     return $ return $ -- list
  101                         [essence|
  102                             forAll &iPat : &innerDomainFr . &flags[&i] = false ->
  103                                 dontCare(&values[&i])
  104                         |]
  105 
  106             let innerStructuralCons flags values = do
  107                     (iPat, i) <- quantifiedVarOverDomain (forgetRepr innerDomainFr)
  108                     let activeZone b = [essence| forAll &iPat : &innerDomainFr . &flags[&i] -> &b |]
  109 
  110                     -- preparing structural constraints for the inner guys
  111                     innerStructuralConsGen <- f innerDomainTo
  112 
  113                     let inLoop = [essence| &values[&i] |]
  114                     outs <- innerStructuralConsGen inLoop
  115                     return (map activeZone outs)
  116 
  117             return $ \ func -> do
  118                 refs <- downX1 func
  119                 case refs of
  120                     [flags,values] ->
  121                         concat <$> sequence
  122                             [ jectivityCons     flags values
  123                             , dontCareInactives flags values
  124                             , mkSizeCons sizeAttr <$> cardinality flags
  125                             , innerStructuralCons flags values
  126                             ]
  127                     _ -> na "{structuralCons} Function1DPartial"
  128 
  129         structuralCons _ _ _ = na "{structuralCons} Function1DPartial"
  130 
  131         downC :: TypeOf_DownC m
  132         downC ( name
  133               , domain@(DomainFunction Function_1DPartial
  134                     (FunctionAttr _ PartialityAttr_Partial _)
  135                     innerDomainFr
  136                     innerDomainTo)
  137               , viewConstantFunction -> Just vals_
  138               ) | domainCanIndexMatrix innerDomainFr = do
  139             let vals = M.fromList vals_
  140             z <- zeroVal innerDomainTo
  141             froms               <- domainValues innerDomainFr
  142             (flagsOut, valsOut) <- unzip <$> sequence
  143                 [ val
  144                 | fr <- froms
  145                 , let val = case M.lookup fr vals of
  146                                 Nothing -> return (ConstantBool False, z)
  147                                 Just v  -> return (ConstantBool True , v)
  148                 ]
  149             return $ Just
  150                 [ ( nameFlags domain name
  151                   , DomainMatrix
  152                       (forgetRepr innerDomainFr)
  153                       DomainBool
  154                   , ConstantAbstract $ AbsLitMatrix
  155                       (forgetRepr innerDomainFr)
  156                       flagsOut
  157                   )
  158                 , ( nameValues domain name
  159                   , DomainMatrix
  160                       (forgetRepr innerDomainFr)
  161                       innerDomainTo
  162                   , ConstantAbstract $ AbsLitMatrix
  163                       (forgetRepr innerDomainFr)
  164                       valsOut
  165                   )
  166                 ]
  167         downC _ = na "{downC} Function1DPartial"
  168 
  169         up :: TypeOf_Up m
  170         up ctxt (name, domain@(DomainFunction Function_1DPartial
  171                                 (FunctionAttr _ PartialityAttr_Partial _)
  172                                 innerDomainFr _)) =
  173             case (lookup (nameFlags domain name) ctxt, lookup (nameValues domain name) ctxt) of
  174                 ( Just (ConstantAbstract (AbsLitMatrix _ flagMatrix)) ,
  175                   Just (ConstantAbstract (AbsLitMatrix _ valuesMatrix)) ) -> do
  176                     froms          <- domainValues innerDomainFr
  177                     functionValues <- forM (zip3 flagMatrix froms valuesMatrix) $ \ (flag, from, to) ->
  178                         case viewConstantBool flag of
  179                             Just b  -> return $ if b then Just (from,to) else Nothing
  180                             Nothing -> failDoc $ vcat [ "Expected a boolean, but got:" <++> pretty flag
  181                                                    , "When working on:" <+> pretty name
  182                                                    , "With domain:" <+> pretty domain
  183                                                    ]
  184                     return ( name, ConstantAbstract $ AbsLitFunction $ catMaybes functionValues )
  185                 (Nothing, _) -> failDoc $ vcat $
  186                     [ "(in Function1DPartial up 1)"
  187                     , "No value for:" <+> pretty (nameFlags domain name)
  188                     , "When working on:" <+> pretty name
  189                     , "With domain:" <+> pretty domain
  190                     ] ++
  191                     ("Bindings in context:" : prettyContext ctxt)
  192                 (_, Nothing) -> failDoc $ vcat $
  193                     [ "(in Function1DPartial up 2)"
  194                     , "No value for:" <+> pretty (nameValues domain name)
  195                     , "When working on:" <+> pretty name
  196                     , "With domain:" <+> pretty domain
  197                     ] ++
  198                     ("Bindings in context:" : prettyContext ctxt)
  199                 _ -> failDoc $ vcat $
  200                     [ "Expected matrix literals for:" <+> pretty (nameFlags domain name)
  201                                             <+> "and" <+> pretty (nameValues domain name)
  202                     , "When working on:" <+> pretty name
  203                     , "With domain:" <+> pretty domain
  204                     ] ++
  205                     ("Bindings in context:" : prettyContext ctxt)
  206         up _ _ = na "{up} Function1DPartial"
  207 
  208         symmetryOrdering :: TypeOf_SymmetryOrdering m
  209         symmetryOrdering innerSO downX1 inp domain = do
  210             [flags, values] <- downX1 inp
  211             Just [_, (_, DomainMatrix innerDomainFr innerDomainTo)] <- downD ("SO", domain)
  212             (iPat, i) <- quantifiedVar
  213             soValues <- innerSO downX1 [essence| &values[&i] |] innerDomainTo
  214             return
  215                 [essence|
  216                     [ ( -toInt(&flags[&i])
  217                       , &soValues
  218                       )
  219                     | &iPat : &innerDomainFr
  220                     ]
  221                 |]
  222