@@ -49,6 +49,9 @@ module Constrained.Generation (
4949 EqW (.. ),
5050 SumSpec (.. ),
5151 pattern SumSpec ,
52+
53+ mapSpec ,
54+ forwardPropagateSpec ,
5255) where
5356
5457import Constrained.AbstractSyntax
@@ -907,10 +910,10 @@ backPropagation relevant (SolverPlan initplan) = SolverPlan (go [] (reverse init
907910 newStage _ _ = []
908911
909912 termVarEqCases :: HasSpec b => Specification a -> Var b -> Term b -> [SolverStage ]
910- termVarEqCases ( MemberSpec vs) x' t
911- | Set. singleton (Name x) == freeVarSet t =
912- [ SolverStage x' [] ( MemberSpec ( NE. nub ( fmap ( \ v -> errorGE $ runTerm ( Env. singleton x v) t) vs)))
913- ( Set. insert (Name x' ) relevant)]
913+ termVarEqCases specx x' t
914+ | Set. singleton (Name x) == freeVarSet t
915+ , Result ctx <- toCtx x t =
916+ [ SolverStage x' [] (forwardPropagateSpec specx ctx) ( Set. insert (Name x) relevant)]
914917 termVarEqCases specx x' t
915918 | Just Refl <- eqVar x x'
916919 , [Name y] <- Set. toList $ freeVarSet t
@@ -1329,3 +1332,34 @@ fromGESpec ge = case ge of
13291332 Result s -> s
13301333 GenError xs -> ErrorSpec (catMessageList xs)
13311334 FatalError es -> error $ catMessages es
1335+
1336+ -- TODO: move this somewhere sensible
1337+
1338+ -- | Functor like property for Specification, but instead of a Haskell function (a -> b),
1339+ -- it takes a function symbol (t '[a] b) from a to b.
1340+ -- Note, in this context, a function symbol is some constructor of a witnesstype.
1341+ -- Eg. ProdFstW, InjRightW, SingletonW, etc. NOT the lifted versions like fst_ singleton_,
1342+ -- which construct Terms. We had to wait until here to define this because it
1343+ -- depends on Semigroup property of Specification, and Asserting equality
1344+ mapSpec ::
1345+ forall t a b .
1346+ AppRequires t '[a ] b =>
1347+ t '[a ] b ->
1348+ Specification a ->
1349+ Specification b
1350+ mapSpec f (ExplainSpec es s) = explainSpec es (mapSpec f s)
1351+ mapSpec f TrueSpec = mapTypeSpec f (emptySpec @ a )
1352+ mapSpec _ (ErrorSpec err) = ErrorSpec err
1353+ mapSpec f (MemberSpec as) = MemberSpec $ NE. nub $ fmap (semantics f) as
1354+ mapSpec f (SuspendedSpec x p) =
1355+ constrained $ \ x' ->
1356+ Exists (\ _ -> fatalError " mapSpec" ) (x :-> fold [Assert $ (x' ==. appTerm f (V x)), p])
1357+ mapSpec f (TypeSpec ts cant) = mapTypeSpec f ts <> notMemberSpec (map (semantics f) cant)
1358+
1359+ -- TODO generalizeme!
1360+ forwardPropagateSpec :: HasSpec a => Specification a -> Ctx a b -> Specification b
1361+ forwardPropagateSpec s CtxHOLE = s
1362+ forwardPropagateSpec s (CtxApp f (c :? Nil ))
1363+ | Evidence <- ctxHasSpec c = mapSpec f (forwardPropagateSpec s c)
1364+ forwardPropagateSpec _ _ = TrueSpec
1365+
0 commit comments