module ProjectM36.WithNameExpr where
import ProjectM36.Base

-- substitute all instances of With-based macros to remove macro context
-- ideally, we would use a different relational expr type to "prove" that the with macros can no longer exist
type WithNameAssocs = [(GraphRefWithNameExpr, GraphRefRelationalExpr)]
-- | Drop macros into the relational expression wherever they are referenced.
substituteWithNameMacros ::
  WithNameAssocs ->
  GraphRefRelationalExpr ->
  GraphRefRelationalExpr
substituteWithNameMacros :: WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
_ e :: GraphRefRelationalExpr
e@MakeRelationFromExprs{} = GraphRefRelationalExpr
e
substituteWithNameMacros WithNameAssocs
_ e :: GraphRefRelationalExpr
e@MakeStaticRelation{} = GraphRefRelationalExpr
e
substituteWithNameMacros WithNameAssocs
_ e :: GraphRefRelationalExpr
e@ExistingRelation{} = GraphRefRelationalExpr
e
substituteWithNameMacros WithNameAssocs
macros e :: GraphRefRelationalExpr
e@(RelationVariable RelVarName
rvname GraphRefTransactionMarker
tid) =
  let
    macroFilt :: (WithNameExprBase GraphRefTransactionMarker, b) -> Bool
macroFilt (WithNameExpr RelVarName
macroName GraphRefTransactionMarker
macroTid, b
_) = RelVarName
rvname RelVarName -> RelVarName -> Bool
forall a. Eq a => a -> a -> Bool
== RelVarName
macroName Bool -> Bool -> Bool
&& GraphRefTransactionMarker
tidGraphRefTransactionMarker -> GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefTransactionMarker
macroTid in
  case ((WithNameExprBase GraphRefTransactionMarker,
  GraphRefRelationalExpr)
 -> Bool)
-> WithNameAssocs -> WithNameAssocs
forall a. (a -> Bool) -> [a] -> [a]
filter (WithNameExprBase GraphRefTransactionMarker,
 GraphRefRelationalExpr)
-> Bool
forall b. (WithNameExprBase GraphRefTransactionMarker, b) -> Bool
macroFilt WithNameAssocs
macros of
    [] -> GraphRefRelationalExpr
e
    [(WithNameExprBase GraphRefTransactionMarker
_,GraphRefRelationalExpr
replacement)] -> GraphRefRelationalExpr
replacement
    WithNameAssocs
_ -> [Char] -> GraphRefRelationalExpr
forall a. HasCallStack => [Char] -> a
error [Char]
"more than one macro matched!"
substituteWithNameMacros WithNameAssocs
macros (Project AttributeNamesBase GraphRefTransactionMarker
attrs GraphRefRelationalExpr
expr) =
  AttributeNamesBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelationalExprBase a -> RelationalExprBase a
Project AttributeNamesBase GraphRefTransactionMarker
attrs (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
expr)
substituteWithNameMacros WithNameAssocs
macros (Union GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) =
  GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Union (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprA) (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprB)
substituteWithNameMacros WithNameAssocs
macros (Join GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) =
  GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Join (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprA) (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprB)
substituteWithNameMacros WithNameAssocs
macros (Rename RelVarName
attrA RelVarName
attrB GraphRefRelationalExpr
expr) =
  RelVarName
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Rename RelVarName
attrA RelVarName
attrB (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
expr)
substituteWithNameMacros WithNameAssocs
macros (Difference GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) =
  GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Difference (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprA) (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprB)
substituteWithNameMacros WithNameAssocs
macros (Group AttributeNamesBase GraphRefTransactionMarker
attrs RelVarName
attr GraphRefRelationalExpr
expr) =
  AttributeNamesBase GraphRefTransactionMarker
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Group AttributeNamesBase GraphRefTransactionMarker
attrs RelVarName
attr (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
expr)  
substituteWithNameMacros WithNameAssocs
macros (Ungroup RelVarName
attr GraphRefRelationalExpr
expr) =
  RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName -> RelationalExprBase a -> RelationalExprBase a
Ungroup RelVarName
attr (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
expr)  
substituteWithNameMacros WithNameAssocs
macros (Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
pred' GraphRefRelationalExpr
expr) =
  RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict (WithNameAssocs
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
substituteWithNameMacrosRestrictionPredicate WithNameAssocs
macros RestrictionPredicateExprBase GraphRefTransactionMarker
pred') (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
expr)  
substituteWithNameMacros WithNameAssocs
macros (Equals GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) =
  GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Equals (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprA) (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprB)
substituteWithNameMacros WithNameAssocs
macros (NotEquals GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) =
  GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
NotEquals (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprA) (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
exprB)
substituteWithNameMacros WithNameAssocs
macros (Extend ExtendTupleExprBase GraphRefTransactionMarker
extendTup GraphRefRelationalExpr
expr) =
  ExtendTupleExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
ExtendTupleExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Extend (WithNameAssocs
-> ExtendTupleExprBase GraphRefTransactionMarker
-> ExtendTupleExprBase GraphRefTransactionMarker
substituteWitNameMacrosExtendTupleExpr WithNameAssocs
macros ExtendTupleExprBase GraphRefTransactionMarker
extendTup) (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
expr)
substituteWithNameMacros WithNameAssocs
macros (With WithNameAssocs
moreMacros GraphRefRelationalExpr
expr) =
  --collect and update nested with exprs
  let newMacros :: WithNameAssocs
newMacros = ((WithNameExprBase GraphRefTransactionMarker,
  GraphRefRelationalExpr)
 -> WithNameAssocs -> WithNameAssocs)
-> WithNameAssocs -> WithNameAssocs -> WithNameAssocs
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (WithNameExprBase GraphRefTransactionMarker,
 GraphRefRelationalExpr)
-> WithNameAssocs -> WithNameAssocs
forall a.
Eq a =>
(a, GraphRefRelationalExpr)
-> [(a, GraphRefRelationalExpr)] -> [(a, GraphRefRelationalExpr)]
macroFolder WithNameAssocs
macros WithNameAssocs
moreMacros
      macroFolder :: (a, GraphRefRelationalExpr)
-> [(a, GraphRefRelationalExpr)] -> [(a, GraphRefRelationalExpr)]
macroFolder (a
wnexpr, GraphRefRelationalExpr
mexpr) [(a, GraphRefRelationalExpr)]
acc =
        let subExpr :: GraphRefRelationalExpr
subExpr = WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
mexpr in
        ((a, GraphRefRelationalExpr) -> Bool)
-> [(a, GraphRefRelationalExpr)] -> [(a, GraphRefRelationalExpr)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(a
w,GraphRefRelationalExpr
_) -> a
w a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
wnexpr) [(a, GraphRefRelationalExpr)]
acc [(a, GraphRefRelationalExpr)]
-> [(a, GraphRefRelationalExpr)] -> [(a, GraphRefRelationalExpr)]
forall a. [a] -> [a] -> [a]
++ [(a
wnexpr, GraphRefRelationalExpr
subExpr)] in
        --scan for a match- if it exists, replace it (representing a with clause at a lower level
  WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
newMacros GraphRefRelationalExpr
expr


substituteWithNameMacrosRestrictionPredicate :: WithNameAssocs -> GraphRefRestrictionPredicateExpr -> GraphRefRestrictionPredicateExpr
substituteWithNameMacrosRestrictionPredicate :: WithNameAssocs
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
substituteWithNameMacrosRestrictionPredicate WithNameAssocs
macros RestrictionPredicateExprBase GraphRefTransactionMarker
pred' =
  let sub :: RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
sub = WithNameAssocs
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
substituteWithNameMacrosRestrictionPredicate WithNameAssocs
macros in
  case RestrictionPredicateExprBase GraphRefTransactionMarker
pred' of
    RestrictionPredicateExprBase GraphRefTransactionMarker
TruePredicate -> RestrictionPredicateExprBase GraphRefTransactionMarker
pred'
    AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
exprA RestrictionPredicateExprBase GraphRefTransactionMarker
exprB ->
      RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
AndPredicate (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
sub RestrictionPredicateExprBase GraphRefTransactionMarker
exprA) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
sub RestrictionPredicateExprBase GraphRefTransactionMarker
exprB)
    OrPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
exprA RestrictionPredicateExprBase GraphRefTransactionMarker
exprB ->
      RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
OrPredicate (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
sub RestrictionPredicateExprBase GraphRefTransactionMarker
exprA) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
sub RestrictionPredicateExprBase GraphRefTransactionMarker
exprB)
    NotPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
expr ->
      RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
NotPredicate (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
sub RestrictionPredicateExprBase GraphRefTransactionMarker
expr)
    RelationalExprPredicate GraphRefRelationalExpr
reexpr ->
      GraphRefRelationalExpr
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a. RelationalExprBase a -> RestrictionPredicateExprBase a
RelationalExprPredicate (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
reexpr)
    AtomExprPredicate AtomExprBase GraphRefTransactionMarker
atomExpr ->
      AtomExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a. AtomExprBase a -> RestrictionPredicateExprBase a
AtomExprPredicate (WithNameAssocs
-> AtomExprBase GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
substituteWithNameMacrosAtomExpr WithNameAssocs
macros AtomExprBase GraphRefTransactionMarker
atomExpr)
    AttributeEqualityPredicate RelVarName
attrName AtomExprBase GraphRefTransactionMarker
atomExpr ->
      RelVarName
-> AtomExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RelVarName -> AtomExprBase a -> RestrictionPredicateExprBase a
AttributeEqualityPredicate RelVarName
attrName (WithNameAssocs
-> AtomExprBase GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
substituteWithNameMacrosAtomExpr WithNameAssocs
macros AtomExprBase GraphRefTransactionMarker
atomExpr)

substituteWitNameMacrosExtendTupleExpr :: WithNameAssocs -> GraphRefExtendTupleExpr -> GraphRefExtendTupleExpr
substituteWitNameMacrosExtendTupleExpr :: WithNameAssocs
-> ExtendTupleExprBase GraphRefTransactionMarker
-> ExtendTupleExprBase GraphRefTransactionMarker
substituteWitNameMacrosExtendTupleExpr WithNameAssocs
macros (AttributeExtendTupleExpr RelVarName
attrName AtomExprBase GraphRefTransactionMarker
atomExpr) =
  RelVarName
-> AtomExprBase GraphRefTransactionMarker
-> ExtendTupleExprBase GraphRefTransactionMarker
forall a. RelVarName -> AtomExprBase a -> ExtendTupleExprBase a
AttributeExtendTupleExpr RelVarName
attrName (WithNameAssocs
-> AtomExprBase GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
substituteWithNameMacrosAtomExpr WithNameAssocs
macros AtomExprBase GraphRefTransactionMarker
atomExpr)

substituteWithNameMacrosAtomExpr :: WithNameAssocs -> GraphRefAtomExpr -> GraphRefAtomExpr
substituteWithNameMacrosAtomExpr :: WithNameAssocs
-> AtomExprBase GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
substituteWithNameMacrosAtomExpr WithNameAssocs
macros AtomExprBase GraphRefTransactionMarker
atomExpr =
  case AtomExprBase GraphRefTransactionMarker
atomExpr of
    e :: AtomExprBase GraphRefTransactionMarker
e@AttributeAtomExpr{} -> AtomExprBase GraphRefTransactionMarker
e
    e :: AtomExprBase GraphRefTransactionMarker
e@NakedAtomExpr{} -> AtomExprBase GraphRefTransactionMarker
e
    FunctionAtomExpr RelVarName
fname [AtomExprBase GraphRefTransactionMarker]
atomExprs GraphRefTransactionMarker
tid ->
      RelVarName
-> [AtomExprBase GraphRefTransactionMarker]
-> GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
forall a. RelVarName -> [AtomExprBase a] -> a -> AtomExprBase a
FunctionAtomExpr RelVarName
fname ((AtomExprBase GraphRefTransactionMarker
 -> AtomExprBase GraphRefTransactionMarker)
-> [AtomExprBase GraphRefTransactionMarker]
-> [AtomExprBase GraphRefTransactionMarker]
forall a b. (a -> b) -> [a] -> [b]
map (WithNameAssocs
-> AtomExprBase GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
substituteWithNameMacrosAtomExpr WithNameAssocs
macros) [AtomExprBase GraphRefTransactionMarker]
atomExprs) GraphRefTransactionMarker
tid
    RelationAtomExpr GraphRefRelationalExpr
reExpr ->
      GraphRefRelationalExpr -> AtomExprBase GraphRefTransactionMarker
forall a. RelationalExprBase a -> AtomExprBase a
RelationAtomExpr (WithNameAssocs -> GraphRefRelationalExpr -> GraphRefRelationalExpr
substituteWithNameMacros WithNameAssocs
macros GraphRefRelationalExpr
reExpr)
    ConstructedAtomExpr RelVarName
dconsName [AtomExprBase GraphRefTransactionMarker]
atomExprs GraphRefTransactionMarker
tid ->
      RelVarName
-> [AtomExprBase GraphRefTransactionMarker]
-> GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
forall a. RelVarName -> [AtomExprBase a] -> a -> AtomExprBase a
ConstructedAtomExpr RelVarName
dconsName ((AtomExprBase GraphRefTransactionMarker
 -> AtomExprBase GraphRefTransactionMarker)
-> [AtomExprBase GraphRefTransactionMarker]
-> [AtomExprBase GraphRefTransactionMarker]
forall a b. (a -> b) -> [a] -> [b]
map (WithNameAssocs
-> AtomExprBase GraphRefTransactionMarker
-> AtomExprBase GraphRefTransactionMarker
substituteWithNameMacrosAtomExpr WithNameAssocs
macros) [AtomExprBase GraphRefTransactionMarker]
atomExprs) GraphRefTransactionMarker
tid