content: {-# LANGUAGE QuasiQuotes #-}
  
  module Conjure.Rules.Vertical.Set.ExplicitVarSizeWithDummy where
  
  import Conjure.Rules.Import
  
  
  rule_Comprehension :: Rule
  rule_Comprehension = "set-comprehension{ExplicitVarSizeWithDummy}" `namedRule` theRule where
      theRule (Comprehension body gensOrConds) = do
          (gocBefore, (pat, s), gocAfter) <- matchFirst gensOrConds $ \ goc -> case goc of
              Generator (GenInExpr pat@Single{} s) -> return (pat, matchDefs [opToSet,opToMSet] s)
              _ -> na "rule_Comprehension"
          TypeSet{}                    <- typeOf s
          Set_ExplicitVarSizeWithDummy <- representationOf s
          [values]                     <- downX1 s
          DomainMatrix index inner     <- domainOf values
          let dummy = [essence| max(`&inner`) |]
          let upd val old = lambdaToFunction pat old val
          return
              ( "Vertical rule for set-comprehension, ExplicitVarSizeWithDummy representation"
              , do
                  (jPat, j) <- quantifiedVar
                  let val = [essence| &values[&j] |]
                  return $ Comprehension (upd val body)
                          $  gocBefore
                          ++ [ Generator (GenDomainNoRepr jPat index)
                             , Condition [essence| &val != &dummy |]
                             ]
                          ++ transformBi (upd val) gocAfter
                 )
      theRule _ = na "rule_Comprehension"
  
  
  rule_PowerSet_Comprehension :: Rule
  rule_PowerSet_Comprehension = "set-powerSet-comprehension{ExplicitVarSizeWithDummy}" `namedRule` theRule where
      theRule (Comprehension body gensOrConds) = do
          (gocBefore, (setPat, setPatNum, expr), gocAfter) <- matchFirst gensOrConds $ \ goc -> case goc of
              Generator (GenInExpr setPat@(AbsPatSet pats) expr) -> return (setPat, length pats, expr)
              _ -> na "rule_PowerSet_Comprehension"
          s                            <- match opPowerSet expr
          TypeSet{}                    <- typeOf s
          Set_ExplicitVarSizeWithDummy <- representationOf s
          [values]                     <- downX1 s
          DomainMatrix index inner     <- domainOf values
          let dummy = [essence| max(`&inner`) |]
          let upd val old = lambdaToFunction setPat old val
          return
              ( "Vertical rule for set-comprehension, ExplicitVarSizeWithDummy representation"
              , do
                  outPats <- replicateM setPatNum quantifiedVar
                  let val = AbstractLiteral $ AbsLitSet [ [essence| &values[&j] |] | (_,j) <- outPats ]
                  return $ Comprehension (upd val body) $ concat
                          [ gocBefore
                          , concat
                              [ [ Generator (GenDomainNoRepr pat index)
                                , Condition [essence| &values[&patX] != &dummy |]
                                ]
                              | (pat,patX) <- take 1 outPats
                              ]
                          , concat
                              [ [ Generator (GenDomainNoRepr pat index)
                                , Condition [essence| &patX > &beforeX |]
                                , Condition [essence| &values[&patX] != &dummy |]
                                ]
                              | ((_, beforeX), (pat, patX)) <- zip outPats (drop 1 outPats)
                              ]
                          , transformBi (upd val) gocAfter
                          ]
              )
      theRule _ = na "rule_PowerSet_Comprehension"
  