packages feed

hermit 0.5.0.0 → 0.6.0.0

raw patch · 78 files changed

+3708/−2857 lines, 78 filesdep +Win32dep ~ghcdep ~kurePVP ok

version bump matches the API change (PVP)

Dependencies added: Win32

Dependency ranges changed: ghc, kure

API changes (from Hackage documentation)

- HERMIT.Core: endoFunExprType :: Monad m => CoreExpr -> m Type
- HERMIT.Core: endoFunType :: Monad m => Type -> m Type
- HERMIT.Core: funExprArgResTypes :: Monad m => CoreExpr -> m (Type, Type)
- HERMIT.Dictionary.Common: callsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => String -> Rewrite c m CoreExpr -> Rewrite c m Core
- HERMIT.Dictionary.Common: callsT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => String -> Transform c m CoreExpr b -> Transform c m Core [b]
- HERMIT.Dictionary.FixPoint: mkFixT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => CoreExpr -> Transform c m z CoreExpr
- HERMIT.Dictionary.Local: betaReducePlusR :: MonadCatch m => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseReduceIdR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Bool -> Rewrite c HermitM CoreExpr
- HERMIT.Dictionary.Reasoning: CoreExprEquality :: [CoreBndr] -> CoreExpr -> CoreExpr -> CoreExprEquality
- HERMIT.Dictionary.Reasoning: RewriteCoreExprEqualityBox :: (RewriteH CoreExprEquality) -> RewriteCoreExprEqualityBox
- HERMIT.Dictionary.Reasoning: TransformCoreExprEqualityStringBox :: (TransformH CoreExprEquality String) -> TransformCoreExprEqualityStringBox
- HERMIT.Dictionary.Reasoning: data CoreExprEquality
- HERMIT.Dictionary.Reasoning: data RewriteCoreExprEqualityBox
- HERMIT.Dictionary.Reasoning: data TransformCoreExprEqualityStringBox
- HERMIT.Dictionary.Reasoning: flipCoreExprEquality :: CoreExprEquality -> CoreExprEquality
- HERMIT.Dictionary.Reasoning: instance Extern (RewriteH CoreExprEquality)
- HERMIT.Dictionary.Reasoning: instance Extern (TransformH CoreExprEquality String)
- HERMIT.Dictionary.Reasoning: instance Typeable RewriteCoreExprEqualityBox
- HERMIT.Dictionary.Reasoning: instance Typeable TransformCoreExprEqualityStringBox
- HERMIT.Dictionary.Reasoning: ppCoreExprEqualityT :: PrettyPrinter -> TransformH CoreExprEquality DocH
- HERMIT.Dictionary.Reasoning: proveCoreExprEqualityT :: (AddBindings c, Monad m, ReadPath c Crumb) => CoreExprEqualityProof c m -> Transform c m CoreExprEquality ()
- HERMIT.Dictionary.Reasoning: type CoreExprEqualityProof c m = (Rewrite c m CoreExpr, Rewrite c m CoreExpr)
- HERMIT.Dictionary.Reasoning: verifyCoreExprEqualityT :: Monad m => Transform c m CoreExprEquality ()
- HERMIT.Dictionary.Rules: type RuleNameString = String
- HERMIT.Dictionary.Unfold: cleanupUnfoldR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.External: CoreBox :: CoreString -> CoreBox
- HERMIT.External: addToDictionary :: External -> Dictionary -> Dictionary
- HERMIT.External: data CoreBox
- HERMIT.External: instance Typeable CoreBox
- HERMIT.External: toDictionary :: [External] -> Dictionary
- HERMIT.External: type Dictionary = Map ExternalName [Dynamic]
- HERMIT.GHC: buildDictionary :: ModGuts -> Id -> CoreM (Id, [CoreBind])
- HERMIT.GHC: buildTypeable :: ModGuts -> Type -> CoreM (Id, [CoreBind])
- HERMIT.GHC: findNamesFromString :: GlobalRdrEnv -> String -> [Name]
- HERMIT.GHC: fqName :: Name -> String
- HERMIT.GHC: lookupRdrNameInModuleForPlugins :: HscEnv -> ModGuts -> ModuleName -> RdrName -> IO (Maybe Name)
- HERMIT.GHC: mkPhiTy :: [PredType] -> Type -> Type
- HERMIT.GHC: mkSigmaTy :: [TyVar] -> [PredType] -> Type -> Type
- HERMIT.GHC: occurAnalyseExpr :: CoreExpr -> CoreExpr
- HERMIT.GHC: runDsMtoCoreM :: ModGuts -> DsM a -> CoreM a
- HERMIT.GHC: runTcMtoCoreM :: ModGuts -> TcM a -> CoreM a
- HERMIT.GHC: uqName :: NamedThing nm => nm -> String
- HERMIT.GHC: var2String :: Var -> String
- HERMIT.Monad: class HasModGuts m
- HERMIT.Monad: cloneVarH :: (String -> String) -> Var -> HermitM Var
- HERMIT.Monad: hs_debugChan :: HermitMEnv -> DebugMessage -> HermitM ()
- HERMIT.Monad: instance HasModGuts HermitM
- HERMIT.Monad: mkHermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv
- HERMIT.Monad: newCoVarH :: String -> Type -> HermitM TyVar
- HERMIT.Monad: newGlobalIdH :: String -> Type -> HermitM Id
- HERMIT.Monad: newIdH :: String -> Type -> HermitM Id
- HERMIT.Monad: newTyVarH :: String -> Kind -> HermitM TyVar
- HERMIT.Monad: newVarH :: String -> KindOrType -> HermitM Var
- HERMIT.Monad: newtype HermitMEnv
- HERMIT.Monad: type Label = String
- HERMIT.Plugin: allPhases :: HPM () -> HPM ()
- HERMIT.Plugin: firstPhase :: HPM () -> HPM ()
- HERMIT.Plugin: getPhaseInfo :: HPM PhaseInfo
- HERMIT.Plugin: lastPhase :: HPM () -> HPM ()
- HERMIT.Plugin: phase :: Int -> HPM () -> HPM ()
- HERMIT.Plugin.Builder: PhaseInfo :: Int -> [CorePass] -> [CorePass] -> PhaseInfo
- HERMIT.Plugin.Builder: data PhaseInfo
- HERMIT.Plugin.Builder: getPhaseFlag :: [CommandLineOption] -> Maybe (Int, [CommandLineOption])
- HERMIT.Plugin.Builder: instance Eq PhaseInfo
- HERMIT.Plugin.Builder: instance Read PhaseInfo
- HERMIT.Plugin.Builder: instance Show PhaseInfo
- HERMIT.Plugin.Builder: phaseNum :: PhaseInfo -> Int
- HERMIT.Plugin.Builder: phasesDone :: PhaseInfo -> [CorePass]
- HERMIT.Plugin.Builder: phasesLeft :: PhaseInfo -> [CorePass]
- HERMIT.Plugin.Types: ps_phase :: PluginState -> PhaseInfo
- HERMIT.Shell.Dictionary: mkDict :: [External] -> Dictionary
- HERMIT.Shell.Externals: KernelEffect :: KernelEffect -> ShellCommand
- HERMIT.Shell.Externals: ProofCommand :: ProofCommand -> ShellCommand
- HERMIT.Shell.Externals: QueryFun :: QueryFun -> ShellCommand
- HERMIT.Shell.Externals: ScriptEffect :: ScriptEffect -> ShellCommand
- HERMIT.Shell.Externals: ShellEffect :: ShellEffect -> ShellCommand
- HERMIT.Shell.Externals: data ShellCommand
- HERMIT.Shell.Externals: interpShellCommand :: [Interp ShellCommand]
- HERMIT.Shell.Interpreter: instance Functor Interp
- HERMIT.Shell.KernelEffect: Apply :: RewriteH g -> KernelEffect
- HERMIT.Shell.KernelEffect: Pathfinder :: TransformH g LocalPathH -> KernelEffect
- HERMIT.Shell.Proof: ModifyLemma :: LemmaName -> (String -> String) -> (RewriteH CoreExprEquality) -> (Bool -> Bool) -> ProofCommand
- HERMIT.Shell.Proof: QueryLemma :: LemmaName -> (TransformH CoreExprEquality String) -> ProofCommand
- HERMIT.Shell.Proof: RuleToLemma :: RuleNameString -> ProofCommand
- HERMIT.Shell.Types: AmbiguousC :: [CompletionType] -> CompletionType
- HERMIT.Shell.Types: BindingGroupOfC :: CompletionType
- HERMIT.Shell.Types: BindingOfC :: CompletionType
- HERMIT.Shell.Types: CommandC :: CompletionType
- HERMIT.Shell.Types: ConsiderC :: CompletionType
- HERMIT.Shell.Types: InlineC :: CompletionType
- HERMIT.Shell.Types: OccurrenceOfC :: CompletionType
- HERMIT.Shell.Types: RhsOfC :: CompletionType
- HERMIT.Shell.Types: cl_lemmas :: CommandLineState -> [Lemma]
- HERMIT.Shell.Types: completionQuery :: CommandLineState -> CompletionType -> IO (TransformH CoreTC [String])
- HERMIT.Shell.Types: completionType :: String -> CompletionType
- HERMIT.Shell.Types: data CompletionType
- HERMIT.Shell.Types: instance Show CompletionType
- HERMIT.Shell.Types: shellComplete :: MVar CommandLineState -> String -> String -> IO [Completion]
- HERMIT.Shell.Types: type Lemma = (LemmaName, CoreExprEquality, Bool)
- HERMIT.Shell.Types: type LemmaName = String
+ HERMIT.Core: endoFunExprTypeM :: MonadCatch m => CoreExpr -> m ([TyVar], Type)
+ HERMIT.Core: endoFunTypeM :: MonadCatch m => Type -> m ([TyVar], Type)
+ HERMIT.Core: funExprArgResTypesM :: MonadCatch m => CoreExpr -> m ([TyVar], Type, Type)
+ HERMIT.Dictionary.Composite: smashExtendedWithR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => [Rewrite c m Core] -> Rewrite c m Core
+ HERMIT.Dictionary.Composite: smashR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m Core
+ HERMIT.Dictionary.Composite: smashUsingR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => [Rewrite c m Core] -> [Rewrite c m Core] -> Rewrite c m Core
+ HERMIT.Dictionary.FixPoint: fixIntroNonRecR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => Rewrite c m CoreBind
+ HERMIT.Dictionary.FixPoint: fixIntroRecR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => Rewrite c m CoreDef
+ HERMIT.Dictionary.Function: appArgM :: Monad m => Int -> CoreExpr -> m CoreExpr
+ HERMIT.Dictionary.Function: buildApplicationM :: (HasDynFlags m, MonadCatch m, MonadIO m) => CoreExpr -> CoreExpr -> m CoreExpr
+ HERMIT.Dictionary.Function: buildCompositionT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => CoreExpr -> CoreExpr -> Transform c m x CoreExpr
+ HERMIT.Dictionary.Function: buildFixT :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => CoreExpr -> Transform c m x CoreExpr
+ HERMIT.Dictionary.Function: buildIdT :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => Type -> Transform c m x CoreExpr
+ HERMIT.Dictionary.GHC: buildDictionary :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => Id -> m (Id, [CoreBind])
+ HERMIT.Dictionary.GHC: buildDictionaryT :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadUnique m) => Transform c m Type CoreExpr
+ HERMIT.Dictionary.GHC: buildTypeable :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => Type -> m (Id, [CoreBind])
+ HERMIT.Dictionary.Kure: betweenR :: MonadCatch m => Int -> Int -> Rewrite c m a -> Rewrite c m a
+ HERMIT.Dictionary.Local.Case: caseFloatArgLemmaR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, HasHermitMEnv m, HasHscEnv m, HasDynFlags m, HasLemmas m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => LemmaName -> Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatCaseAltR :: MonadCatch m => Maybe Int -> Rewrite c m CoreExpr
+ HERMIT.Dictionary.Navigation: instance Extern Considerable
+ HERMIT.Dictionary.Navigation: instance Typeable Considerable
+ HERMIT.Dictionary.Navigation: string2considerable :: String -> Maybe Considerable
+ HERMIT.Dictionary.Reasoning: flipEquality :: Equality -> Equality
+ HERMIT.Dictionary.Reasoning: getLemmaByNameT :: (HasLemmas m, Monad m) => LemmaName -> Transform c m x Lemma
+ HERMIT.Dictionary.Reasoning: getLemmasT :: HasLemmas m => Transform c m x Lemmas
+ HERMIT.Dictionary.Reasoning: insertLemmaR :: (HasLemmas m, Monad m) => LemmaName -> Lemma -> Rewrite c m a
+ HERMIT.Dictionary.Reasoning: lemmaR :: LemmaName -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.Reasoning: markLemmaUsedR :: (HasLemmas m, Monad m) => LemmaName -> Rewrite c m a
+ HERMIT.Dictionary.Reasoning: modifyLemmaR :: (HasLemmas m, Monad m) => LemmaName -> (LemmaName -> LemmaName) -> Rewrite c m Equality -> (Bool -> Bool) -> (Bool -> Bool) -> Rewrite c m a
+ HERMIT.Dictionary.Reasoning: ppEqualityT :: PrettyPrinter -> TransformH Equality DocH
+ HERMIT.Dictionary.Reasoning: proveEqualityT :: (AddBindings c, Monad m, ReadPath c Crumb) => EqualityProof c m -> Transform c m Equality ()
+ HERMIT.Dictionary.Reasoning: type EqualityProof c m = (Rewrite c m CoreExpr, Rewrite c m CoreExpr)
+ HERMIT.Dictionary.Reasoning: verifyEqualityT :: Monad m => Transform c m Equality ()
+ HERMIT.Dictionary.Rules: RuleName :: String -> RuleName
+ HERMIT.Dictionary.Rules: RuleNameListBox :: [RuleName] -> RuleNameListBox
+ HERMIT.Dictionary.Rules: instance Eq RuleName
+ HERMIT.Dictionary.Rules: instance Extern RuleName
+ HERMIT.Dictionary.Rules: instance Extern [RuleName]
+ HERMIT.Dictionary.Rules: instance IsString RuleName
+ HERMIT.Dictionary.Rules: instance Show RuleName
+ HERMIT.Dictionary.Rules: instance Typeable RuleName
+ HERMIT.Dictionary.Rules: instance Typeable RuleNameListBox
+ HERMIT.Dictionary.Rules: newtype RuleName
+ HERMIT.Dictionary.Rules: newtype RuleNameListBox
+ HERMIT.Dictionary.Rules: specialiseR :: RewriteH ModGuts
+ HERMIT.Dictionary.Undefined: buildStrictnessLemmaT :: (BoundVars c, HasDynFlags m, HasHscEnv m, HasHermitMEnv m, HasLemmas m, MonadCatch m, MonadIO m, MonadThings m) => LemmaName -> CoreExpr -> Transform c m x ()
+ HERMIT.Dictionary.Unfold: betaReducePlusR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Common: assumptionAEqualityT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => CoreExpr -> CoreExpr -> Transform c m x Equality
+ HERMIT.Dictionary.WorkerWrapper.Common: assumptionBEqualityT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => CoreExpr -> CoreExpr -> CoreExpr -> Transform c m x Equality
+ HERMIT.Dictionary.WorkerWrapper.Common: assumptionCEqualityT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => CoreExpr -> CoreExpr -> CoreExpr -> Transform c m x Equality
+ HERMIT.Dictionary.WorkerWrapper.Common: externals :: [External]
+ HERMIT.Dictionary.WorkerWrapper.Common: instance Extern WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: instance Typeable WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: split1BetaR :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, HasLemmas m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => LemmaName -> CoreExpr -> CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Common: split2BetaR :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, HasLemmas m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => LemmaName -> CoreExpr -> CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Driver: usageOutput :: String
+ HERMIT.External: RewriteEqualityBox :: (RewriteH Equality) -> RewriteEqualityBox
+ HERMIT.External: Strictness :: CmdTag
+ HERMIT.External: TransformEqualityStringBox :: (TransformH Equality String) -> TransformEqualityStringBox
+ HERMIT.External: data RewriteEqualityBox
+ HERMIT.External: data TransformEqualityStringBox
+ HERMIT.External: instance Extern (RewriteH Equality)
+ HERMIT.External: instance Extern (TransformH Equality String)
+ HERMIT.External: instance Extern LemmaName
+ HERMIT.External: instance Extern RememberedName
+ HERMIT.External: instance Typeable CoreString
+ HERMIT.External: instance Typeable RewriteEqualityBox
+ HERMIT.External: instance Typeable TransformEqualityStringBox
+ HERMIT.External: splitFunTyArgs :: TypeRep -> ([TypeRep], TypeRep)
+ HERMIT.GHC: foldBag :: (r -> r -> r) -> (a -> r) -> r -> Bag a -> r
+ HERMIT.GHC: loadSysInterface :: SDoc -> Module -> IfM lcl ModIface
+ HERMIT.GHC: lookupRdrNameInModule :: HscEnv -> ModGuts -> ModuleName -> RdrName -> IO (Maybe Name)
+ HERMIT.GHC: occurAnalyseExpr_NoBinderSwap :: CoreExpr -> CoreExpr
+ HERMIT.GHC: qualifiedName :: Name -> String
+ HERMIT.GHC: reportAllUnsolved :: WantedConstraints -> TcM ()
+ HERMIT.GHC: unqualifiedName :: NamedThing nm => nm -> String
+ HERMIT.GHC: zEncodeString :: UserString -> EncodedString
+ HERMIT.Kernel: KernelEnv :: (DebugMessage -> HermitM ()) -> KernelEnv
+ HERMIT.Kernel: data KernelEnv
+ HERMIT.Kernel: kEnvChan :: KernelEnv -> DebugMessage -> HermitM ()
+ HERMIT.Kure: instance HasDynFlags m => HasDynFlags (Transform c m a)
+ HERMIT.Monad: Equality :: [CoreBndr] -> CoreExpr -> CoreExpr -> Equality
+ HERMIT.Monad: HermitMResult :: DefStash -> Lemmas -> a -> HermitMResult a
+ HERMIT.Monad: Lemma :: Equality -> Bool -> Bool -> Lemma
+ HERMIT.Monad: LemmaName :: String -> LemmaName
+ HERMIT.Monad: RememberedName :: String -> RememberedName
+ HERMIT.Monad: addLemma :: (HasLemmas m, Monad m) => LemmaName -> Lemma -> m ()
+ HERMIT.Monad: class HasDebugChan m
+ HERMIT.Monad: class HasLemmas m
+ HERMIT.Monad: class HasStash m
+ HERMIT.Monad: class Monad m => LiftCoreM m
+ HERMIT.Monad: data Equality
+ HERMIT.Monad: data HermitMEnv
+ HERMIT.Monad: data HermitMResult a
+ HERMIT.Monad: data Lemma
+ HERMIT.Monad: embedHermitM :: (HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m) => HermitM a -> m a
+ HERMIT.Monad: getDebugChan :: HasDebugChan m => m (DebugMessage -> m ())
+ HERMIT.Monad: getLemmas :: HasLemmas m => m Lemmas
+ HERMIT.Monad: hEnvLemmas :: HermitMEnv -> Lemmas
+ HERMIT.Monad: hEnvModGuts :: HermitMEnv -> ModGuts
+ HERMIT.Monad: hEnvStash :: HermitMEnv -> DefStash
+ HERMIT.Monad: hResLemmas :: HermitMResult a -> Lemmas
+ HERMIT.Monad: hResStash :: HermitMResult a -> DefStash
+ HERMIT.Monad: hResult :: HermitMResult a -> a
+ HERMIT.Monad: insertLemma :: HasLemmas m => LemmaName -> Lemma -> m ()
+ HERMIT.Monad: instance Eq LemmaName
+ HERMIT.Monad: instance Eq RememberedName
+ HERMIT.Monad: instance HasDebugChan HermitM
+ HERMIT.Monad: instance HasLemmas HermitM
+ HERMIT.Monad: instance HasStash HermitM
+ HERMIT.Monad: instance IsString LemmaName
+ HERMIT.Monad: instance IsString RememberedName
+ HERMIT.Monad: instance LiftCoreM HermitM
+ HERMIT.Monad: instance Ord LemmaName
+ HERMIT.Monad: instance Ord RememberedName
+ HERMIT.Monad: instance Show LemmaName
+ HERMIT.Monad: instance Show RememberedName
+ HERMIT.Monad: instance Typeable LemmaName
+ HERMIT.Monad: instance Typeable RememberedName
+ HERMIT.Monad: lemmaEq :: Lemma -> Equality
+ HERMIT.Monad: lemmaP :: Lemma -> Bool
+ HERMIT.Monad: lemmaU :: Lemma -> Bool
+ HERMIT.Monad: mkEnv :: ModGuts -> DefStash -> Lemmas -> HermitMEnv
+ HERMIT.Monad: newtype LemmaName
+ HERMIT.Monad: newtype RememberedName
+ HERMIT.Monad: putStash :: HasStash m => DefStash -> m ()
+ HERMIT.Monad: runDsM :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => DsM a -> m a
+ HERMIT.Monad: runTcM :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => TcM a -> m a
+ HERMIT.Monad: type Lemmas = Map LemmaName Lemma
+ HERMIT.Name: BindingName :: HermitName -> BindingName
+ HERMIT.Name: OccurrenceName :: HermitName -> OccurrenceName
+ HERMIT.Name: OccurrenceNameListBox :: [OccurrenceName] -> OccurrenceNameListBox
+ HERMIT.Name: RhsOfName :: HermitName -> RhsOfName
+ HERMIT.Name: cloneVarH :: MonadUnique m => (String -> String) -> Var -> m Var
+ HERMIT.Name: cmpHN2Name :: HermitName -> Name -> Bool
+ HERMIT.Name: cmpHN2Var :: HermitName -> Var -> Bool
+ HERMIT.Name: instance Eq HermitName
+ HERMIT.Name: instance Extern BindingName
+ HERMIT.Name: instance Extern HermitName
+ HERMIT.Name: instance Extern OccurrenceName
+ HERMIT.Name: instance Extern RhsOfName
+ HERMIT.Name: instance Extern [OccurrenceName]
+ HERMIT.Name: instance IsString HermitName
+ HERMIT.Name: instance Show HermitName
+ HERMIT.Name: instance Typeable BindingName
+ HERMIT.Name: instance Typeable HermitName
+ HERMIT.Name: instance Typeable OccurrenceName
+ HERMIT.Name: instance Typeable OccurrenceNameListBox
+ HERMIT.Name: instance Typeable RhsOfName
+ HERMIT.Name: mkBindingPred :: BindingName -> Var -> Bool
+ HERMIT.Name: mkOccPred :: OccurrenceName -> Var -> Bool
+ HERMIT.Name: mkRhsOfPred :: RhsOfName -> Var -> Bool
+ HERMIT.Name: newCoVarH :: MonadUnique m => String -> Type -> m TyVar
+ HERMIT.Name: newGlobalIdH :: MonadUnique m => String -> Type -> m Id
+ HERMIT.Name: newIdH :: MonadUnique m => String -> Type -> m Id
+ HERMIT.Name: newTyVarH :: MonadUnique m => String -> Kind -> m TyVar
+ HERMIT.Name: newVarH :: MonadUnique m => String -> KindOrType -> m Var
+ HERMIT.Name: newtype BindingName
+ HERMIT.Name: newtype OccurrenceName
+ HERMIT.Name: newtype OccurrenceNameListBox
+ HERMIT.Name: newtype RhsOfName
+ HERMIT.Name: showName :: HermitName -> String
+ HERMIT.Name: unBindingName :: BindingName -> HermitName
+ HERMIT.Name: unOccurrenceName :: OccurrenceName -> HermitName
+ HERMIT.Name: unRhsOfName :: RhsOfName -> HermitName
+ HERMIT.Parser: parseExprH :: String -> Either String ExprH
+ HERMIT.ParserCore: parse2BeforeT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m) => (CoreExpr -> CoreExpr -> Translate c m a b) -> CoreString -> CoreString -> Translate c m a b
+ HERMIT.ParserCore: parse3BeforeT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m) => (CoreExpr -> CoreExpr -> CoreExpr -> Translate c m a b) -> CoreString -> CoreString -> CoreString -> Translate c m a b
+ HERMIT.Plugin: allPasses :: HPM () -> HPM ()
+ HERMIT.Plugin: firstPass :: HPM () -> HPM ()
+ HERMIT.Plugin: getPassInfo :: HPM PassInfo
+ HERMIT.Plugin: lastPass :: HPM () -> HPM ()
+ HERMIT.Plugin: pass :: Int -> HPM () -> HPM ()
+ HERMIT.Plugin.Builder: PassInfo :: Int -> [CorePass] -> [CorePass] -> PassInfo
+ HERMIT.Plugin.Builder: data PassInfo
+ HERMIT.Plugin.Builder: getPassFlag :: [CommandLineOption] -> Maybe (Int, [CommandLineOption])
+ HERMIT.Plugin.Builder: instance Eq PassInfo
+ HERMIT.Plugin.Builder: instance Read PassInfo
+ HERMIT.Plugin.Builder: instance Show PassInfo
+ HERMIT.Plugin.Builder: passNum :: PassInfo -> Int
+ HERMIT.Plugin.Builder: passesDone :: PassInfo -> [CorePass]
+ HERMIT.Plugin.Builder: passesLeft :: PassInfo -> [CorePass]
+ HERMIT.Plugin.Types: ps_pass :: PluginState -> PassInfo
+ HERMIT.PrettyPrinter.Clean: instance Eq ArrowType
+ HERMIT.PrettyPrinter.Clean: instance Show ArrowType
+ HERMIT.PrettyPrinter.Common: pad :: MDoc a -> MDoc a
+ HERMIT.PrettyPrinter.Common: po_showUniques :: PrettyOptions -> Bool
+ HERMIT.Shell.Command: interpShellCommand :: (MonadCatch m, MonadException m, CLMonad m) => [Interp m ()]
+ HERMIT.Shell.Completion: shellComplete :: (MonadCatch m, MonadIO m, MonadState CommandLineState m) => String -> String -> m [Completion]
+ HERMIT.Shell.Dictionary: addToDictionary :: External -> Dictionary -> Dictionary
+ HERMIT.Shell.Dictionary: mkDictionary :: [External] -> Dictionary
+ HERMIT.Shell.Interpreter: exprToDyns :: MonadState CommandLineState m => ExprH -> m [Dynamic]
+ HERMIT.Shell.Interpreter: instance Monad m => Functor (Interp m)
+ HERMIT.Shell.Interpreter: interpEM :: (CLMonad m, Typeable b) => (b -> ExprH -> m a) -> Interp m a
+ HERMIT.Shell.Interpreter: interpM :: (CLMonad m, Typeable b) => (b -> m a) -> Interp m a
+ HERMIT.Shell.KernelEffect: applyRewrite :: (Injection ModGuts g, Walker HermitC g, MonadCatch m, CLMonad m) => RewriteH g -> ExprH -> m ()
+ HERMIT.Shell.KernelEffect: beginScope :: (MonadCatch m, CLMonad m) => ExprH -> m ()
+ HERMIT.Shell.KernelEffect: deleteSAST :: (MonadCatch m, CLMonad m) => SAST -> m ()
+ HERMIT.Shell.KernelEffect: endScope :: (MonadCatch m, CLMonad m) => ExprH -> m ()
+ HERMIT.Shell.KernelEffect: goDirection :: (MonadCatch m, CLMonad m) => Direction -> ExprH -> m ()
+ HERMIT.Shell.KernelEffect: setPath :: (Injection ModGuts g, Walker HermitC g, MonadCatch m, CLMonad m) => TransformH g LocalPathH -> ExprH -> m ()
+ HERMIT.Shell.Types: instance MonadException m => MonadException (CLT m)
+ HERMIT.Shell.Types: instance MonadException m => MonadException (StateT s m)
+ HERMIT.Shell.Types: type CLMonad m = (MonadIO m, MonadState CommandLineState m, MonadError CLException m)
- HERMIT.Context: findBoundVars :: BoundVars c => String -> c -> VarSet
+ HERMIT.Context: findBoundVars :: BoundVars c => (Var -> Bool) -> c -> VarSet
- HERMIT.Core: splitFunTypeM :: Monad m => Type -> m (Type, Type)
+ HERMIT.Core: splitFunTypeM :: MonadCatch m => Type -> m ([TyVar], Type, Type)
- HERMIT.Dictionary.AlphaConversion: alphaAltR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: alphaAltR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreAlt
- HERMIT.Dictionary.AlphaConversion: alphaAltVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: alphaAltVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => [Var] -> Rewrite c m CoreAlt
- HERMIT.Dictionary.AlphaConversion: alphaAltWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [String] -> Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: alphaAltWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => [String] -> Rewrite c m CoreAlt
- HERMIT.Dictionary.AlphaConversion: alphaCaseBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaCaseBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Maybe String -> Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: alphaCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: alphaLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Maybe String -> Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: alphaLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: alphaLetVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLetVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => [Var] -> Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: alphaLetWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [String] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLetWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => [String] -> Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: alphaProgConsIdsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [Id] -> Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.AlphaConversion: alphaProgConsIdsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => [Id] -> Rewrite c m CoreProg
- HERMIT.Dictionary.AlphaConversion: alphaProgConsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.AlphaConversion: alphaProgConsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreProg
- HERMIT.Dictionary.AlphaConversion: alphaProgConsWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [String] -> Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.AlphaConversion: alphaProgConsWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => [String] -> Rewrite c m CoreProg
- HERMIT.Dictionary.AlphaConversion: alphaProgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.AlphaConversion: alphaProgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreProg
- HERMIT.Dictionary.AlphaConversion: alphaR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.AlphaConversion: alphaR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m Core
- HERMIT.Dictionary.AlphaConversion: cloneVarAvoidingT :: BoundVars c => Var -> Maybe String -> [Var] -> Transform c HermitM CoreTC Var
+ HERMIT.Dictionary.AlphaConversion: cloneVarAvoidingT :: (BoundVars c, MonadUnique m) => Var -> Maybe String -> [Var] -> Transform c m CoreTC Var
- HERMIT.Dictionary.AlphaConversion: unshadowAltR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: unshadowAltR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreAlt
- HERMIT.Dictionary.AlphaConversion: unshadowExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: unshadowExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.AlphaConversion: unshadowProgR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.AlphaConversion: unshadowProgR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreProg
- HERMIT.Dictionary.AlphaConversion: unshadowR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb) => Rewrite c HermitM Core
+ HERMIT.Dictionary.AlphaConversion: unshadowR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m Core
- HERMIT.Dictionary.Common: callNameG :: MonadCatch m => String -> Transform c m CoreExpr ()
+ HERMIT.Dictionary.Common: callNameG :: MonadCatch m => HermitName -> Transform c m CoreExpr ()
- HERMIT.Dictionary.Common: callNameT :: MonadCatch m => String -> Transform c m CoreExpr (CoreExpr, [CoreExpr])
+ HERMIT.Dictionary.Common: callNameT :: MonadCatch m => HermitName -> Transform c m CoreExpr (CoreExpr, [CoreExpr])
- HERMIT.Dictionary.Common: findBoundVarT :: (BoundVars c, MonadCatch m) => String -> Transform c m a Var
+ HERMIT.Dictionary.Common: findBoundVarT :: (BoundVars c, MonadCatch m) => (Var -> Bool) -> Transform c m a Var
- HERMIT.Dictionary.Common: findIdT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a Id
+ HERMIT.Dictionary.Common: findIdT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> Transform c m a Id
- HERMIT.Dictionary.Common: findTyConT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a TyCon
+ HERMIT.Dictionary.Common: findTyConT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> Transform c m a TyCon
- HERMIT.Dictionary.Common: findTypeT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a Type
+ HERMIT.Dictionary.Common: findTypeT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> Transform c m a Type
- HERMIT.Dictionary.Common: findVarT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a Var
+ HERMIT.Dictionary.Common: findVarT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> Transform c m a Var
- HERMIT.Dictionary.Composite: bashDebugR :: RewriteH Core
+ HERMIT.Dictionary.Composite: bashDebugR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, HasDebugChan m, HasDynFlags m, MonadCatch m, MonadUnique m) => Rewrite c m Core
- HERMIT.Dictionary.Composite: bashExtendedWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [Rewrite c HermitM Core] -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Composite: bashExtendedWithR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => [Rewrite c m Core] -> Rewrite c m Core
- HERMIT.Dictionary.Composite: bashR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.Composite: bashR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m Core
- HERMIT.Dictionary.Composite: bashUsingR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core
+ HERMIT.Dictionary.Composite: bashUsingR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core
- HERMIT.Dictionary.Composite: simplifyR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.Composite: simplifyR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m Core
- HERMIT.Dictionary.Composite: unfoldBasicCombinatorR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Composite: unfoldBasicCombinatorR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Debug: bracketR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a
+ HERMIT.Dictionary.Debug: bracketR :: (Injection a CoreTC, ReadBindings c, ReadPath c Crumb, HasDebugChan m, MonadCatch m) => String -> Rewrite c m a -> Rewrite c m a
- HERMIT.Dictionary.Debug: observeFailureR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a
+ HERMIT.Dictionary.Debug: observeFailureR :: (Injection a CoreTC, ReadBindings c, ReadPath c Crumb, HasDebugChan m, MonadCatch m) => String -> Rewrite c m a -> Rewrite c m a
- HERMIT.Dictionary.Debug: observeR :: Injection a CoreTC => String -> RewriteH a
+ HERMIT.Dictionary.Debug: observeR :: (Injection a CoreTC, ReadBindings c, ReadPath c Crumb, HasDebugChan m, Monad m) => String -> Rewrite c m a
- HERMIT.Dictionary.Debug: traceR :: String -> RewriteH a
+ HERMIT.Dictionary.Debug: traceR :: (HasDebugChan m, Monad m) => String -> Rewrite c m a
- HERMIT.Dictionary.FixPoint: fixFusionRuleBR :: Maybe (CoreExprEqualityProof HermitC HermitM) -> Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.FixPoint: fixFusionRuleBR :: Maybe (EqualityProof HermitC HermitM) -> Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
- HERMIT.Dictionary.FixPoint: fixIntroR :: RewriteH CoreDef
+ HERMIT.Dictionary.FixPoint: fixIntroR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => Rewrite c m Core
- HERMIT.Dictionary.Fold: foldR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: foldR :: (ReadBindings c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => HermitName -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Fold: foldVarR :: ReadBindings c => Var -> Maybe BindingDepth -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: foldVarR :: (ReadBindings c, MonadCatch m, MonadUnique m) => Maybe BindingDepth -> Var -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Fold: stashFoldAnyR :: ReadBindings c => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: stashFoldAnyR :: (ReadBindings c, HasStash m, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Fold: stashFoldR :: ReadBindings c => Label -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: stashFoldR :: (ReadBindings c, HasStash m, MonadCatch m) => RememberedName -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Function: staticArgPosR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => [Int] -> Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgPosR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => [Int] -> Rewrite c m CoreDef
- HERMIT.Dictionary.Function: staticArgPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => ([(Int, Var)] -> HermitM [Int]) -> Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgPredR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => ([(Int, Var)] -> m [Int]) -> Rewrite c m CoreDef
- HERMIT.Dictionary.Function: staticArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreDef
- HERMIT.Dictionary.Function: staticArgTypesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgTypesR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreDef
- HERMIT.Dictionary.Inline: configurableInlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => InlineConfig -> (Transform c HermitM Id Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: configurableInlineR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => InlineConfig -> (Transform c m Id Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: getUnfoldingT :: ReadBindings c => InlineConfig -> Transform c HermitM Id (CoreExpr, BindingDepth -> Bool)
+ HERMIT.Dictionary.Inline: getUnfoldingT :: (ReadBindings c, MonadCatch m) => InlineConfig -> Transform c m Id (CoreExpr, BindingDepth -> Bool)
- HERMIT.Dictionary.Inline: inlineCaseAlternativeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineCaseAlternativeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: inlineCaseScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineCaseScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: inlineMatchingPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => (Id -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineMatchingPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => (Id -> Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: inlineNameR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineNameR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => String -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: inlineNamesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [String] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineNamesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => [String] -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: inlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Inline: inlineTargetsT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Transform c HermitM Core [String]
+ HERMIT.Dictionary.Inline: inlineTargetsT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => Transform c m Core [String]
- HERMIT.Dictionary.Local: abstractR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local: abstractR :: (ReadBindings c, MonadCatch m, MonadUnique m) => (Var -> Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseElimInlineScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimInlineScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseElimMergeAltsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimMergeAltsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseElimR :: Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimR :: MonadCatch m => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseElimSeqR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimSeqR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe CoreExpr -> Maybe (Rewrite c HermitM CoreExpr) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => Maybe CoreExpr -> Maybe (Rewrite c m CoreExpr) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseFloatR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseInlineAlternativeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseInlineAlternativeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseInlineScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseInlineScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseIntroSeqR :: (Id -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseIntroSeqR :: (MonadCatch m, MonadUnique m) => (Id -> Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseMergeAltsWithBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseMergeAltsWithBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseReduceDataconR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Bool -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceDataconR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Bool -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseReduceR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Bool -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Bool -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseReduceUnfoldR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Bool -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceUnfoldR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => Bool -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseSplitInlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => (Id -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseSplitInlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m) => (Id -> Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Case: caseSplitR :: (Id -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseSplitR :: (MonadCatch m, MonadUnique m) => (Id -> Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatExprR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatExprR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatInAppR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatInAppR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatInCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatInCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatInR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatInR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letFloatTopR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.Local.Let: letFloatTopR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m) => Rewrite c m CoreProg
- HERMIT.Dictionary.Local.Let: letIntroR :: String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letIntroR :: (MonadCatch m, MonadUnique m) => String -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letIntroUnfoldingR :: (BoundVars c, ReadBindings c) => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letIntroUnfoldingR :: (BoundVars c, ReadBindings c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => HermitName -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letNonRecIntroR :: String -> CoreExpr -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letNonRecIntroR :: (MonadCatch m, MonadUnique m) => String -> CoreExpr -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letToCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letToCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: letTupleR :: String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letTupleR :: (MonadCatch m, MonadUnique m) => String -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Local.Let: nonRecIntroR :: String -> CoreExpr -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Local.Let: nonRecIntroR :: (MonadCatch m, MonadUnique m) => String -> CoreExpr -> Rewrite c m Core
- HERMIT.Dictionary.Local.Let: progNonRecIntroR :: String -> CoreExpr -> Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.Local.Let: progNonRecIntroR :: (MonadCatch m, MonadUnique m) => String -> CoreExpr -> Rewrite c m CoreProg
- HERMIT.Dictionary.Reasoning: alphaEqualityR :: (Var -> Bool) -> (String -> String) -> RewriteH CoreExprEquality
+ HERMIT.Dictionary.Reasoning: alphaEqualityR :: (Var -> Bool) -> (String -> String) -> RewriteH Equality
- HERMIT.Dictionary.Reasoning: birewrite :: (AddBindings c, ReadBindings c, ExtendPath c Crumb, ReadPath c Crumb, HasEmptyContext c) => CoreExprEquality -> BiRewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Reasoning: birewrite :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m, MonadUnique m) => Equality -> BiRewrite c m CoreExpr
- HERMIT.Dictionary.Reasoning: bothR :: (AddBindings c, MonadCatch m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m CoreExprEquality
+ HERMIT.Dictionary.Reasoning: bothR :: (AddBindings c, MonadCatch m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m Equality
- HERMIT.Dictionary.Reasoning: bothT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m CoreExprEquality (b, b)
+ HERMIT.Dictionary.Reasoning: bothT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m Equality (b, b)
- HERMIT.Dictionary.Reasoning: discardUniVars :: CoreExprEquality -> CoreExprEquality
+ HERMIT.Dictionary.Reasoning: discardUniVars :: Equality -> Equality
- HERMIT.Dictionary.Reasoning: eqLhsIntroR :: CoreExprEquality -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Reasoning: eqLhsIntroR :: Equality -> Rewrite c HermitM Core
- HERMIT.Dictionary.Reasoning: eqRhsIntroR :: CoreExprEquality -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Reasoning: eqRhsIntroR :: Equality -> Rewrite c HermitM Core
- HERMIT.Dictionary.Reasoning: extensionalityR :: Maybe String -> Rewrite c HermitM CoreExprEquality
+ HERMIT.Dictionary.Reasoning: extensionalityR :: Maybe String -> Rewrite c HermitM Equality
- HERMIT.Dictionary.Reasoning: forallVarsT :: Monad m => Transform c m [Var] b -> Transform c m CoreExprEquality b
+ HERMIT.Dictionary.Reasoning: forallVarsT :: Monad m => Transform c m [Var] b -> Transform c m Equality b
- HERMIT.Dictionary.Reasoning: instantiateDictsR :: RewriteH CoreExprEquality
+ HERMIT.Dictionary.Reasoning: instantiateDictsR :: RewriteH Equality
- HERMIT.Dictionary.Reasoning: instantiateEquality :: MonadIO m => [(Var, CoreExpr, [Var])] -> CoreExprEquality -> m CoreExprEquality
+ HERMIT.Dictionary.Reasoning: instantiateEquality :: MonadIO m => [(Var, CoreExpr, [Var])] -> Equality -> m Equality
- HERMIT.Dictionary.Reasoning: instantiateEqualityVar :: MonadIO m => (Var -> Bool) -> CoreExpr -> [Var] -> CoreExprEquality -> m CoreExprEquality
+ HERMIT.Dictionary.Reasoning: instantiateEqualityVar :: MonadIO m => (Var -> Bool) -> CoreExpr -> [Var] -> Equality -> m Equality
- HERMIT.Dictionary.Reasoning: instantiateEqualityVarR :: (Var -> Bool) -> CoreString -> RewriteH CoreExprEquality
+ HERMIT.Dictionary.Reasoning: instantiateEqualityVarR :: (Var -> Bool) -> CoreString -> RewriteH Equality
- HERMIT.Dictionary.Reasoning: lhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m CoreExprEquality
+ HERMIT.Dictionary.Reasoning: lhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m Equality
- HERMIT.Dictionary.Reasoning: lhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m CoreExprEquality b
+ HERMIT.Dictionary.Reasoning: lhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m Equality b
- HERMIT.Dictionary.Reasoning: rhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m CoreExprEquality
+ HERMIT.Dictionary.Reasoning: rhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m Equality
- HERMIT.Dictionary.Reasoning: rhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m CoreExprEquality b
+ HERMIT.Dictionary.Reasoning: rhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m Equality b
- HERMIT.Dictionary.Reasoning: unshadowEqualityR :: RewriteH CoreExprEquality
+ HERMIT.Dictionary.Reasoning: unshadowEqualityR :: RewriteH Equality
- HERMIT.Dictionary.Reasoning: verifyEqualityCommonTargetT :: MonadCatch m => CoreExpr -> CoreExpr -> CoreExprEqualityProof c m -> Transform c m a ()
+ HERMIT.Dictionary.Reasoning: verifyEqualityCommonTargetT :: MonadCatch m => CoreExpr -> CoreExpr -> EqualityProof c m -> Transform c m a ()
- HERMIT.Dictionary.Rules: getHermitRuleT :: HasCoreRules c => RuleNameString -> Transform c HermitM a CoreRule
+ HERMIT.Dictionary.Rules: getHermitRuleT :: (HasCoreRules c, HasHermitMEnv m, LiftCoreM m, MonadIO m) => RuleName -> Transform c m a CoreRule
- HERMIT.Dictionary.Rules: getHermitRulesT :: HasCoreRules c => Transform c HermitM a [(RuleNameString, CoreRule)]
+ HERMIT.Dictionary.Rules: getHermitRulesT :: (HasCoreRules c, HasHermitMEnv m, LiftCoreM m, MonadIO m) => Transform c m a [(RuleName, CoreRule)]
- HERMIT.Dictionary.Rules: ruleNameToEqualityT :: (BoundVars c, HasCoreRules c) => RuleNameString -> Transform c HermitM a CoreExprEquality
+ HERMIT.Dictionary.Rules: ruleNameToEqualityT :: (BoundVars c, HasCoreRules c, HasDynFlags m, HasHermitMEnv m, LiftCoreM m, MonadCatch m, MonadIO m, MonadThings m) => RuleName -> Transform c m a Equality
- HERMIT.Dictionary.Rules: ruleR :: (ReadBindings c, HasCoreRules c) => RuleNameString -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Rules: ruleR :: (AddBindings c, ExtendPath c Crumb, HasCoreRules c, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, HasDynFlags m, HasHermitMEnv m, HasLemmas m, LiftCoreM m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => RuleName -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Rules: ruleToEqualityT :: (BoundVars c, HasDynFlags m, HasModGuts m, MonadThings m, MonadCatch m) => Transform c m CoreRule CoreExprEquality
+ HERMIT.Dictionary.Rules: ruleToEqualityT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, MonadThings m, MonadCatch m) => Transform c m CoreRule Equality
- HERMIT.Dictionary.Rules: rulesR :: (ReadBindings c, HasCoreRules c) => [RuleNameString] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Rules: rulesR :: (AddBindings c, ExtendPath c Crumb, HasCoreRules c, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, HasDynFlags m, HasHermitMEnv m, HasLemmas m, LiftCoreM m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m) => [RuleName] -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: errorToUndefinedR :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: errorToUndefinedR :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: isUndefinedValT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m CoreExpr ()
+ HERMIT.Dictionary.Undefined: isUndefinedValT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m CoreExpr ()
- HERMIT.Dictionary.Undefined: mkUndefinedValT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Type -> Transform c m a CoreExpr
+ HERMIT.Dictionary.Undefined: mkUndefinedValT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Type -> Transform c m a CoreExpr
- HERMIT.Dictionary.Undefined: replaceCurrentExprWithUndefinedR :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: replaceCurrentExprWithUndefinedR :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: replaceIdWithUndefinedR :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Id -> Rewrite c m Core
+ HERMIT.Dictionary.Undefined: replaceIdWithUndefinedR :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Id -> Rewrite c m Core
- HERMIT.Dictionary.Undefined: undefinedAppR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedAppR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedCaseAltsR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCaseAltsR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedCaseScrutineeR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCaseScrutineeR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedCastR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCastR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedLamR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedLamR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedLetR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedLetR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: undefinedTickR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedTickR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Undefined: verifyStrictT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => CoreExpr -> Rewrite c m CoreExpr -> Transform c m a ()
+ HERMIT.Dictionary.Undefined: verifyStrictT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => CoreExpr -> Rewrite c m CoreExpr -> Transform c m a ()
- HERMIT.Dictionary.Unfold: rememberR :: Label -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Unfold: rememberR :: RememberedName -> Rewrite c HermitM Core
- HERMIT.Dictionary.Unfold: unfoldNameR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldNameR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => HermitName -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Unfold: unfoldNamesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [String] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldNamesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c, MonadCatch m) => [HermitName] -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Unfold: unfoldPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => (Id -> [CoreExpr] -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldPredR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => (Id -> [CoreExpr] -> Bool) -> Rewrite c m CoreExpr
- HERMIT.Dictionary.Unfold: unfoldR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr
- HERMIT.Dictionary.Unfold: unfoldStashR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldStashR :: ReadBindings c => RememberedName -> Rewrite c HermitM CoreExpr
- HERMIT.Dictionary.Unsafe: unsafeReplaceStashR :: String -> RewriteH CoreExpr
+ HERMIT.Dictionary.Unsafe: unsafeReplaceStashR :: RememberedName -> RewriteH CoreExpr
- HERMIT.Dictionary.WorkerWrapper.Common: workLabel :: Label
+ HERMIT.Dictionary.WorkerWrapper.Common: workLabel :: RememberedName
- HERMIT.Kernel: applyK :: Kernel -> AST -> RewriteH ModGuts -> HermitMEnv -> IO (KureM AST)
+ HERMIT.Kernel: applyK :: Kernel -> AST -> RewriteH ModGuts -> KernelEnv -> IO (KureM AST)
- HERMIT.Kernel: queryK :: Kernel -> forall a. AST -> TransformH ModGuts a -> HermitMEnv -> IO (KureM a)
+ HERMIT.Kernel: queryK :: Kernel -> forall a. AST -> TransformH ModGuts a -> KernelEnv -> IO (KureM a)
- HERMIT.Kernel.Scoped: ScopedKernel :: (forall m. (MonadIO m, MonadCatch m) => SAST -> m ()) -> (forall m. MonadIO m => m ()) -> (forall g m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => RewriteH g -> HermitMEnv -> SAST -> m SAST) -> (forall g a m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => TransformH g a -> HermitMEnv -> SAST -> m a) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m ()) -> (forall m. MonadIO m => m [SAST]) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m [PathH]) -> (forall m. (MonadIO m, MonadCatch m) => (LocalPathH -> LocalPathH) -> HermitMEnv -> SAST -> m SAST) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST) -> Kernel -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m AST) -> ScopedKernel
+ HERMIT.Kernel.Scoped: ScopedKernel :: (forall m. (MonadIO m, MonadCatch m) => SAST -> m ()) -> (forall m. MonadIO m => m ()) -> (forall g m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => RewriteH g -> KernelEnv -> SAST -> m SAST) -> (forall g a m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => TransformH g a -> KernelEnv -> SAST -> m a) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m ()) -> (forall m. MonadIO m => m [SAST]) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m [PathH]) -> (forall m. (MonadIO m, MonadCatch m) => (LocalPathH -> LocalPathH) -> KernelEnv -> SAST -> m SAST) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST) -> Kernel -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m AST) -> ScopedKernel
- HERMIT.Kernel.Scoped: applyS :: ScopedKernel -> forall g m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => RewriteH g -> HermitMEnv -> SAST -> m SAST
+ HERMIT.Kernel.Scoped: applyS :: ScopedKernel -> forall g m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => RewriteH g -> KernelEnv -> SAST -> m SAST
- HERMIT.Kernel.Scoped: modPathS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => (LocalPathH -> LocalPathH) -> HermitMEnv -> SAST -> m SAST
+ HERMIT.Kernel.Scoped: modPathS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => (LocalPathH -> LocalPathH) -> KernelEnv -> SAST -> m SAST
- HERMIT.Kernel.Scoped: queryS :: ScopedKernel -> forall g a m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => TransformH g a -> HermitMEnv -> SAST -> m a
+ HERMIT.Kernel.Scoped: queryS :: ScopedKernel -> forall g a m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => TransformH g a -> KernelEnv -> SAST -> m a
- HERMIT.Monad: DebugCore :: String -> HermitC -> CoreTC -> DebugMessage
+ HERMIT.Monad: DebugCore :: String -> c -> CoreTC -> DebugMessage
- HERMIT.Monad: HermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv
+ HERMIT.Monad: HermitMEnv :: ModGuts -> DefStash -> Lemmas -> HermitMEnv
- HERMIT.Monad: data DebugMessage
+ HERMIT.Monad: data DebugMessage :: *
- HERMIT.Monad: getModGuts :: HasModGuts m => m ModGuts
+ HERMIT.Monad: getModGuts :: (HasHermitMEnv m, Monad m) => m ModGuts
- HERMIT.Monad: getStash :: HermitM DefStash
+ HERMIT.Monad: getStash :: HasStash m => m DefStash
- HERMIT.Monad: liftCoreM :: CoreM a -> HermitM a
+ HERMIT.Monad: liftCoreM :: LiftCoreM m => CoreM a -> m a
- HERMIT.Monad: lookupDef :: Label -> HermitM CoreDef
+ HERMIT.Monad: lookupDef :: (HasStash m, Monad m) => RememberedName -> m CoreDef
- HERMIT.Monad: runHM :: (ModGuts, HermitMEnv) -> DefStash -> (DefStash -> a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b
+ HERMIT.Monad: runHM :: DebugChan -> HermitMEnv -> (HermitMResult a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b
- HERMIT.Monad: saveDef :: Label -> CoreDef -> HermitM ()
+ HERMIT.Monad: saveDef :: (HasStash m, Monad m) => RememberedName -> CoreDef -> m ()
- HERMIT.Monad: sendDebugMessage :: DebugMessage -> HermitM ()
+ HERMIT.Monad: sendDebugMessage :: (HasDebugChan m, Monad m) => DebugMessage -> m ()
- HERMIT.Monad: type DefStash = Map Label CoreDef
+ HERMIT.Monad: type DefStash = Map RememberedName CoreDef
- HERMIT.Name: findId :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) => String -> c -> m Id
+ HERMIT.Name: findId :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> c -> m Id
- HERMIT.Name: findInNameSpace :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadIO m, MonadThings m) => NameSpace -> String -> c -> m Named
+ HERMIT.Name: findInNameSpace :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadIO m, MonadThings m) => NameSpace -> HermitName -> c -> m Named
- HERMIT.Name: findInNameSpaces :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) => [NameSpace] -> String -> c -> m Named
+ HERMIT.Name: findInNameSpaces :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => [NameSpace] -> HermitName -> c -> m Named
- HERMIT.Name: findTyCon :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) => String -> c -> m TyCon
+ HERMIT.Name: findTyCon :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> c -> m TyCon
- HERMIT.Name: findType :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) => String -> c -> m Type
+ HERMIT.Name: findType :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> c -> m Type
- HERMIT.Name: findVar :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) => String -> c -> m Var
+ HERMIT.Name: findVar :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m) => HermitName -> c -> m Var
- HERMIT.ParserCore: parseCore :: CoreString -> HermitC -> HermitM CoreExpr
+ HERMIT.ParserCore: parseCore :: BoundVars c => CoreString -> c -> HermitM CoreExpr
- HERMIT.ParserCore: parseCoreExprT :: CoreString -> TransformH a CoreExpr
+ HERMIT.ParserCore: parseCoreExprT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m) => CoreString -> Transform c m a CoreExpr
- HERMIT.Plugin: defPS :: SAST -> ScopedKernel -> PhaseInfo -> IO PluginState
+ HERMIT.Plugin: defPS :: SAST -> ScopedKernel -> PassInfo -> IO PluginState
- HERMIT.Plugin.Builder: type PluginPass = PhaseInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts
+ HERMIT.Plugin.Builder: type PluginPass = PassInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts
- HERMIT.Plugin.Types: PluginState :: SAST -> PrettyPrinter -> (Handle -> PrettyOptions -> Either String DocH -> IO ()) -> TVar (Map String Int) -> Bool -> Bool -> Bool -> ScopedKernel -> PhaseInfo -> PluginState
+ HERMIT.Plugin.Types: PluginState :: SAST -> PrettyPrinter -> (Handle -> PrettyOptions -> Either String DocH -> IO ()) -> TVar (Map String Int) -> Bool -> Bool -> Bool -> ScopedKernel -> PassInfo -> PluginState
- HERMIT.Plugin.Types: mkKernelEnv :: PluginState -> HermitMEnv
+ HERMIT.Plugin.Types: mkKernelEnv :: PluginState -> KernelEnv
- HERMIT.PrettyPrinter.Common: PrettyOptions :: Bool -> ShowOption -> ShowOption -> ShowOption -> Maybe PathH -> Maybe Int -> Bool -> Float -> Int -> PrettyOptions
+ HERMIT.PrettyPrinter.Common: PrettyOptions :: Bool -> ShowOption -> ShowOption -> ShowOption -> Bool -> Maybe PathH -> Maybe Int -> Bool -> Float -> Int -> PrettyOptions
- HERMIT.Shell.Command: cl_kernel_env :: CommandLineState -> HermitMEnv
+ HERMIT.Shell.Command: cl_kernel_env :: CommandLineState -> KernelEnv
- HERMIT.Shell.Command: commandLine :: [CommandLineOption] -> Behavior -> [External] -> CLT IO ()
+ HERMIT.Shell.Command: commandLine :: (MonadCatch m, MonadException m, CLMonad m) => [Interp m ()] -> [CommandLineOption] -> [External] -> m ()
- HERMIT.Shell.Command: evalScript :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()
+ HERMIT.Shell.Command: evalScript :: (MonadCatch m, CLMonad m) => [Interp m ()] -> String -> m ()
- HERMIT.Shell.Command: performQuery :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => QueryFun -> ExprH -> m ()
+ HERMIT.Shell.Command: performQuery :: (MonadCatch m, CLMonad m) => QueryFun -> ExprH -> m ()
- HERMIT.Shell.Command: shellComplete :: MVar CommandLineState -> String -> String -> IO [Completion]
+ HERMIT.Shell.Command: shellComplete :: (MonadCatch m, MonadIO m, MonadState CommandLineState m) => String -> String -> m [Completion]
- HERMIT.Shell.Interpreter: data Interp :: * -> *
+ HERMIT.Shell.Interpreter: data Interp :: (* -> *) -> * -> *
- HERMIT.Shell.Interpreter: interp :: Typeable a => (a -> cmd) -> Interp cmd
+ HERMIT.Shell.Interpreter: interp :: (Monad m, Typeable b) => (b -> a) -> Interp m a
- HERMIT.Shell.Interpreter: interpExprH :: MonadState CommandLineState m => [Interp b] -> ExprH -> m b
+ HERMIT.Shell.Interpreter: interpExprH :: CLMonad m => [Interp m b] -> ExprH -> m b
- HERMIT.Shell.KernelEffect: data KernelEffect :: *
+ HERMIT.Shell.KernelEffect: data KernelEffect
- HERMIT.Shell.KernelEffect: performKernelEffect :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => KernelEffect -> ExprH -> m ()
+ HERMIT.Shell.KernelEffect: performKernelEffect :: (MonadCatch m, CLMonad m) => ExprH -> KernelEffect -> m ()
- HERMIT.Shell.Proof: performProofCommand :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => ProofCommand -> m ()
+ HERMIT.Shell.Proof: performProofCommand :: (MonadCatch m, MonadException m, CLMonad m) => ProofCommand -> m ()
- HERMIT.Shell.Proof: ppLemmaT :: PrettyPrinter -> TransformH Lemma DocH
+ HERMIT.Shell.Proof: ppLemmaT :: PrettyPrinter -> LemmaName -> TransformH Lemma DocH
- HERMIT.Shell.Proof: userProofTechnique :: TransformH CoreExprEquality () -> UserProofTechnique
+ HERMIT.Shell.Proof: userProofTechnique :: TransformH Equality () -> UserProofTechnique
- HERMIT.Shell.ScriptToRewrite: addScriptToDict :: MonadState CommandLineState m => ScriptName -> Script -> m ()
+ HERMIT.Shell.ScriptToRewrite: addScriptToDict :: CLMonad m => ScriptName -> Script -> m ()
- HERMIT.Shell.ScriptToRewrite: performScriptEffect :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => (ExprH -> m ()) -> ScriptEffect -> m ()
+ HERMIT.Shell.ScriptToRewrite: performScriptEffect :: (MonadCatch m, CLMonad m) => (ExprH -> m ()) -> ScriptEffect -> m ()
- HERMIT.Shell.ScriptToRewrite: scriptToRewrite :: MonadState CommandLineState m => Script -> m (RewriteH Core)
+ HERMIT.Shell.ScriptToRewrite: scriptToRewrite :: CLMonad m => Script -> m (RewriteH Core)
- HERMIT.Shell.Types: CommandLineState :: PluginState -> Int -> [(ScriptName, Script)] -> [Lemma] -> Bool -> VersionStore -> PathH -> [External] -> Maybe Script -> SAST -> CommandLineState
+ HERMIT.Shell.Types: CommandLineState :: PluginState -> Int -> [(ScriptName, Script)] -> Bool -> VersionStore -> PathH -> [External] -> Maybe Script -> SAST -> CommandLineState
- HERMIT.Shell.Types: cl_kernel_env :: CommandLineState -> HermitMEnv
+ HERMIT.Shell.Types: cl_kernel_env :: CommandLineState -> KernelEnv
- HERMIT.Shell.Types: cl_putStr :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()
+ HERMIT.Shell.Types: cl_putStr :: CLMonad m => String -> m ()
- HERMIT.Shell.Types: cl_putStrLn :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()
+ HERMIT.Shell.Types: cl_putStrLn :: CLMonad m => String -> m ()
- HERMIT.Shell.Types: fixWindow :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => m ()
+ HERMIT.Shell.Types: fixWindow :: CLMonad m => m ()
- HERMIT.Shell.Types: performQuery :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => QueryFun -> ExprH -> m ()
+ HERMIT.Shell.Types: performQuery :: (MonadCatch m, CLMonad m) => QueryFun -> ExprH -> m ()
- HERMIT.Shell.Types: pluginM :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => PluginM a -> m a
+ HERMIT.Shell.Types: pluginM :: CLMonad m => PluginM a -> m a
- HERMIT.Shell.Types: putStrToConsole :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()
+ HERMIT.Shell.Types: putStrToConsole :: CLMonad m => String -> m ()
- HERMIT.Shell.Types: showWindow :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => m ()
+ HERMIT.Shell.Types: showWindow :: CLMonad m => m ()

Files

dist/build/HERMIT/Parser.hs view
@@ -6,6 +6,7 @@     , unparseScript     , unparseExprH     , ExprH(..)+    , parseExprH     ) where  import Data.Char (isSpace)@@ -19,85 +20,84 @@  -- parser produced by Happy Version 1.19.3 -newtype HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 = HappyAbsSyn HappyAny+newtype HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12 = HappyAbsSyn HappyAny #if __GLASGOW_HASKELL__ >= 607 type HappyAny = Happy_GHC_Exts.Any #else type HappyAny = forall a . a #endif-happyIn4 :: t4 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn4 #-}-happyOut4 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t4-happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut4 #-}-happyIn5 :: t5 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn5 :: t5 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn5 #-}-happyOut5 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t5+happyOut5 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t5 happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut5 #-}-happyIn6 :: t6 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn6 :: t6 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn6 #-}-happyOut6 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t6+happyOut6 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t6 happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut6 #-}-happyIn7 :: t7 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn7 :: t7 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn7 #-}-happyOut7 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t7+happyOut7 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t7 happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut7 #-}-happyIn8 :: t8 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn8 :: t8 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn8 #-}-happyOut8 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t8+happyOut8 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t8 happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut8 #-}-happyIn9 :: t9 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn9 :: t9 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn9 #-}-happyOut9 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t9+happyOut9 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t9 happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut9 #-}-happyIn10 :: t10 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn10 :: t10 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn10 #-}-happyOut10 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t10+happyOut10 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t10 happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut10 #-}-happyIn11 :: t11 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn11 :: t11 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn11 #-}-happyOut11 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t11+happyOut11 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t11 happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut11 #-}-happyInTok :: (Token) -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn12 :: t12 -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12)+happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn12 #-}+happyOut12 :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> t12+happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut12 #-}+happyInTok :: (Token) -> (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) happyInTok x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyInTok #-}-happyOutTok :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> (Token)+happyOutTok :: (HappyAbsSyn t5 t6 t7 t8 t9 t10 t11 t12) -> (Token) happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOutTok #-}   happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\x0e\x00\x1e\x00\x0e\x00\x06\x00\x00\x00\x00\x00\xfd\xff\x01\x00\x00\x00\x1a\x00\x0e\x00\x1a\x00\x0e\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x09\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00"#+happyActOffsets = HappyA# "\x0e\x00\x1a\x00\x1e\x00\x0e\x00\x06\x00\x01\x00\x00\x00\x1a\x00\x1a\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\xfd\xff\x0e\x00\x0e\x00\x00\x00\x00\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x09\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00"#  happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\x45\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00\x4d\x00\x39\x00\x48\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x2d\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00"#+happyGotoOffsets = HappyA# "\x45\x00\x50\x00\x00\x00\x3f\x00\x00\x00\xfe\xff\x00\x00\x4d\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x39\x00\x33\x00\x00\x00\x00\x00\x2d\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00"#  happyDefActions :: HappyAddr-happyDefActions = HappyA# "\xfa\xff\x00\x00\xfa\xff\x00\x00\xfc\xff\xfb\xff\xf9\xff\xf4\xff\xf2\xff\x00\x00\xfa\xff\xe8\xff\xfa\xff\x00\x00\xed\xff\xee\xff\xea\xff\xef\xff\xf1\xff\xf0\xff\xf6\xff\xe7\xff\x00\x00\xe9\xff\xfd\xff\x00\x00\xf3\xff\x00\x00\xfa\xff\xfa\xff\xfe\xff\xf7\xff\xf8\xff\xf5\xff\xeb\xff\xec\xff\x00\x00\xe6\xff"#+happyDefActions = HappyA# "\xf9\xff\x00\x00\x00\x00\xf9\xff\x00\x00\xf3\xff\xf1\xff\x00\x00\xe7\xff\x00\x00\xec\xff\xed\xff\xe9\xff\x00\x00\xfb\xff\xfa\xff\xf8\xff\xf9\xff\xf9\xff\xf5\xff\xfc\xff\xf9\xff\xf9\xff\xee\xff\xf0\xff\xef\xff\xe6\xff\x00\x00\xe8\xff\x00\x00\xf2\xff\x00\x00\xfd\xff\xf4\xff\xea\xff\xeb\xff\x00\x00\xf6\xff\xf7\xff\xe5\xff"#  happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x04\x00\x01\x00\x05\x00\x02\x00\x08\x00\x05\x00\x03\x00\x04\x00\x05\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x01\x00\x07\x00\x03\x00\x04\x00\x05\x00\x0e\x00\x06\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x01\x00\x03\x00\x04\x00\x05\x00\x05\x00\x07\x00\x03\x00\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x03\x00\x04\x00\x05\x00\xff\xff\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#+happyCheck = HappyA# "\xff\xff\x04\x00\x01\x00\x05\x00\x02\x00\x08\x00\x05\x00\x03\x00\x04\x00\x05\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x01\x00\x07\x00\x03\x00\x04\x00\x05\x00\x0e\x00\x06\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x01\x00\x03\x00\x04\x00\x05\x00\x05\x00\x07\x00\x03\x00\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x03\x00\x04\x00\x05\x00\x03\x00\x04\x00\x05\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#  happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x1d\x00\x0a\x00\x1a\x00\x23\x00\x1e\x00\x0c\x00\x21\x00\x07\x00\x08\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1c\x00\x0a\x00\x24\x00\x03\x00\x0b\x00\x0c\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x0a\x00\x15\x00\x07\x00\x08\x00\x0c\x00\x25\x00\x03\x00\x00\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1f\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x20\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x14\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x18\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x1e\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x15\x00\x07\x00\x08\x00\x16\x00\x17\x00\x19\x00\x07\x00\x08\x00\x00\x00\x12\x00\x13\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyTable = HappyA# "\x00\x00\x16\x00\x08\x00\x1e\x00\x23\x00\x17\x00\x09\x00\x21\x00\x05\x00\x06\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x20\x00\x08\x00\x24\x00\x04\x00\x12\x00\x09\x00\xff\xff\x25\x00\x13\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x08\x00\x1a\x00\x05\x00\x06\x00\x09\x00\x27\x00\x04\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x25\x00\x0e\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x26\x00\x0e\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x13\x00\x0e\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x14\x00\x0e\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x20\x00\x0e\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x05\x00\x06\x00\x1a\x00\x05\x00\x06\x00\x1b\x00\x1c\x00\x1d\x00\x05\x00\x06\x00\x04\x00\x05\x00\x06\x00\x18\x00\x19\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# -happyReduceArr = Happy_Data_Array.array (1, 25) [-	(1 , happyReduce_1),+happyReduceArr = Happy_Data_Array.array (2, 26) [ 	(2 , happyReduce_2), 	(3 , happyReduce_3), 	(4 , happyReduce_4),@@ -121,205 +121,206 @@ 	(22 , happyReduce_22), 	(23 , happyReduce_23), 	(24 , happyReduce_24),-	(25 , happyReduce_25)+	(25 , happyReduce_25),+	(26 , happyReduce_26) 	]  happy_n_terms = 15 :: Int happy_n_nonterms = 8 :: Int -happyReduce_1 = happySpecReduce_2  0# happyReduction_1-happyReduction_1 happy_x_2+happyReduce_2 = happySpecReduce_2  0# happyReduction_2+happyReduction_2 happy_x_2 	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn4+	 =  case happyOut5 happy_x_2 of { happy_var_2 -> +	happyIn5 		 (CmdName "{" : happy_var_2 	)} -happyReduce_2 = happySpecReduce_2  0# happyReduction_2-happyReduction_2 happy_x_2+happyReduce_3 = happySpecReduce_2  0# happyReduction_3+happyReduction_3 happy_x_2 	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn4+	 =  case happyOut5 happy_x_2 of { happy_var_2 -> +	happyIn5 		 (CmdName "}" : happy_var_2 	)} -happyReduce_3 = happySpecReduce_1  0# happyReduction_3-happyReduction_3 happy_x_1-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> -	happyIn4-		 (happy_var_1-	)}--happyReduce_4 = happySpecReduce_1  1# happyReduction_4+happyReduce_4 = happySpecReduce_1  0# happyReduction_4 happyReduction_4 happy_x_1 	 =  case happyOut6 happy_x_1 of { happy_var_1 ->  	happyIn5 		 (happy_var_1 	)} -happyReduce_5 = happySpecReduce_0  1# happyReduction_5-happyReduction_5  =  happyIn5+happyReduce_5 = happySpecReduce_1  1# happyReduction_5+happyReduction_5 happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	happyIn6+		 (happy_var_1+	)}++happyReduce_6 = happySpecReduce_0  1# happyReduction_6+happyReduction_6  =  happyIn6 		 ([] 	) -happyReduce_6 = happySpecReduce_1  2# happyReduction_6-happyReduction_6 happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	happyIn6+happyReduce_7 = happySpecReduce_1  2# happyReduction_7+happyReduction_7 happy_x_1+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	happyIn7 		 ([happy_var_1] 	)} -happyReduce_7 = happySpecReduce_3  2# happyReduction_7-happyReduction_7 happy_x_3+happyReduce_8 = happySpecReduce_3  2# happyReduction_8+happyReduction_8 happy_x_3 	happy_x_2 	happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	case happyOut4 happy_x_3 of { happy_var_3 -> -	happyIn6+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	case happyOut5 happy_x_3 of { happy_var_3 -> +	happyIn7 		 ([happy_var_1, CmdName "}"] ++ happy_var_3 	)}} -happyReduce_8 = happySpecReduce_3  2# happyReduction_8-happyReduction_8 happy_x_3+happyReduce_9 = happySpecReduce_3  2# happyReduction_9+happyReduction_9 happy_x_3 	happy_x_2 	happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	case happyOut4 happy_x_3 of { happy_var_3 -> -	happyIn6+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	case happyOut5 happy_x_3 of { happy_var_3 -> +	happyIn7 		 (happy_var_1 : happy_var_3 	)}} -happyReduce_9 = happySpecReduce_2  2# happyReduction_9-happyReduction_9 happy_x_2+happyReduce_10 = happySpecReduce_2  2# happyReduction_10+happyReduction_10 happy_x_2 	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn6+	 =  case happyOut5 happy_x_2 of { happy_var_2 -> +	happyIn7 		 (happy_var_2 	)} -happyReduce_10 = happySpecReduce_3  3# happyReduction_10-happyReduction_10 happy_x_3+happyReduce_11 = happySpecReduce_3  3# happyReduction_11+happyReduction_11 happy_x_3 	happy_x_2 	happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	 =  case happyOut9 happy_x_1 of { happy_var_1 ->  	case happyOutTok happy_x_2 of { (InfixOp happy_var_2) -> -	case happyOut7 happy_x_3 of { happy_var_3 -> -	happyIn7+	case happyOut8 happy_x_3 of { happy_var_3 -> +	happyIn8 		 (AppH (AppH (CmdName happy_var_2) happy_var_1) happy_var_3 	)}}} -happyReduce_11 = happySpecReduce_1  3# happyReduction_11-happyReduction_11 happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> -	happyIn7+happyReduce_12 = happySpecReduce_1  3# happyReduction_12+happyReduction_12 happy_x_1+	 =  case happyOut9 happy_x_1 of { happy_var_1 -> +	happyIn8 		 (happy_var_1 	)} -happyReduce_12 = happySpecReduce_2  4# happyReduction_12-happyReduction_12 happy_x_2+happyReduce_13 = happySpecReduce_2  4# happyReduction_13+happyReduction_13 happy_x_2 	happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> -	case happyOut9 happy_x_2 of { happy_var_2 -> -	happyIn8+	 =  case happyOut9 happy_x_1 of { happy_var_1 -> +	case happyOut10 happy_x_2 of { happy_var_2 -> +	happyIn9 		 (AppH happy_var_1 happy_var_2 	)}} -happyReduce_13 = happySpecReduce_1  4# happyReduction_13-happyReduction_13 happy_x_1-	 =  case happyOut9 happy_x_1 of { happy_var_1 -> -	happyIn8+happyReduce_14 = happySpecReduce_1  4# happyReduction_14+happyReduction_14 happy_x_1+	 =  case happyOut10 happy_x_1 of { happy_var_1 -> +	happyIn9 		 (happy_var_1 	)} -happyReduce_14 = happySpecReduce_2  5# happyReduction_14-happyReduction_14 happy_x_2+happyReduce_15 = happySpecReduce_2  5# happyReduction_15+happyReduction_15 happy_x_2 	happy_x_1 	 =  case happyOutTok happy_x_2 of { (Ident happy_var_2) -> -	happyIn9+	happyIn10 		 (SrcName happy_var_2 	)} -happyReduce_15 = happySpecReduce_2  5# happyReduction_15-happyReduction_15 happy_x_2+happyReduce_16 = happySpecReduce_2  5# happyReduction_16+happyReduction_16 happy_x_2 	happy_x_1 	 =  case happyOutTok happy_x_2 of { (InfixOp happy_var_2) -> -	happyIn9+	happyIn10 		 (SrcName happy_var_2 	)} -happyReduce_16 = happySpecReduce_2  5# happyReduction_16-happyReduction_16 happy_x_2+happyReduce_17 = happySpecReduce_2  5# happyReduction_17+happyReduction_17 happy_x_2 	happy_x_1 	 =  case happyOutTok happy_x_2 of { (Quote happy_var_2) -> -	happyIn9+	happyIn10 		 (SrcName happy_var_2 	)} -happyReduce_17 = happySpecReduce_1  5# happyReduction_17-happyReduction_17 happy_x_1+happyReduce_18 = happySpecReduce_1  5# happyReduction_18+happyReduction_18 happy_x_1 	 =  case happyOutTok happy_x_1 of { (Quote happy_var_1) -> -	happyIn9+	happyIn10 		 (CmdName happy_var_1 	)} -happyReduce_18 = happySpecReduce_1  5# happyReduction_18-happyReduction_18 happy_x_1+happyReduce_19 = happySpecReduce_1  5# happyReduction_19+happyReduction_19 happy_x_1 	 =  case happyOutTok happy_x_1 of { (CoreString happy_var_1) -> -	happyIn9+	happyIn10 		 (CoreH happy_var_1 	)} -happyReduce_19 = happySpecReduce_3  5# happyReduction_19-happyReduction_19 happy_x_3+happyReduce_20 = happySpecReduce_3  5# happyReduction_20+happyReduction_20 happy_x_3 	happy_x_2 	happy_x_1-	 =  case happyOut10 happy_x_2 of { happy_var_2 -> -	happyIn9+	 =  case happyOut11 happy_x_2 of { happy_var_2 -> +	happyIn10 		 (ListH happy_var_2 	)} -happyReduce_20 = happySpecReduce_3  5# happyReduction_20-happyReduction_20 happy_x_3+happyReduce_21 = happySpecReduce_3  5# happyReduction_21+happyReduction_21 happy_x_3 	happy_x_2 	happy_x_1-	 =  case happyOut7 happy_x_2 of { happy_var_2 -> -	happyIn9+	 =  case happyOut8 happy_x_2 of { happy_var_2 -> +	happyIn10 		 (happy_var_2 	)} -happyReduce_21 = happySpecReduce_1  5# happyReduction_21-happyReduction_21 happy_x_1+happyReduce_22 = happySpecReduce_1  5# happyReduction_22+happyReduction_22 happy_x_1 	 =  case happyOutTok happy_x_1 of { (Ident happy_var_1) -> -	happyIn9+	happyIn10 		 (CmdName happy_var_1 	)} -happyReduce_22 = happySpecReduce_1  6# happyReduction_22-happyReduction_22 happy_x_1-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> -	happyIn10+happyReduce_23 = happySpecReduce_1  6# happyReduction_23+happyReduction_23 happy_x_1+	 =  case happyOut12 happy_x_1 of { happy_var_1 -> +	happyIn11 		 (happy_var_1 	)} -happyReduce_23 = happySpecReduce_0  6# happyReduction_23-happyReduction_23  =  happyIn10+happyReduce_24 = happySpecReduce_0  6# happyReduction_24+happyReduction_24  =  happyIn11 		 ([] 	) -happyReduce_24 = happySpecReduce_1  7# happyReduction_24-happyReduction_24 happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	happyIn11+happyReduce_25 = happySpecReduce_1  7# happyReduction_25+happyReduction_25 happy_x_1+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	happyIn12 		 ([happy_var_1] 	)} -happyReduce_25 = happySpecReduce_3  7# happyReduction_25-happyReduction_25 happy_x_3+happyReduce_26 = happySpecReduce_3  7# happyReduction_26+happyReduction_26 happy_x_3 	happy_x_2 	happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	case happyOut11 happy_x_3 of { happy_var_3 -> -	happyIn11+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	case happyOut12 happy_x_3 of { happy_var_3 -> +	happyIn12 		 (happy_var_1 : happy_var_3 	)}} @@ -359,8 +360,11 @@ happyError' = parseError  parser tks = happySomeParser where-  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))+  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut5 x)) +exprParser tks = happySomeParser where+  happySomeParser = happyThen (happyParse 1# tks) (\x -> happyReturn (happyOut8 x))+ happySeq = happyDontSeq  @@ -448,6 +452,9 @@  parseScript :: String -> Either String Script parseScript = lexer >=> parser++parseExprH :: String -> Either String ExprH+parseExprH = lexer >=> exprParser  --------------------------------------------- 
dist/build/HERMIT/ParserCore.hs view
@@ -4,6 +4,8 @@ module HERMIT.ParserCore     ( parseCore     , parseCoreExprT+    , parse2BeforeT+    , parse3BeforeT     , parse2beforeBiR     , parse3beforeBiR     , parse4beforeBiR@@ -256,21 +258,17 @@   mkIntExpr' :: Integer -> CoreParseM CoreExpr-#if __GLASGOW_HASKELL__ > 706 mkIntExpr' i = do     dflags <- lift getDynFlags     return $ mkIntExpr dflags i-#else-mkIntExpr' i = return $ mkIntExpr i-#endif  lookupName :: String -> CoreParseM CoreExpr lookupName nm = do-    c <- ask-    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId nm c+    vset <- ask+    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId (parseName nm) vset     return $ varToCoreExpr v -type CoreParseM a = ReaderT HermitC HermitM a+type CoreParseM a = ReaderT VarSet HermitM a  parseError :: Monad m => [Token] -> m a parseError ts = fail $ "core parse error: " ++ show ts@@ -337,19 +335,30 @@  --------------------------------------------- -parseCore :: CoreString -> HermitC -> HermitM CoreExpr+parseCore :: BoundVars c => CoreString -> c -> HermitM CoreExpr parseCore (CoreString s) c =     case lexer s of         Left msg -> fail msg-        Right tokens -> runReaderT (parser tokens) c+        Right tokens -> runReaderT (parser tokens) (boundVars c)  ---------------------------------------------  -- These should probably go somewhere else.  -- | Parse a 'CoreString' to a 'CoreExpr', using the current context.-parseCoreExprT :: CoreString -> TransformH a CoreExpr-parseCoreExprT = contextonlyT . parseCore+parseCoreExprT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m)+               => CoreString -> Transform c m a CoreExpr+parseCoreExprT cs = contextonlyT $ embedHermitM . parseCore cs++parse2BeforeT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m)+              => (CoreExpr -> CoreExpr -> Translate c m a b)+              -> CoreString -> CoreString -> Translate c m a b+parse2BeforeT f s1 s2 = parseCoreExprT s1 &&& parseCoreExprT s2 >>= uncurry f++parse3BeforeT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m)+              => (CoreExpr -> CoreExpr -> CoreExpr -> Translate c m a b)+              -> CoreString -> CoreString -> CoreString -> Translate c m a b+parse3BeforeT f s1 s2 s3 = (parseCoreExprT s1 &&& parseCoreExprT s2) &&& parseCoreExprT s3 >>= (uncurry . uncurry $ f)  parse2beforeBiR :: (CoreExpr -> CoreExpr -> BiRewriteH a)                 -> CoreString -> CoreString -> BiRewriteH a
dist/build/HERMIT/ParserType.hs view
@@ -2,15 +2,11 @@ {-# OPTIONS -fglasgow-exts -cpp #-} {-# LANGUAGE CPP #-} module HERMIT.ParserType-#if __GLASGOW_HASKELL__ <= 706-    () where-#else     ( parseType     , parseTypeT     , parseTypeWithHoles     , parseTypeWithHolesT     ) where-#endif  import Control.Arrow import Control.Monad.State@@ -238,14 +234,10 @@ happySeq = happyDontSeq  -#if __GLASGOW_HASKELL__ <= 706-findType = error "findType cannot be called in < GHC 7.8"-#endif- lookupName :: String -> TypeParseM Type lookupName nm = do     c <- getContext-    et <- lift $ attemptM $ findType nm c+    et <- lift $ attemptM $ findType (parseName nm) c     either (const (addTyVar nm)) return et  catchFrees :: Type -> TypeParseM ([TyVar], Type)@@ -268,7 +260,7 @@ addTyVar :: String -> TypeParseM Type addTyVar tvStr = do     used <- gets tpUsed-    case [ tv | tv <- used, getOccString tv == tvStr ] of+    case [ tv | tv <- used, unqualifiedName tv == tvStr ] of         [] -> do tv <- lift $ newTyVarH tvStr liftedTypeKind                  modify $ \ st -> st { tpUsed = tv : tpUsed st }                  return $ mkTyVarTy tv
examples/concatVanishes/Flatten.hs view
@@ -3,10 +3,6 @@  import HList -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- data Tree a = Node (Tree a) (Tree a) | Leaf a  flatten :: Tree a -> [a]
examples/concatVanishes/QSort.hs view
@@ -4,10 +4,6 @@ import HList import Data.List -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- data Tree a = Node (Tree a) (Tree a) | Leaf a  qsort        :: Ord a => [a] -> [a]
examples/concatVanishes/Rev.hs view
@@ -3,10 +3,6 @@  import HList -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- rev :: [a] -> [a] rev []     = [] rev (y:ys) = rev ys ++ [y]
examples/evaluation/Eval.hs view
@@ -3,10 +3,6 @@  import Prelude hiding (abs) -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- data Expr = Val Int | Add Expr Expr | Throw | Catch Expr Expr  type Mint = Maybe Int
examples/factorial/Fac.hs view
@@ -6,10 +6,6 @@ import Prelude hiding ((*),(-)) import GHC.Exts -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- ------------------------------------  fac :: Int -> Int
examples/fib-stream/Fib.hs view
@@ -5,10 +5,6 @@ import Nat import Stream -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- fib :: Nat -> Nat fib Zero             = Zero fib (Succ Zero)      = Succ Zero
examples/fib-tuple/Fib.hs view
@@ -1,11 +1,6 @@ {-# LANGUAGE CPP #-} module Main where -#if __GLASGOW_HASKELL__ < 708--- so we can fix-intro-import Data.Function (fix)-#endif- import Prelude hiding ((+))  data Nat = Z | S Nat
examples/flatten/Flatten.hs view
@@ -3,10 +3,6 @@  import HList -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- data Tree a = Node (Tree a) (Tree a) | Leaf a  flatten :: Tree a -> [a]
examples/hanoi/Hanoi.hs view
@@ -5,10 +5,6 @@  import Control.Monad (forM_) -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- data Nat = Z | S Nat  toInt :: Nat -> Int
examples/last/Last.hs view
@@ -1,10 +1,6 @@ {-# LANGUAGE CPP #-} module Main where -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- import Prelude hiding (last)  -------------------------------------------------
examples/qsort/QSort.hs view
@@ -3,10 +3,6 @@  import HList -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- import Data.List  data Tree a = Node (Tree a) (Tree a) | Leaf a
examples/reverse/Reverse.hs view
@@ -4,10 +4,6 @@ import HList -- import Seq -#if __GLASGOW_HASKELL__ < 708-import Data.Function (fix)-#endif- rev :: [a] -> [a] rev []     = [] rev (x:xs) = rev xs ++ [x]
hermit.cabal view
@@ -1,5 +1,5 @@ Name:                hermit-Version:             0.5.0.0+Version:             0.6.0.0 Synopsis:            Haskell Equational Reasoning Model-to-Implementation Tunnel Description:   HERMIT uses Haskell to express semi-formal models,@@ -28,12 +28,12 @@   .   @    $ hermit Reverse.hs Reverse.hss resume-   [starting HERMIT v0.5.0.0 on Reverse.hs]+   [starting HERMIT v0.6.0.0 on Reverse.hs]    % ghc Reverse.hs -fforce-recomp -O2 -dcore-lint -fexpose-all-unfoldings -fsimple-list-literals -fplugin=HERMIT -fplugin-opt=HERMIT:Main:Reverse.hss -fplugin-opt=HERMIT:Main:resume    [1 of 2] Compiling HList            ( HList.hs, HList.o )    Loading package ghc-prim ... linking ... done.    ...-   Loading package hermit-0.5.0.0 ... linking ... done.+   Loading package hermit-0.6.0.0 ... linking ... done.    [2 of 2] Compiling Main             ( Reverse.hs, Reverse.o )    Linking Reverse ...    $ ./Reverse@@ -44,12 +44,12 @@   .   @    $ hermit Reverse.hs-   [starting HERMIT v0.5.0.0 on Reverse.hs]+   [starting HERMIT v0.6.0.0 on Reverse.hs]    % ghc Reverse.hs -fforce-recomp -O2 -dcore-lint -fexpose-all-unfoldings -fsimple-list-literals -fplugin=HERMIT -fplugin-opt=HERMIT:*:    [1 of 2] Compiling HList            ( HList.hs, HList.o )    Loading package ghc-prim ... linking ... done.    ...-   Loading package hermit-0.5.0.0 ... linking ... done.+   Loading package hermit-0.6.0.0 ... linking ... done.    [2 of 2] Compiling Main             ( Reverse.hs, Reverse.o )    ===================== Welcome to HERMIT =====================    HERMIT is a toolkit for the interactive transformation of GHC@@ -143,9 +143,9 @@                  containers >= 0.5.0.0,                  data-default >= 0.5.0,                  directory >= 1.2.0.0,-                 ghc >= 7.6,+                 ghc >= 7.8,                  haskeline >= 0.7.0.3,-                 kure >= 2.16.0,+                 kure >= 2.16.4,                  marked-pretty >= 0.1,                  mtl >= 2.1.2,                  operational >= 0.2.2.1,@@ -154,13 +154,13 @@                  temporary >= 1.2.0.3,                  transformers -  if !os(windows)+  if os(windows)+    build-depends: Win32+  else     build-depends: terminfo >= 0.3.2.5 -  if impl(ghc >= 7.8)-    build-tools: happy >= 1.19.3, alex >= 3.1.3-  else-    build-tools: happy, alex+  build-tools:   alex >= 3.1.3,+                 happy >= 1.19.3    default-language: Haskell2010 @@ -226,6 +226,7 @@        HERMIT.PrettyPrinter.GHC         HERMIT.Shell.Command+       HERMIT.Shell.Completion        HERMIT.Shell.Dictionary        HERMIT.Shell.Interpreter        HERMIT.Shell.Externals@@ -241,6 +242,11 @@        HERMIT.Syntax         Paths_hermit++  if os(windows)+    Other-modules:+        HERMIT.Win32.Console+        HERMIT.Win32.IO    Hs-Source-Dirs: src 
src/HERMIT.hs view
@@ -3,9 +3,9 @@ import Data.Maybe (fromMaybe)  import HERMIT.GHC-import HERMIT.Plugin.Builder (getPhaseFlag)+import HERMIT.Plugin.Builder (getPassFlag) import HERMIT.Plugin  plugin :: Plugin-plugin = hermitPlugin $ \ options -> let (pn,opts) = fromMaybe (0,options) (getPhaseFlag options)-                                     in phase pn $ interactive [] opts+plugin = hermitPlugin $ \ options -> let (pn,opts) = fromMaybe (0,options) (getPassFlag options)+                                     in pass pn $ interactive [] opts
src/HERMIT/Context.hs view
@@ -178,9 +178,9 @@   boundVars :: VarSet -> VarSet   boundVars = id --- | List all variables bound in the context that match the given name.-findBoundVars :: BoundVars c => String -> c -> VarSet-findBoundVars nm = filterVarSet (cmpString2Var nm) . boundVars+-- | List all variables bound in the context that match the given predicate.+findBoundVars :: BoundVars c => (Var -> Bool) -> c -> VarSet+findBoundVars p = filterVarSet p . boundVars  -- | A class of contexts from which HERMIT bindings can be retrieved. class BoundVars c => ReadBindings c where
src/HERMIT/Core.hs view
@@ -58,11 +58,11 @@           , isCoArg           , exprKindOrType           , exprTypeM-          , endoFunType+          , endoFunTypeM           , splitTyConAppM           , splitFunTypeM-          , endoFunExprType-          , funExprArgResTypes+          , endoFunExprTypeM+          , funExprArgResTypesM           , funExprsWithInverseTypes           , appCount           , mapAlts@@ -184,24 +184,15 @@  -- | Syntactic Equality of 'Coercion's. coercionSyntaxEq :: Coercion -> Coercion -> Bool-#if __GLASGOW_HASKELL__ > 706 coercionSyntaxEq (Refl role1 ty1)        (Refl role2 ty2)        = role1 == role2 && typeSyntaxEq ty1 ty2 coercionSyntaxEq (TyConAppCo role1 tc1 cos1) (TyConAppCo role2 tc2 cos2) = role1 == role2 && tc1 == tc2 && all2 coercionSyntaxEq cos1 cos2-#else-coercionSyntaxEq (Refl ty1)              (Refl ty2)              = typeSyntaxEq ty1 ty2-coercionSyntaxEq (TyConAppCo tc1 cos1)   (TyConAppCo tc2 cos2)   = tc1 == tc2 && all2 coercionSyntaxEq cos1 cos2-#endif coercionSyntaxEq (AppCo co11 co12)       (AppCo co21 co22)       = coercionSyntaxEq co11 co21 && coercionSyntaxEq co12 co22 coercionSyntaxEq (ForAllCo v1 co1)       (ForAllCo v2 co2)       = v1 == v2 && coercionSyntaxEq co1 co2 coercionSyntaxEq (CoVarCo v1)            (CoVarCo v2)            = v1 == v2-#if __GLASGOW_HASKELL__ > 706 coercionSyntaxEq (AxiomInstCo con1 ind1 cos1) (AxiomInstCo con2 ind2 cos2) = con1 == con2 && ind1 == ind2 && all2 coercionSyntaxEq cos1 cos2 coercionSyntaxEq (LRCo lr1 co1)          (LRCo lr2 co2)          = lr1 == lr2 && coercionSyntaxEq co1 co2 coercionSyntaxEq (UnivCo role1 ty11 ty12) (UnivCo role2 ty21 ty22) = role1 == role2 && typeSyntaxEq ty11 ty21 && typeSyntaxEq ty12 ty22-#else-coercionSyntaxEq (AxiomInstCo con1 cos1) (AxiomInstCo con2 cos2) = con1 == con2 && all2 coercionSyntaxEq cos1 cos2-coercionSyntaxEq (UnsafeCo ty11 ty12)    (UnsafeCo ty21 ty22)    = typeSyntaxEq ty11 ty21 && typeSyntaxEq ty12 ty22-#endif+coercionSyntaxEq (SubCo co1)             (SubCo co2)             = coercionSyntaxEq co1 co2 coercionSyntaxEq (SymCo co1)             (SymCo co2)             = coercionSyntaxEq co1 co2 coercionSyntaxEq (TransCo co11 co12)     (TransCo co21 co22)     = coercionSyntaxEq co11 co21 && coercionSyntaxEq co12 co22 coercionSyntaxEq (NthCo n1 co1)          (NthCo n2 co2)          = n1 == n2 && coercionSyntaxEq co1 co2@@ -308,8 +299,7 @@ freeVarsBind :: CoreBind -> VarSet freeVarsBind (NonRec v e) = freeVarsExpr e `unionVarSet` freeVarsVar v freeVarsBind (Rec defs)   = let (bs,es) = unzip defs-                             in delVarSetList (unionVarSets $ map freeVarsExpr es) bs-                                `unionVarSet`  unionVarSets (map freeVarsVar bs)+                             in delVarSetList (unionVarSets (map freeVarsVar bs ++ map freeVarsExpr es)) bs  -- | Find all free variables on a binder. Equivalent to idFreeVars, but safe to call on type bindings. freeVarsVar :: Var -> VarSet@@ -380,30 +370,33 @@ splitTyConAppM :: Monad m => Type -> m (TyCon, [Type]) splitTyConAppM = maybeM "splitTyConApp failed." . splitTyConApp_maybe --- | Return the domain and codomain types of a function type, if it is a function type.-splitFunTypeM :: Monad m => Type -> m (Type,Type)-splitFunTypeM = maybeM "not a function type." . splitFunTy_maybe+-- | Get the quantified variables, domain, and codomain of a function type.+splitFunTypeM :: MonadCatch m => Type -> m ([TyVar], Type, Type)+splitFunTypeM ty = prefixFailMsg "Split function type failed: " $ do+    let (tvs, fTy) = splitForAllTys ty+    (argTy, resTy) <- maybeM "not a function type." $ splitFunTy_maybe fTy+    return (tvs, argTy, resTy)  -- | Return the domain/codomain type of an endofunction type.-endoFunType :: Monad m => Type -> m Type-endoFunType ty =-  do (ty1,ty2) <- splitFunTypeM ty+endoFunTypeM :: MonadCatch m => Type -> m ([TyVar], Type)+endoFunTypeM ty =+  do (tvs,ty1,ty2) <- splitFunTypeM ty      guardMsg (eqType ty1 ty2) ("argument and result types differ.")-     return ty1+     return (tvs, ty1)  -- | Return the domain/codomain type of an endofunction expression.-endoFunExprType :: Monad m => CoreExpr -> m Type-endoFunExprType = exprTypeM >=> endoFunType+endoFunExprTypeM :: MonadCatch m => CoreExpr -> m ([TyVar], Type)+endoFunExprTypeM = exprTypeM >=> endoFunTypeM  -- | Return the domain and codomain types of a function expression.-funExprArgResTypes :: Monad m => CoreExpr -> m (Type,Type)-funExprArgResTypes = exprTypeM >=> splitFunTypeM+funExprArgResTypesM :: MonadCatch m => CoreExpr -> m ([TyVar],Type,Type)+funExprArgResTypesM = exprTypeM >=> splitFunTypeM  -- | Check two expressions have types @a -> b@ and @b -> a@, returning @(a,b)@. funExprsWithInverseTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type,Type) funExprsWithInverseTypes f g =-  do (fdom,fcod) <- funExprArgResTypes f-     (gdom,gcod) <- funExprArgResTypes g+  do (_,fdom,fcod) <- funExprArgResTypesM f -- TODO: don't throw away TyVars+     (_,gdom,gcod) <- funExprArgResTypesM g      setFailMsg "functions do not have inverse types." $        do guardM (eqType fdom gcod)           guardM (eqType gdom fcod)
src/HERMIT/Dictionary.hs view
@@ -20,6 +20,7 @@     , module HERMIT.Dictionary.Undefined     , module HERMIT.Dictionary.Unfold     , module HERMIT.Dictionary.Unsafe+    , module HERMIT.Dictionary.WorkerWrapper.Common -- TODO: rename     , module HERMIT.Dictionary.WorkerWrapper.Fix     , module HERMIT.Dictionary.WorkerWrapper.FixResult     ) where@@ -64,6 +65,8 @@ import qualified HERMIT.Dictionary.Unfold as Unfold import           HERMIT.Dictionary.Unsafe hiding (externals) import qualified HERMIT.Dictionary.Unsafe as Unsafe+import           HERMIT.Dictionary.WorkerWrapper.Common hiding (externals)+import qualified HERMIT.Dictionary.WorkerWrapper.Common as WorkerWrapperCommon import           HERMIT.Dictionary.WorkerWrapper.Fix hiding (externals) import qualified HERMIT.Dictionary.WorkerWrapper.Fix as WorkerWrapperFix import           HERMIT.Dictionary.WorkerWrapper.FixResult hiding (externals)@@ -92,6 +95,7 @@     ++ Undefined.externals     ++ Unfold.externals     ++ Unsafe.externals+    ++ WorkerWrapperCommon.externals     ++ WorkerWrapperFix.externals     ++ WorkerWrapperFixResult.externals 
src/HERMIT/Dictionary/AlphaConversion.hs view
@@ -1,50 +1,47 @@ {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-} module HERMIT.Dictionary.AlphaConversion-       ( -- * Alpha-Renaming and Shadowing-         externals-         -- ** Alpha-Renaming-       , alphaR-       , alphaLamR-       , alphaCaseBinderR-       , alphaAltWithR-       , alphaAltVarsR-       , alphaAltR-       , alphaCaseR-       , alphaLetWithR-       , alphaLetVarsR-       , alphaLetR-       , alphaProgConsWithR-       , alphaProgConsIdsR-       , alphaProgConsR-       , alphaProgR-         -- ** Shadow Detection and Unshadowing-       , unshadowR-       , unshadowExprR-       , unshadowAltR-       , unshadowProgR-       , visibleVarsT-       , cloneVarAvoidingT---       , freshNameGenAvoidingT-       , freshNameGenAvoiding-       , detectShadowsM-       , replaceVarR-       )-where+    ( -- * Alpha-Renaming and Shadowing+      externals+      -- ** Alpha-Renaming+    , alphaR+    , alphaLamR+    , alphaCaseBinderR+    , alphaAltWithR+    , alphaAltVarsR+    , alphaAltR+    , alphaCaseR+    , alphaLetWithR+    , alphaLetVarsR+    , alphaLetR+    , alphaProgConsWithR+    , alphaProgConsIdsR+    , alphaProgConsR+    , alphaProgR+      -- ** Shadow Detection and Unshadowing+    , unshadowR+    , unshadowExprR+    , unshadowAltR+    , unshadowProgR+    , visibleVarsT+    , cloneVarAvoidingT+    , freshNameGenAvoiding+    , detectShadowsM+    , replaceVarR+    ) where -import Control.Applicative import Control.Arrow-import Control.Monad (liftM2)+import Control.Monad (liftM, liftM2) import Data.Char (isDigit) import Data.Function (on)-import Data.List (intersect)-import Data.Maybe (fromMaybe, listToMaybe)+import Data.List (intersect, delete, elemIndex)+import Data.Maybe (listToMaybe)  import HERMIT.Core import HERMIT.Context-import HERMIT.Monad import HERMIT.Kure import HERMIT.External import HERMIT.GHC+import HERMIT.Name import HERMIT.Utilities(dupsBy)  import HERMIT.Dictionary.GHC hiding (externals)@@ -106,7 +103,7 @@  -- | If a name is provided, use that as the name of the new variable. --   Otherwise modify the variable name making sure to /not/ clash with the given variables or any visible variables.-cloneVarAvoidingT :: BoundVars c => Var -> Maybe String -> [Var] -> Transform c HermitM CoreTC Var+cloneVarAvoidingT :: (BoundVars c, MonadUnique m) => Var -> Maybe String -> [Var] -> Transform c m CoreTC Var cloneVarAvoidingT v mn vs =   do vvs <- visibleVarsT      let nameModifier = freshNameGenAvoiding mn (extendVarSetList vvs vs)@@ -125,7 +122,7 @@                      , nm `notElem` names                      ]    where-           names = map uqName (varSetElems curr)+           names = varSetToStrings curr            nums = reverse $ takeWhile isDigit (reverse old)            baseLeng = length $ drop (length nums) old            base = take baseLeng old@@ -136,8 +133,8 @@  -- | Discard variables from the first set that do not shadow a variable in the second set. shadowedBy :: VarSet -> VarSet -> VarSet-shadowedBy vs fvs = let fvUqNames = map uqName (varSetElems fvs)-                     in filterVarSet (\ v -> uqName v `elem` fvUqNames) vs+shadowedBy vs fvs = let fvNames = varSetToStrings fvs+                     in filterVarSet (\ v -> unqualifiedName v `elem` fvNames) vs  -- | Shadows are any duplicates in the list, or any occurrences of the list elements in the set. detectShadowsM :: Monad m => [Var] -> VarSet -> m VarSet@@ -147,72 +144,86 @@  -- | Rename local variables with manifestly unique names (x, x0, x1, ...). --   Does not rename top-level definitions.-unshadowR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb)-          => Rewrite c HermitM Core+unshadowR :: ( AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c+             , ReadPath c Crumb, MonadCatch m, MonadUnique m )+          => Rewrite c m Core unshadowR = setFailMsg "No shadows to eliminate." $     anytdR (promoteExprR unshadowExprR <+ promoteAltR unshadowAltR <+ promoteProgR unshadowProgR) -unshadowExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb)-              => Rewrite c HermitM CoreExpr+unshadowExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m)+              => Rewrite c m CoreExpr unshadowExprR = do-    bs  <- letVarsT <+ (return <$> (caseBinderIdT <+ lamVarT))-    fvs <- unionVarSet <$> boundVarsT <*> arr freeVarsExpr+    bs  <- letVarsT <+ (liftM return (caseBinderIdT <+ lamVarT))+    fvs <- liftM2 unionVarSet boundVarsT (arr freeVarsExpr)     ss  <- detectShadowsM bs fvs     alphaLamR Nothing <+ alphaLetVarsR (varSetElems ss) <+ alphaCaseBinderR Nothing -unshadowAltR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb)-             => Rewrite c HermitM CoreAlt+unshadowAltR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m)+             => Rewrite c m CoreAlt unshadowAltR = do     bs  <- arr altVars-    fvs <- unionVarSet <$> boundVarsT <*> arr freeVarsAlt+    fvs <- liftM2 unionVarSet boundVarsT (arr freeVarsAlt)     ss  <- detectShadowsM bs fvs     alphaAltVarsR (varSetElems ss) -unshadowProgR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb)-              => Rewrite c HermitM CoreProg+unshadowProgR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m)+              => Rewrite c m CoreProg unshadowProgR = do     bs  <- progConsIdsT-    fvs <- unionVarSet <$> boundVarsT <*> arr freeVarsProg+    fvs <- liftM2 unionVarSet boundVarsT (arr freeVarsProg)     ss  <- detectShadowsM bs fvs     alphaProgConsIdsR (varSetElems ss)  dupVars :: [Var] -> [Var]-dupVars = dupsBy ((==) `on` uqName)+dupVars = dupsBy ((==) `on` unqualifiedName)  ----------------------------------------------------------------------- --- Maybe this should be defined elsewhere.+-- Maybe this should be defined in Dictionary.GHC.  -- | Replace all occurrences of a specified variable. --   Arguments are the variable to replace and the replacement variable, respectively. replaceVarR :: (Injection a Core, MonadCatch m) => Var -> Var -> Rewrite c m a replaceVarR v v' = extractR $ tryR $ substR v $ varToCoreExpr v' --- | Given a variable to replace, and a replacement, produce a 'Var' @->@ 'Var' function that---   acts as an identity for all 'Var's except the one to replace, for which it returns the replacment.---   Don't export this, it'll likely just cause confusion.-replaceVar :: Var -> Var -> (Var -> Var)-replaceVar v v' = replaceVars [(v,v')]+-- TODO: Experimental+replaceRecBindVarR :: Monad m => Id -> Id -> Rewrite c m CoreBind+replaceRecBindVarR v v' =+   do Rec ies <- idR+      let (is,es) = unzip ies+      case elemIndex v is of+        Nothing -> fail "Specified identifier does not occur in the current recursive binding group."+        Just n  -> let is0       = delete v is+                       (is1,is2) = splitAt n is0+                       is'       = is1 ++ v' : is2+                       es'       = map (substCoreExpr v (Var v')) es+                       -- TODO.  Do we need to initialize the emptySubst with bindFreeVars?+                       sub       = extendSubst emptySubst v (Var v')+                   in return $ snd $ substBind sub (Rec (zip is' es')) --- | Given a lists of variables to replace, and their replacements, produce a 'Var' @->@ 'Var' function that---   acts as in identity for all 'Var's except the ones to replace, for which it returns the replacment.---   Don't export this, it'll likely just cause confusion.-replaceVars :: [(Var,Var)] -> (Var -> Var)-replaceVars kvs v = fromMaybe v (lookup v kvs)+                   -- let is0       = delete v is+                   --     emptySub  = mkEmptySubst $ mkInScopeSet $ unionVarSets (map (localFreeVarsExpr . Var) is0)+                   --     sub       = extendSubst emptySub v (Var v')+                   --     (is1,is2) = splitAt n (snd $ substRecBndrs sub is0)+                   --     is'       = is1 ++ v' : is2+                   --     es'       = map (substCoreExpr v (Var v')) es+                   -- in return $ Rec (zip is' es')  -----------------------------------------------------------------------  -- | Alpha rename a lambda binder.  Optionally takes a suggested new name.-alphaLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Rewrite c HermitM CoreExpr+alphaLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+          => Maybe String -> Rewrite c m CoreExpr alphaLamR mn = setFailMsg (wrongFormForAlpha "Lam v e") $               do v  <- lamVarT                  v' <- extractT (cloneVarAvoidingT v mn [v])-                 lamAnyR (arr $ replaceVar v v') (replaceVarR v v')+                 lamAnyR (return v') (replaceVarR v v')  -----------------------------------------------------------------------  -- | Alpha rename a case binder.  Optionally takes a suggested new name.-alphaCaseBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Rewrite c HermitM CoreExpr+alphaCaseBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                 => Maybe String -> Rewrite c m CoreExpr alphaCaseBinderR mn = setFailMsg (wrongFormForAlpha "Case e i ty alts") $                      do i  <- caseBinderIdT                         i' <- extractT (cloneVarAvoidingT i mn [i])@@ -221,7 +232,8 @@ -----------------------------------------------------------------------  -- | Rename the specified variable in a case alternative.  Optionally takes a suggested new name.-alphaAltVarR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Var -> Rewrite c HermitM CoreAlt+alphaAltVarR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+             => Maybe String -> Var -> Rewrite c m CoreAlt alphaAltVarR mn v = do     (con, vs, rhs) <- idR     v' <- extractT (cloneVarAvoidingT v mn vs)@@ -238,129 +250,150 @@  -- | Rename the specified variables in a case alternative, using the suggested names where provided. -- Suggested names *must* be provided in left-to-right order matching the order of the alt binders.-alphaAltVarsWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [(Maybe String,Var)] -> Rewrite c HermitM CoreAlt+alphaAltVarsWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                  => [(Maybe String,Var)] -> Rewrite c m CoreAlt alphaAltVarsWithR = andR . map (uncurry alphaAltVarR) . reverse -- note: right-to-left so type subst aren't undone  -- | Rename the variables bound in a case alternative with the given list of suggested names.-alphaAltWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [String] -> Rewrite c HermitM CoreAlt+alphaAltWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+              => [String] -> Rewrite c m CoreAlt alphaAltWithR ns =   do vs <- arr altVars      alphaAltVarsWithR $ zip (map Just ns) vs  -- | Rename the specified variables in a case alternative.-alphaAltVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreAlt+alphaAltVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+              => [Var] -> Rewrite c m CoreAlt alphaAltVarsR vs =   do bs <- arr altVars      alphaAltVarsWithR (zip (repeat Nothing) (bs `intersect` vs))  -- | Rename all identifiers bound in a case alternative.-alphaAltR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreAlt+alphaAltR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+          => Rewrite c m CoreAlt alphaAltR = arr altVars >>= alphaAltVarsR  -----------------------------------------------------------------------  -- | Rename all identifiers bound in a case expression.-alphaCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+alphaCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+           => Rewrite c m CoreExpr alphaCaseR = alphaCaseBinderR Nothing >+> caseAllR idR idR idR (const alphaAltR)  -----------------------------------------------------------------------  -- | Alpha rename a non-recursive let binder.  Optionally takes a suggested new name.-alphaLetNonRecR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Rewrite c HermitM CoreExpr+alphaLetNonRecR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                => Maybe String -> Rewrite c m CoreExpr alphaLetNonRecR mn = setFailMsg (wrongFormForAlpha "Let (NonRec v e1) e2") $                     do v  <- letNonRecVarT                        v' <- extractT (cloneVarAvoidingT v mn [v])                        letNonRecAnyR (return v') idR (replaceVarR v v')  -- | Alpha rename a non-recursive let binder if the variable appears in the argument list.  Optionally takes a suggested new name.-alphaLetNonRecVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> [Var] -> Rewrite c HermitM CoreExpr-alphaLetNonRecVarsR mn vs = whenM ((`elem` vs) <$> letNonRecVarT) (alphaLetNonRecR mn)+alphaLetNonRecVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                    => Maybe String -> [Var] -> Rewrite c m CoreExpr+alphaLetNonRecVarsR mn vs = whenM (liftM (`elem` vs) letNonRecVarT) (alphaLetNonRecR mn)   -- TODO: Maybe it would be more efficient to rename all the Ids at once, rather than one by one?  -- | Rename the specified identifiers in a recursive let, using the suggested names where provided.-alphaLetRecIdsWithR :: forall c. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [(Maybe String,Id)] -> Rewrite c HermitM CoreExpr+alphaLetRecIdsWithR :: forall c m. ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                                   , BoundVars c, MonadCatch m, MonadUnique m )+                    => [(Maybe String,Id)] -> Rewrite c m CoreExpr alphaLetRecIdsWithR = andR . map (uncurry alphaLetRecIdR)   where     -- | Rename the specified identifier bound in a recursive let.  Optionally takes a suggested new name.-    alphaLetRecIdR :: Maybe String -> Id -> Rewrite c HermitM CoreExpr+    alphaLetRecIdR :: Maybe String -> Id -> Rewrite c m CoreExpr     alphaLetRecIdR mn i = setFailMsg (wrongFormForAlpha "Let (Rec bs) e") $                      do is <- letRecIdsT                         i' <- extractT (cloneVarAvoidingT i mn is)-                        letRecDefAnyR (\ _ -> (arr (replaceVar i i'), replaceVarR i i')) (replaceVarR i i')+                        letAnyR (replaceRecBindVarR i i') (replaceVarR i i')   -- | Rename the identifiers bound in a Let with the given list of suggested names.-alphaLetWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [String] -> Rewrite c HermitM CoreExpr+alphaLetWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+              => [String] -> Rewrite c m CoreExpr alphaLetWithR ns = alphaLetNonRecR (listToMaybe ns)                   <+ (letRecIdsT >>= (alphaLetRecIdsWithR . zip (map Just ns)))  -- | Rename the specified variables bound in a let.-alphaLetVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreExpr+alphaLetVarsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+              => [Var] -> Rewrite c m CoreExpr alphaLetVarsR vs = alphaLetNonRecVarsR Nothing vs                    <+ (do bs <- letT (arr bindVars) successT const                           alphaLetRecIdsWithR (zip (repeat Nothing) (bs `intersect` vs))                       )  -- | Rename all identifiers bound in a Let.-alphaLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+alphaLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+          => Rewrite c m CoreExpr alphaLetR = letVarsT >>= alphaLetVarsR  -----------------------------------------------------------------------  -- | Alpha rename a non-recursive top-level binder.  Optionally takes a suggested new name.-alphaProgConsNonRecR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> Rewrite c HermitM CoreProg+alphaProgConsNonRecR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                     => Maybe String -> Rewrite c m CoreProg alphaProgConsNonRecR mn = setFailMsg (wrongFormForAlpha "ProgCons (NonRec v e) p") $                     do i <- progConsNonRecIdT-                       guardMsg (not $ isExportedId i) ("Identifier " ++ var2String i ++ " is exported, and thus cannot be alpha-renamed.")+                       guardMsg (not $ isExportedId i) ("Identifier " ++ unqualifiedName i ++ " is exported, and thus cannot be alpha-renamed.")                        i' <- extractT (cloneVarAvoidingT i mn [i])                        consNonRecAnyR (return i') idR (replaceVarR i i')  -- | Alpha rename a non-recursive top-level binder if the identifier appears in the argument list.  Optionally takes a suggested new name.-alphaProgConsNonRecIdsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Maybe String -> [Id] -> Rewrite c HermitM CoreProg-alphaProgConsNonRecIdsR mn is = whenM ((`elem` is) <$> progConsNonRecIdT) (alphaProgConsNonRecR mn)+alphaProgConsNonRecIdsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                        => Maybe String -> [Id] -> Rewrite c m CoreProg+alphaProgConsNonRecIdsR mn is = whenM (liftM (`elem` is) progConsNonRecIdT) (alphaProgConsNonRecR mn)  -- TODO: Maybe it would be more efficient to rename all the Ids at once, rather than one by one?  -- | Rename the specified identifiers in a recursive top-level binding at the head of a program, using the suggested names where provided.-alphaProgConsRecIdsWithR :: forall c. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [(Maybe String,Id)] -> Rewrite c HermitM CoreProg+alphaProgConsRecIdsWithR :: forall c m. ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                                        , BoundVars c, MonadCatch m, MonadUnique m )+                         => [(Maybe String,Id)] -> Rewrite c m CoreProg alphaProgConsRecIdsWithR = andR . map (uncurry alphaProgConsRecIdR) . filter (not . isExportedId . snd)   where     -- | Rename the specified identifier bound in a recursive top-level binder.  Optionally takes a suggested new name.-    alphaProgConsRecIdR :: Maybe String -> Id -> Rewrite c HermitM CoreProg+    alphaProgConsRecIdR :: Maybe String -> Id -> Rewrite c m CoreProg     alphaProgConsRecIdR mn i =  setFailMsg (wrongFormForAlpha "ProgCons (Rec bs) p") $                       do is <- progConsRecIdsT                          i' <- extractT (cloneVarAvoidingT i mn is)-                         consRecDefAnyR (\ _ -> (arr (replaceVar i i'), replaceVarR i i')) (replaceVarR i i')+                         progConsAnyR (replaceRecBindVarR i i') (replaceVarR i i')   -- | Rename the identifiers bound in the top-level binding at the head of the program with the given list of suggested names.-alphaProgConsWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [String] -> Rewrite c HermitM CoreProg+alphaProgConsWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                   => [String] -> Rewrite c m CoreProg alphaProgConsWithR ns = alphaProgConsNonRecR (listToMaybe ns)                         <+ (progConsRecIdsT >>= (alphaProgConsRecIdsWithR . zip (map Just ns)))  -- | Rename the specified variables bound in the top-level binding at the head of the program.-alphaProgConsIdsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => [Id] -> Rewrite c HermitM CoreProg+alphaProgConsIdsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+                  => [Id] -> Rewrite c m CoreProg alphaProgConsIdsR vs = alphaProgConsNonRecIdsR Nothing vs                        <+ (do bs <- progConsT (arr bindVars) successT const                               alphaProgConsRecIdsWithR (zip (repeat Nothing) (bs `intersect` vs))                           )  -- | Rename all identifiers bound in the top-level binding at the head of the program.-alphaProgConsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg+alphaProgConsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+               => Rewrite c m CoreProg alphaProgConsR = progConsIdsT >>= alphaProgConsIdsR  -----------------------------------------------------------------------  -- | Rename all identifiers bound at the top-level.-alphaProgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg+alphaProgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+           => Rewrite c m CoreProg alphaProgR = alphaProgConsR >+> progConsAllR idR alphaProgR  -----------------------------------------------------------------------  -- | Alpha rename any bindings at this node.  Note: does not rename case alternatives unless invoked on the alternative.-alphaR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core+alphaR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+       => Rewrite c m Core alphaR = setFailMsg "Cannot alpha-rename here." $            promoteExprR (alphaLamR Nothing <+ alphaCaseBinderR Nothing <+ alphaLetR)         <+ promoteAltR alphaAltR
src/HERMIT/Dictionary/Common.hs view
@@ -13,8 +13,6 @@     , callNameG     , callDataConT     , callDataConNameT-    , callsR-    , callsT       -- ** Collecting variable bindings     , progConsIdsT     , progConsRecIdsT@@ -32,11 +30,9 @@     , boundVarsT     , findBoundVarT     , findIdT-#if __GLASGOW_HASKELL__ > 706     , findVarT     , findTyConT     , findTypeT-#endif     , varBindingDepthT     , varIsOccurrenceOfT     , exprIsOccurrenceOfT@@ -63,9 +59,9 @@  ------------------------------------------------------------------------------ --- | Apply a transformation to a value in the current context.+-- | apply a transformation to a value in the current context. applyInContextT :: Transform c m a b -> a -> Transform c m x b-applyInContextT t a = contextonlyT $ \ c -> apply t c a+applyInContextT t a = contextonlyT $ \ c -> applyT t c a  -- Note: this is the same as: return a >>> t @@ -78,6 +74,7 @@                                 App {} -> return (collectArgs e)                                 _      -> fail "not an application or variable occurence." +-- | Succeeds if we are looking at an application matching the given predicate. callPredT :: Monad m => (Id -> [CoreExpr] -> Bool) -> Transform c m CoreExpr (CoreExpr, [CoreExpr]) callPredT p = do     call@(Var i, args) <- callT@@ -86,9 +83,11 @@  -- | Succeeds if we are looking at an application of given function --   returning zero or more arguments to which it is applied.-callNameT :: MonadCatch m => String -> Transform c m CoreExpr (CoreExpr, [CoreExpr])-callNameT nm = setFailMsg ("callNameT failed: not a call to '" ++ nm ++ ".") $-    callPredT (const . cmpString2Var nm)+--+-- Note: comparison is performed with cmpHN2Var.+callNameT :: MonadCatch m => HermitName -> Transform c m CoreExpr (CoreExpr, [CoreExpr])+callNameT nm = prefixFailMsg ("callNameT failed: not a call to '" ++ show nm ++ ".")+             $ callPredT (const . cmpHN2Var nm)  -- | Succeeds if we are looking at a fully saturated function call. callSaturatedT :: Monad m => Transform c m CoreExpr (CoreExpr, [CoreExpr])@@ -97,20 +96,15 @@ --       idArity is conservatively set to zero by default.  -- | Succeeds if we are looking at an application of given function-callNameG :: MonadCatch m => String -> Transform c m CoreExpr ()-callNameG nm = prefixFailMsg "callNameG failed: " $ callNameT nm >>= \_ -> constT (return ())+callNameG :: MonadCatch m => HermitName -> Transform c m CoreExpr ()+callNameG nm = prefixFailMsg "callNameG failed: " $ callNameT nm >> return ()  -- | Succeeds if we are looking at an application of a data constructor. callDataConT :: MonadCatch m => Transform c m CoreExpr (DataCon, [Type], [CoreExpr]) callDataConT = prefixFailMsg "callDataConT failed:" $-#if __GLASGOW_HASKELL__ > 706     do mb <- contextfreeT $ \ e -> let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- varSetElems (localFreeVarsExpr e) ])                                    in return $ exprIsConApp_maybe (in_scope, idUnfolding) e        maybe (fail "not a datacon application.") return mb-#else-    contextfreeT (return . exprIsConApp_maybe idUnfolding)-        >>= maybe (fail "not a datacon application.") return-#endif  -- | Succeeds if we are looking at an application of a named data constructor. callDataConNameT :: MonadCatch m => String -> Transform c m CoreExpr (DataCon, [Type], [CoreExpr])@@ -119,16 +113,6 @@     guardMsg (cmpString2Name nm (dataConName dc)) "wrong datacon."     return res --- TODO: Both callsR and callsT should be eliminated, now that we have callNameT--- | Apply a rewrite to all applications of a given function in a top-down manner, pruning on success.-callsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => String -> Rewrite c m CoreExpr -> Rewrite c m Core-callsR nm rr = prunetdR (promoteExprR $ callNameG nm >> rr)---- | Apply a translate to all applications of a given function in a top-down manner,---   pruning on success, collecting the results.-callsT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => String -> Transform c m CoreExpr b -> Transform c m Core [b]-callsT nm t = collectPruneT (promoteExprT $ callNameG nm >> t)- ------------------------------------------------------------------------------  -- | List the identifiers bound by the top-level binding group at the head of the program.@@ -200,35 +184,39 @@ boundVarsT = contextonlyT (return . boundVars)  -- | Find the unique variable bound in the context that matches the given name, failing if it is not unique.-findBoundVarT :: (BoundVars c, MonadCatch m) => String -> Transform c m a Var-findBoundVarT nm = prefixFailMsg ("Cannot resolve name " ++ nm ++ ", ") $-                        do c <- contextT-                           case varSetElems (findBoundVars nm c) of-                             []         -> fail "no matching variables in scope."-                             [v]        -> return v-                             _ : _ : _  -> fail "multiple matching variables in scope."+findBoundVarT :: (BoundVars c, MonadCatch m) => (Var -> Bool) -> Transform c m a Var+findBoundVarT p = do+    c <- contextT+    case varSetElems (findBoundVars p c) of+        []         -> fail "no matching variables in scope."+        [v]        -> return v+        _ : _ : _  -> fail "multiple matching variables in scope."  --------------------------------------------------------------------------------------------------  -- | Lookup the name in the context first, then, failing that, in GHC's global reader environment.-findIdT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a Id-findIdT nm = prefixFailMsg ("Cannot resolve name " ++ nm ++ ", ") $ contextonlyT (findId nm)+findIdT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m)+        => HermitName -> Transform c m a Id+findIdT nm = prefixFailMsg ("Cannot resolve name " ++ show nm ++ ", ") $ contextonlyT (findId nm) -#if __GLASGOW_HASKELL__ > 706 -- | Lookup the name in the context first, then, failing that, in GHC's global reader environment.-findVarT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a Var-findVarT nm = prefixFailMsg ("Cannot resolve name " ++ nm ++ ", ") $ contextonlyT (findVar nm)+findVarT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m)+         => HermitName -> Transform c m a Var+findVarT nm = prefixFailMsg ("Cannot resolve name " ++ show nm ++ ", ") $ contextonlyT (findVar nm)  -- | Lookup the name in the context first, then, failing that, in GHC's global reader environment.-findTyConT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a TyCon-findTyConT nm = prefixFailMsg ("Cannot resolve name " ++ nm ++ ", ") $ contextonlyT (findTyCon nm)+findTyConT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m)+           => HermitName -> Transform c m a TyCon+findTyConT nm = prefixFailMsg ("Cannot resolve name " ++ show nm ++ ", ") $ contextonlyT (findTyCon nm)  -- | Lookup the name in the context first, then, failing that, in GHC's global reader environment.-findTypeT :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> Transform c m a Type-findTypeT nm = prefixFailMsg ("Cannot resolve name " ++ nm ++ ", ") $ contextonlyT (findType nm)-#endif+findTypeT :: (BoundVars c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m)+          => HermitName -> Transform c m a Type+findTypeT nm = prefixFailMsg ("Cannot resolve name " ++ show nm ++ ", ") $ contextonlyT (findType nm)  -- TODO: "inScope" was defined elsewhere, but I've moved it here.  Should it be combined with the above functions?+-- Used in Dictionary.Inline to check if variables an in scope.+-- Used in Dictionary.Fold  -- | Determine whether a variable is in scope. inScope :: ReadBindings c => c -> Var -> Bool@@ -241,7 +229,7 @@  -- | Modify transformation to apply to current expression as if it were the body of a lambda binding the given variables. withVarsInScope :: (AddBindings c, ReadPath c Crumb) => [Var] -> Transform c m a b -> Transform c m a b-withVarsInScope vs t = transform $ apply t . flip (foldl (flip addLambdaBinding)) vs -- careful to add left-to-right+withVarsInScope vs t = transform $ applyT t . flip (foldl (flip addLambdaBinding)) vs -- careful to add left-to-right  ------------------------------------------------------------------------------ 
src/HERMIT/Dictionary/Composite.hs view
@@ -8,17 +8,22 @@     , bashR     , bashExtendedWithR     , bashDebugR-    )-where+    , smashR+    , smashUsingR+    , smashExtendedWithR+    ) where  import Control.Arrow +import Data.String (fromString)+ import HERMIT.Context import HERMIT.Core+import HERMIT.External import HERMIT.GHC-import HERMIT.Monad import HERMIT.Kure-import HERMIT.External+import HERMIT.Monad+import HERMIT.Name  import HERMIT.Dictionary.Debug hiding (externals) import HERMIT.Dictionary.GHC hiding (externals)@@ -31,7 +36,8 @@ externals ::  [External] externals =     [ external "unfold-basic-combinator" (promoteExprR unfoldBasicCombinatorR :: RewriteH Core)-        [ "Unfold the current expression if it is one of the basic combinators: ($), (.), id, flip, const, fst or snd." ]+        [ "Unfold the current expression if it is one of the basic combinators:"+        , "($), (.), id, flip, const, fst, snd, curry, and uncurry." ]     , external "simplify" (simplifyR :: RewriteH Core)         [ "innermost (unfold-basic-combinator <+ beta-reduce-plus <+ safe-let-subst <+ case-reduce <+ let-elim)" ]     , external "bash" (bashR :: RewriteH Core)@@ -52,16 +58,20 @@  ------------------------------------------------------------------------------------------------------ -basicCombinators :: [String]-basicCombinators = ["$",".","id","flip","const","fst","snd","curry","uncurry"]+basicCombinators :: [HermitName]+basicCombinators = map fromString ["$",".","id","flip","const","fst","snd","curry","uncurry"] --- | Unfold the current expression if it is one of the basic combinators: ('$'), ('.'), 'id', 'flip', 'const', 'fst' or 'snd'.+-- | Unfold the current expression if it is one of the basic combinators:+-- ('$'), ('.'), 'id', 'flip', 'const', 'fst', 'snd', 'curry', and 'uncurry'. --   This is intended to be used as a component of simplification traversals such as 'simplifyR' or 'bashR'.-unfoldBasicCombinatorR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr-unfoldBasicCombinatorR = setFailMsg "unfold-basic-combinator failed." $-     unfoldNamesR basicCombinators+unfoldBasicCombinatorR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                          , MonadCatch m )+                       => Rewrite c m CoreExpr+unfoldBasicCombinatorR = setFailMsg "unfold-basic-combinator failed." $ unfoldNamesR basicCombinators -simplifyR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM Core+simplifyR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+             , MonadCatch m, MonadUnique m )+          => Rewrite c m Core simplifyR = setFailMsg "Simplify failed: nothing to simplify." $     innermostR (   promoteBindR recToNonrecR                 <+ promoteExprR ( unfoldBasicCombinatorR@@ -73,80 +83,68 @@  ------------------------------------------------------------------------------------------------------ -bashR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM Core+-- | Bash is intended as a general-purpose cleanup/simplification command.+-- It performs rewrites such as let floating, case floating, and case elimination, when safe.+-- It also performs dead binding elimination and case reduction, and unfolds a number of+-- basic combinators. See 'bashComponents' for a list of rewrites performed.+-- Bash also performs occurrence analysis and de-zombification on the result, to update+-- IdInfo attributes relied-upon by GHC.+bashR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+         , MonadCatch m, MonadUnique m )+      => Rewrite c m Core bashR = bashExtendedWithR [] -bashExtendedWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [Rewrite c HermitM Core] -> Rewrite c HermitM Core+-- | An extensible bash. Given rewrites are performed before normal bash rewrites.+bashExtendedWithR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                     , MonadCatch m, MonadUnique m )+                  => [Rewrite c m Core] -> Rewrite c m Core bashExtendedWithR rs = bashUsingR (rs ++ map fst bashComponents) --smashR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM Core-smashR = smashExtendedWithR []--smashExtendedWithR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [Rewrite c HermitM Core] -> Rewrite c HermitM Core-smashExtendedWithR rs = smashUsingR (rs ++ map fst smashComponents1) (map fst smashComponents2)----- | Like bashR, but outputs name of each successful sub-rewrite, providing a log.+-- | Like 'bashR', but outputs name of each successful sub-rewrite, providing a log. -- Also performs core lint on the result of a successful sub-rewrite. -- If core lint fails, shows core fragment before and after the sub-rewrite which introduced the problem. -- Note: core fragment which fails linting is still returned! Otherwise would behave differently than bashR. -- Useful for debugging the bash command itself.-bashDebugR :: RewriteH Core-bashDebugR = bashUsingR [ idR >>= \e -> r >>> traceR nm >>> (catchM (promoteT lintExprT >> idR)-                                                                    (\s -> do _ <- return e >>> observeR "[before]"-                                                                              observeR ("[" ++ nm ++ "]\n" ++ s)))+bashDebugR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+              , HasDebugChan m, HasDynFlags m, MonadCatch m, MonadUnique m )+           => Rewrite c m Core+bashDebugR = bashUsingR [ bracketR nm r >>> catchM (promoteT lintExprT >> idR) traceR                         | (r,nm) <- bashComponents ] --- bashUsingR :: forall c m. (ExtendPath c Crumb, AddBindings c, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core--- bashUsingR rs =---     setFailMsg "bash failed: nothing to do." $---     readerT $ \ core1 -> occurAnalyseR >>> readerT (\ core2 -> if core1 `coreSyntaxEq` core2---                                                                  then bashCoreR      -- equal, no progress yet---                                                                  else tryR bashCoreR -- unequal, progress has already been made---                                                    )---   -- the changedByR combinator doesn't quite do what we need here---   where---     bashCoreR :: Rewrite c m Core---     bashCoreR = repeatR (innermostR (catchesT rs) >>> occurAnalyseR)--bashUsingR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core-bashUsingR rs =-    setFailMsg "bash failed: nothing to do." $+-- | Perform the 'bash' algorithm with a given list of rewrites.+bashUsingR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m)+           => [Rewrite c m Core] -> Rewrite c m Core+bashUsingR rs = setFailMsg "bash failed: nothing to do." $     repeatR (occurAnalyseR >>> onetdR (catchesT rs)) >+> anytdR (promoteExprR dezombifyR) >+> occurAnalyseChangedR -smashUsingR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => [Rewrite c m Core] -> [Rewrite c m Core] -> Rewrite c m Core-smashUsingR rs1 rs2 =-    setFailMsg "smash failed: nothing to do." $-    repeatR (occurAnalyseR >>> (onetdR (catchesT rs1) <+ onetdR (catchesT rs2))) >+> anytdR (promoteExprR dezombifyR) >+> occurAnalyseChangedR--- --   occurAnalyseChangedR >+> (innermostR (catchesT rs) >>> occurAnalyseR)- {- Occurrence Analysis updates meta-data, as well as performing some basic simplifications. occurAnalyseR always succeeds, whereas occurAnalyseChangedR fails is the result is syntactically equivalent. The awkwardness is because:   - we want bash to fail if nothing changes-  - we want bash to succeed if the result is not syntactically-equivalent (ideally, if any changes are made at all, but that's not the case yet)+  - we want bash to succeed if the result is not syntactically-equivalent+    (ideally, if any changes are made at all, but that's not the case yet)   - we want bash to update the meta-data   - after running bash there should be nothing left to do (i.e. an immediately subsequent bash should always fail) -Also, it's still possible for some meta-data to be out-of-date after bash, despite the case analysis.  For example, if the focal point is a case-alt rhs, this won't update the identifer info of variables bound in the alternative.+Also, it's still possible for some meta-data to be out-of-date after bash, despite the case analysis.+For example, if the focal point is a case-alt rhs, this won't update the identifer info of variables+bound in the alternative. -}  bashHelp :: [String]-bashHelp = "Iteratively apply the following rewrites until nothing changes:" : map snd (bashComponents-                                                                                         :: [(RewriteH Core,String)] -- to resolve ambiguity+bashHelp = "Iteratively apply the following rewrites until nothing changes:"+         : map snd (bashComponents :: [(RewriteH Core,String)] -- to resolve ambiguity                                                                                        )- -- TODO: Think about a good order for bash.-bashComponents :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [(Rewrite c HermitM Core, String)]+bashComponents :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                  , MonadCatch m, MonadUnique m )+               => [(Rewrite c m Core, String)] bashComponents =   [ -- (promoteExprR occurAnalyseExprChangedR, "occur-analyse-expr")    -- ??     (promoteExprR betaReduceR, "beta-reduce")                        -- O(1)   , (promoteExprR (caseReduceR True), "case-reduce")                 -- O(n)-  , (promoteExprR (caseReduceIdR True), "case-reduce-id")            -- O(n)+  , (promoteExprR (caseReduceUnfoldR True), "case-reduce-unfold")    -- O(n)   , (promoteExprR caseElimSeqR, "case-elim-seq")   , (promoteExprR unfoldBasicCombinatorR, "unfold-basic-combinator") -- O(n)   , (promoteExprR inlineCaseAlternativeR, "inline-case-alternative") -- O(n)@@ -171,6 +169,28 @@   ]  +------------------------------------------------------------------------------------------------------++-- | Smash is a more powerful but less efficient version of bash.+-- Unlike bash, smash is not concerned with whether it duplicates work,+-- and is intended for use during proving tasks.+smashR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+          , MonadCatch m, MonadUnique m )+       => Rewrite c m Core+smashR = smashExtendedWithR []++smashExtendedWithR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                      , MonadCatch m, MonadUnique m )+                   => [Rewrite c m Core] -> Rewrite c m Core+smashExtendedWithR rs = smashUsingR (rs ++ map fst smashComponents1) (map fst smashComponents2)+++smashUsingR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c, MonadCatch m) => [Rewrite c m Core] -> [Rewrite c m Core] -> Rewrite c m Core+smashUsingR rs1 rs2 =+    setFailMsg "smash failed: nothing to do." $+    repeatR (occurAnalyseR >>> (onetdR (catchesT rs1) <+ onetdR (catchesT rs2))) >+> anytdR (promoteExprR dezombifyR) >+> occurAnalyseChangedR++ smashHelp :: [String] smashHelp = "A more powerful but less efficient version of \"bash\", intended for use while proving lemmas.  Iteratively apply the following rewrites until nothing changes:" : map snd (smashComponents1 ++ smashComponents2                                                                                            :: [(RewriteH Core,String)] -- to resolve ambiguity@@ -178,12 +198,14 @@   -- | As bash, but with "let-nonrec-subst" instead of "let-nonrec-subst-safe".-smashComponents1 :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [(Rewrite c HermitM Core, String)]+smashComponents1 :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                    , MonadCatch m, MonadUnique m )+                 => [(Rewrite c m Core, String)] smashComponents1 =   [ -- (promoteExprR occurAnalyseExprChangedR, "occur-analyse-expr")    -- ??     (promoteExprR betaReduceR, "beta-reduce")                        -- O(1)   , (promoteExprR (caseReduceR True), "case-reduce")                 -- O(n)-  , (promoteExprR (caseReduceIdR True), "case-reduce-id")            -- O(n)+  , (promoteExprR (caseReduceUnfoldR True), "case-reduce-unfold")    -- O(n)   , (promoteExprR caseElimSeqR, "case-elim-seq")   , (promoteExprR unfoldBasicCombinatorR, "unfold-basic-combinator") -- O(n)   , (promoteExprR inlineCaseAlternativeR, "inline-case-alternative") -- O(n)@@ -207,14 +229,9 @@ --  , (promoteExprR dezombifyR, "dezombify")                           -- O(1) -- performed at the end   ] -smashComponents2 :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [(Rewrite c HermitM Core, String)]+smashComponents2 :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c+                    , MonadCatch m, MonadUnique m )+                 => [(Rewrite c m Core, String)] smashComponents2 =-  [-    (promoteExprR caseElimMergeAltsR, "case-elim-merge-alts") -- do this last, lest it prevent other simplifications-  ]----- (beta-reduce <+ case-reduce <+ case-reduce-id <+ case-elim-seq <+ unfold-basic-combinator <+ inline-case-alternative <+ eta-reduce <+ let-subst <+ case-float-app <+ case-float-case <+ case-float-let <+ case-float-cast <+ let-float-app <+ let-float-arg <+ let-float-lam <+ let-float-let <+ let-float-case <+ let-float-cast <+ let-float-top <+ cast-elim-refl <+ cast-elim-sym---------------------------------------------------------------------------------------------------------+    [ (promoteExprR caseElimMergeAltsR, "case-elim-merge-alts") -- do this last, lest it prevent other simplifications+    ]
src/HERMIT/Dictionary/Debug.hs view
@@ -1,48 +1,51 @@ {-# LANGUAGE FlexibleContexts #-} module HERMIT.Dictionary.Debug-       ( -- * Debugging Dictionarys-         externals-       , bracketR-       , observeR-       , observeFailureR-       , traceR-       )-where+    ( -- * Debugging Rewrites+      externals+    , bracketR+    , observeR+    , observeFailureR+    , traceR+    ) where  import Control.Arrow -import HERMIT.Kure+import HERMIT.Context+import HERMIT.Core import HERMIT.External+import HERMIT.Kure import HERMIT.Monad  -- | Exposed debugging 'External's. externals :: [External] externals = map (.+ Debug)-         [ external "trace" (traceR :: String -> RewriteH Core)-                [ "give a side-effect message as output when processing this command" ]-         , external "observe" (observeR :: String -> RewriteH Core)-                [ "give a side-effect message as output, and observe the value being processed" ]-         , external "observe-failure" (observeFailureR :: String -> RewriteH Core -> RewriteH Core)-                [ "give a side-effect message if the rewrite fails, including the failing input" ]-         , external "bracket" (bracketR :: String -> RewriteH Core -> RewriteH Core)-                [ "if given rewrite succeeds, see its input and output" ]-         ]+    [ external "trace" (traceR :: String -> RewriteH Core)+        [ "give a side-effect message as output when processing this command" ]+    , external "observe" (observeR :: String -> RewriteH Core)+        [ "give a side-effect message as output, and observe the value being processed" ]+    , external "observe-failure" (observeFailureR :: String -> RewriteH Core -> RewriteH Core)+        [ "give a side-effect message if the rewrite fails, including the failing input" ]+    , external "bracket" (bracketR :: String -> RewriteH Core -> RewriteH Core)+        [ "if given rewrite succeeds, see its input and output" ]+    ]  -- | If the 'Rewrite' fails, print out the 'Core', with a message.-observeFailureR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a+observeFailureR :: (Injection a CoreTC, ReadBindings c, ReadPath c Crumb, HasDebugChan m, MonadCatch m)+                => String -> Rewrite c m a -> Rewrite c m a observeFailureR str m = m <+ observeR str  -- | Print out the 'Core', with a message.-observeR :: Injection a CoreTC => String -> RewriteH a-observeR msg = extractR $ sideEffectR $ \ cxt core ->-        sendDebugMessage $ DebugCore msg cxt core+observeR :: (Injection a CoreTC, ReadBindings c, ReadPath c Crumb, HasDebugChan m, Monad m)+         => String -> Rewrite c m a+observeR msg = extractR $ sideEffectR $ \ cxt -> sendDebugMessage . DebugCore msg cxt  -- | Just say something, every time the rewrite is done.-traceR :: String -> RewriteH a+traceR :: (HasDebugChan m, Monad m) => String -> Rewrite c m a traceR msg = sideEffectR $ \ _ _ -> sendDebugMessage $ DebugTick msg  -- | Show before and after a rewrite.-bracketR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a+bracketR :: (Injection a CoreTC, ReadBindings c, ReadPath c Crumb, HasDebugChan m, MonadCatch m)+         => String -> Rewrite c m a -> Rewrite c m a bracketR msg rr = do     -- Be careful to only run the rr once, in case it has side effects.     (e,r) <- idR &&& attemptM rr
src/HERMIT/Dictionary/FixPoint.hs view
@@ -1,25 +1,25 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}  module HERMIT.Dictionary.FixPoint-       ( -- * Operations on the Fixed Point Operator (fix)-         -- | Note that many of these operations require 'Data.Function.fix' to be explicitly imported, if it is not used in the source file.-         HERMIT.Dictionary.FixPoint.externals-         -- ** Rewrites and BiRewrites on Fixed Points-       , fixIntroR-       , fixComputationRuleBR-       , fixRollingRuleBR-       , fixFusionRuleBR-         -- ** Utilities-       , mkFixT-       , isFixExprT-       )-where+    ( -- * Operations on the Fixed Point Operator (fix)+      HERMIT.Dictionary.FixPoint.externals+      -- ** Rewrites and BiRewrites on Fixed Points+    , fixIntroR+    , fixIntroNonRecR+    , fixIntroRecR+    , fixComputationRuleBR+    , fixRollingRuleBR+    , fixFusionRuleBR+      -- ** Utilities+    , isFixExprT+    ) where  import Control.Applicative import Control.Arrow+import Control.Monad import Control.Monad.IO.Class -import Data.Monoid (mempty)+import Data.String (fromString)  import HERMIT.Context import HERMIT.Core@@ -27,60 +27,100 @@ import HERMIT.Kure import HERMIT.External import HERMIT.GHC+import HERMIT.Name import HERMIT.ParserCore import HERMIT.Utilities  import HERMIT.Dictionary.Common-import HERMIT.Dictionary.GHC+import HERMIT.Dictionary.Function+import HERMIT.Dictionary.Kure import HERMIT.Dictionary.Reasoning import HERMIT.Dictionary.Undefined+import HERMIT.Dictionary.Unfold  --------------------------------------------------------------------------------------------------  -- | Externals for manipulating fixed points. externals ::  [External] externals =-         [ external "fix-intro" (promoteDefR fixIntroR :: RewriteH Core)-                [ "rewrite a recursive binding into a non-recursive binding using fix"-                ] .+ Introduce .+ Context-         , external "fix-computation-rule" (promoteExprBiR fixComputationRuleBR :: BiRewriteH Core)-                [ "Fixed-Point Computation Rule",-                  "fix t f  <==>  f (fix t f)"-                ] .+ Context-         , external "fix-rolling-rule" (promoteExprBiR fixRollingRuleBR :: BiRewriteH Core)-                [ "Rolling Rule",-                  "fix tyA (\\ a -> f (g a))  <==>  f (fix tyB (\\ b -> g (f b))"-                ] .+ Context-         , external "fix-fusion-rule" ((\ f g h lhsR rhsR strictf -> promoteExprBiR (fixFusionRule (Just (lhsR,rhsR)) (Just strictf) f g h)) :: CoreString -> CoreString -> CoreString -> RewriteH Core -> RewriteH Core -> RewriteH Core -> BiRewriteH Core)-                [ "Fixed-point Fusion Rule"-                , "Given f :: A -> B, g :: A -> A, h :: B -> B, and"-                , "proofs that, for some x, (f (g a) ==> x) and (h (f a) ==> x) and that f is strict, then"-                , "f (fix g) <==> fix h"-                ] .+ Context-         , external "fix-fusion-rule-unsafe" ((\ f g h lhsR rhsR -> promoteExprBiR (fixFusionRule (Just (lhsR,rhsR)) Nothing f g h)) :: CoreString -> CoreString -> CoreString -> RewriteH Core -> RewriteH Core -> BiRewriteH Core)-                [ "(Unsafe) Fixed-point Fusion Rule"-                , "Given f :: A -> B, g :: A -> A, h :: B -> B, and"-                , "a proof that, for some x, (f (g a) ==> x) and (h (f a) ==> x), then"-                , "f (fix g) <==> fix h"-                , "Note that the precondition that f is strict is required to hold."-                ] .+ Context .+ PreCondition-         , external "fix-fusion-rule-unsafe" ((\ f g h -> promoteExprBiR (fixFusionRule Nothing Nothing f g h)) :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)-                [ "(Very Unsafe) Fixed-point Fusion Rule"-                , "Given f :: A -> B, g :: A -> A, h :: B -> B, then"-                , "f (fix g) <==> fix h"-                , "Note that the preconditions that f (g a) == h (f a) and that f is strict are required to hold."-                ] .+ Context .+ PreCondition-         ]+    [ external "fix-intro" (fixIntroR :: RewriteH Core)+        [ "rewrite a function binding into a non-recursive binding using fix" ] .+ Introduce .+ Context+    , external "fix-computation-rule" (promoteExprBiR fixComputationRuleBR :: BiRewriteH Core)+        [ "Fixed-Point Computation Rule",+          "fix t f  <==>  f (fix t f)"+        ] .+ Context+    , external "fix-rolling-rule" (promoteExprBiR fixRollingRuleBR :: BiRewriteH Core)+        [ "Rolling Rule",+          "fix tyA (\\ a -> f (g a))  <==>  f (fix tyB (\\ b -> g (f b))"+        ] .+ Context+    , external "fix-fusion-rule" ((\ f g h r1 r2 strictf -> promoteExprBiR+                                                                (fixFusionRule (Just (r1,r2)) (Just strictf) f g h))+                                                                :: CoreString -> CoreString -> CoreString+                                                                    -> RewriteH Core -> RewriteH Core+                                                                    -> RewriteH Core -> BiRewriteH Core)+        [ "Fixed-point Fusion Rule"+        , "Given f :: A -> B, g :: A -> A, h :: B -> B, and"+        , "proofs that, for some x, (f (g a) ==> x) and (h (f a) ==> x) and that f is strict, then"+        , "f (fix g) <==> fix h"+        ] .+ Context+    , external "fix-fusion-rule-unsafe" ((\ f g h r1 r2 -> promoteExprBiR (fixFusionRule (Just (r1,r2)) Nothing f g h))+                                                            :: CoreString -> CoreString -> CoreString+                                                                -> RewriteH Core -> RewriteH Core -> BiRewriteH Core)+        [ "(Unsafe) Fixed-point Fusion Rule"+        , "Given f :: A -> B, g :: A -> A, h :: B -> B, and"+        , "a proof that, for some x, (f (g a) ==> x) and (h (f a) ==> x), then"+        , "f (fix g) <==> fix h"+        , "Note that the precondition that f is strict is required to hold."+        ] .+ Context .+ PreCondition+    , external "fix-fusion-rule-unsafe" ((\ f g h -> promoteExprBiR (fixFusionRule Nothing Nothing f g h))+                                                        :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)+        [ "(Very Unsafe) Fixed-point Fusion Rule"+        , "Given f :: A -> B, g :: A -> A, h :: B -> B, then"+        , "f (fix g) <==> fix h"+        , "Note that the preconditions that f (g a) == h (f a) and that f is strict are required to hold."+        ] .+ Context .+ PreCondition+    ]  -------------------------------------------------------------------------------------------------- +fixIntroR :: ( AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+             , HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+          => Rewrite c m Core+fixIntroR = promoteR fixIntroRecR <+ promoteR fixIntroNonRecR++fixIntroNonRecR :: ( AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                   , HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+                => Rewrite c m CoreBind+fixIntroNonRecR = prefixFailMsg "fix introduction failed: " $ do+    NonRec f rhs <- idR+    rhs' <- polyFixT f <<< return rhs+    return $ NonRec f rhs'+ -- |  @f = e@   ==\>   @f = fix (\\ f -> e)@-fixIntroR :: RewriteH CoreDef-fixIntroR = prefixFailMsg "fix introduction failed: " $-           do Def f _ <- idR-              f' <- constT $ cloneVarH id f-              Def f <$> (mkFixT =<< (defT mempty (extractR $ substR f $ varToCoreExpr f') (\ () e' -> Lam f' e')))+fixIntroRecR :: ( AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                , HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+             => Rewrite c m CoreDef+fixIntroRecR = prefixFailMsg "fix introduction failed: " $ do+    Def f rhs <- idR+    rhs' <- polyFixT f <<< return rhs+    return $ Def f rhs' +-- | Helper for fixIntroNonRecR and fixIntroRecR. Argument is function name.+-- Meant to be applied to RHS of function.+polyFixT :: forall c m.+            ( AddBindings c, BoundVars c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+            , HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+         => Id -> Rewrite c m CoreExpr+polyFixT f = do+    (tvs, body) <- arr collectTyBinders+    f' <- constT $ newIdH (unqualifiedName f) (exprType body)+    body' <- contextonlyT $ \ c -> do+                let constLam = mkCoreLams tvs $ varToCoreExpr f'+                    c' = addBindingGroup (NonRec f constLam)   -- we want to unfold f such as to throw away TyArgs+                       $ addBindingGroup (NonRec f' body)    c -- add f' to context so its in-scope after unfolding+                applyT (tryR (extractR (anyCallR (promoteR (unfoldPredR (const . (==f))) :: Rewrite c m Core)))) c' body+    liftM (mkCoreLams tvs) $ buildFixT $ Lam f' body'+ --------------------------------------------------------------------------------------------------  -- | @fix ty f@  \<==\>  @f (fix ty f)@@@ -129,7 +169,7 @@      rollingRuleResult :: Type -> CoreExpr -> CoreExpr -> TransformH z CoreExpr     rollingRuleResult ty f g = do x <- constT (newIdH "x" ty)-                                  mkFixT (Lam x (App f (App g (Var x))))+                                  buildFixT (Lam x (App f (App g (Var x))))      wrongFixBody :: String     wrongFixBody = "body of fix does not have the form: Lam v (App f (App g (Var v)))"@@ -141,12 +181,12 @@ -- h :: B -> B  -- | If @f@ is strict, then (@f (g a)@ == @h (f a)@)  ==\>  (@f (fix g)@ == @fix h@)-fixFusionRuleBR :: Maybe (CoreExprEqualityProof HermitC HermitM) -> Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr+fixFusionRuleBR :: Maybe (EqualityProof HermitC HermitM) -> Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr fixFusionRuleBR meq mfstrict f g h = beforeBiR   (prefixFailMsg "fixed-point fusion failed: " $-   do (tyA,tyB) <- funExprArgResTypes f-      tyA'      <- endoFunExprType g-      tyB'      <- endoFunExprType h+   do (_,tyA,tyB) <- funExprArgResTypesM f -- TODO: don't throw away TyVars+      (_,tyA')    <- endoFunExprTypeM g+      (_,tyB')    <- endoFunExprTypeM h       guardMsg (typeAlphaEq tyA tyA' && typeAlphaEq tyB tyB') "given functions do not have compatible types."       whenJust (verifyStrictT f) mfstrict       whenJust (\ eq ->@@ -167,13 +207,13 @@                        guardMsg (exprAlphaEq f f') "first argument function does not match."                        (_,g') <- isFixExprT <<< return fixg                        guardMsg (exprAlphaEq g g') "second argument function does not match."-                       mkFixT h+                       buildFixT h         fixFusionR :: RewriteH CoreExpr        fixFusionR = prefixFailMsg "(reversed) fixed-point fusion failed: " $                     do (_,h') <- isFixExprT                        guardMsg (exprAlphaEq h h') "third argument function does not match."-                       App f <$> mkFixT g+                       App f <$> buildFixT g  -- | If @f@ is strict, then (@f (g a)@ == @h (f a)@)  ==>  (@f (fix g)@ == @fix h@) fixFusionRule :: Maybe (RewriteH Core, RewriteH Core) -> Maybe (RewriteH Core) -> CoreString -> CoreString -> CoreString -> BiRewriteH CoreExpr@@ -184,24 +224,14 @@ -- | Check that the expression has the form "fix t (f :: t -> t)", returning "t" and "f". isFixExprT :: TransformH CoreExpr (Type,CoreExpr) isFixExprT = withPatFailMsg (wrongExprForm "fix t f") $ -- fix :: forall a. (a -> a) -> a-  do App (App (Var fixId) (Type ty)) f <- idR-     fixId' <- findFixId-     guardMsg (fixId == fixId') (var2String fixId ++ " does not match " ++ fixLocation)+  do (Var fixId, [Type ty, f]) <- callT+     fixId' <- findIdT fixLocation+     guardMsg (fixId == fixId') (unqualifiedName fixId ++ " does not match " ++ show fixLocation)      return (ty,f)  -------------------------------------------------------------------------------------------------- --- | f  ==>  fix f-mkFixT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => CoreExpr -> Transform c m z CoreExpr-mkFixT f = do t <- endoFunExprType f-              fixId <- findFixId-              return $ mkCoreApps (varToCoreExpr fixId) [Type t, f]--fixLocation :: String-fixLocation = "Data.Function.fix"---- TODO: will crash if 'fix' is not used (or explicitly imported) in the source file.-findFixId :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m a Id-findFixId = findIdT fixLocation+fixLocation :: HermitName+fixLocation = fromString "Data.Function.fix"  --------------------------------------------------------------------------------------------------
src/HERMIT/Dictionary/Fold.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeFamilies #-} module HERMIT.Dictionary.Fold     ( -- * Fold/Unfold Transformation       externals@@ -7,24 +8,24 @@     , stashFoldAnyR       -- * Unlifted fold interface     , fold-    , unifyTypes+    , unifyTypes -- TODO: remove in favor of GHC's unification     , tyMatchesToCoreExpr-    )--where+    ) where  import Control.Arrow import Control.Applicative import Control.Monad+import Control.Monad.IO.Class  import qualified Data.Map as Map  import HERMIT.Core import HERMIT.Context-import HERMIT.Monad-import HERMIT.Kure import HERMIT.External import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name  import HERMIT.Dictionary.Common (varBindingDepthT,inScope,findIdT) import HERMIT.Dictionary.Inline hiding (externals)@@ -35,7 +36,7 @@  externals :: [External] externals =-    [ external "fold" (promoteExprR . foldR :: String -> RewriteH Core)+    [ external "fold" (promoteExprR . foldR :: HermitName -> RewriteH Core)         [ "fold a definition"         , ""         , "double :: Int -> Int"@@ -47,7 +48,7 @@         , ""         , "Note: due to associativity, if you wanted to fold 5 + 6 + 6, "         , "you first need to apply an associativity rewrite." ]  .+ Context .+ Deep-    , external "fold-remembered" (promoteExprR . stashFoldR :: Label -> RewriteH Core)+    , external "fold-remembered" (promoteExprR . stashFoldR :: RememberedName -> RewriteH Core)         [ "Fold a remembered definition." ]                      .+ Context .+ Deep     , external "fold-any" (promoteExprR stashFoldAnyR :: RewriteH Core)         [ "Attempt to fold any of the remembered definitions." ] .+ Context .+ Deep@@ -55,26 +56,25 @@  ------------------------------------------------------------------------ -stashFoldR :: ReadBindings c => Label -> Rewrite c HermitM CoreExpr+stashFoldR :: (ReadBindings c, HasStash m, MonadCatch m) => RememberedName -> Rewrite c m CoreExpr stashFoldR label = prefixFailMsg "Fold failed: " $     transform $ \ c e -> do         Def i rhs <- lookupDef label-        guardMsg (inScope c i) $ var2String i ++ " is not in scope.\n(A common cause of this error is trying to fold a recursive call while being in the body of a non-recursive definition.  This can be resolved by calling \"nonrec-to-rec\" on the non-recursive binding group.)"+        guardMsg (inScope c i) $ unqualifiedName i ++ " is not in scope.\n(A common cause of this error is trying to fold a recursive call while being in the body of a non-recursive definition.  This can be resolved by calling \"nonrec-to-rec\" on the non-recursive binding group.)"         maybe (fail "no match.")               return               (fold i rhs e) -stashFoldAnyR :: ReadBindings c => Rewrite c HermitM CoreExpr+stashFoldAnyR :: (ReadBindings c, HasStash m, MonadCatch m) => Rewrite c m CoreExpr stashFoldAnyR = setFailMsg "Fold failed: no definitions could be folded." $-                catchesM =<< map stashFoldR <$> (Map.keys <$> constT getStash)+                catchesM =<< liftM (map stashFoldR) (liftM Map.keys (constT getStash)) -foldR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr-foldR nm = prefixFailMsg "Fold failed: " $ do-    v <- findIdT nm-    foldVarR v Nothing+foldR :: (ReadBindings c, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m)+      => HermitName -> Rewrite c m CoreExpr+foldR nm = prefixFailMsg "Fold failed: " $ findIdT nm >>= foldVarR Nothing -foldVarR :: ReadBindings c => Var -> Maybe BindingDepth -> Rewrite c HermitM CoreExpr-foldVarR v md = do+foldVarR :: (ReadBindings c, MonadCatch m, MonadUnique m) => Maybe BindingDepth -> Var -> Rewrite c m CoreExpr+foldVarR md v = do     case md of         Nothing    -> return ()         Just depth -> do depth' <- varBindingDepthT v@@ -148,7 +148,7 @@ foldMatch vs as (Var i) e | i `elem` vs = matchWithTypes vs as i e                           | otherwise   = case e of                                             Var i' | maybe False (==i) (lookup i' as) -> matchWithTypes vs as i e-                                                   | i == i' -> liftM tail $ matchWithTypes vs as i e +                                                   | i == i' -> liftM tail $ matchWithTypes vs as i e                                                                 -- note we depend on (i,e) being at front here                                                                 -- this is not strictly necessary, but is faster                                             _                -> Nothing@@ -190,7 +190,7 @@     return (x ++ tyMatchesToCoreExpr t ++ concat y)  foldMatch vs as (Cast e c) (Cast e' c') = do-    guard (coreEqCoercion c c') +    guard (coreEqCoercion c c')     foldMatch vs as e e'  foldMatch vs as (Type t1) (Type t2) = liftM tyMatchesToCoreExpr $ foldMatchType vs as t1 t2@@ -221,6 +221,10 @@               -> Type                 -- ^ expression we are checking               -> Maybe [(TyVar,Type)] -- ^ mapping of vars to types, or failure +-- look through type synonyms+foldMatchType vs as t1 t2 | Just t1' <- tcView t1 = foldMatchType vs as t1' t2+                          | Just t2' <- tcView t2 = foldMatchType vs as t1 t2'+ foldMatchType vs as (TyVarTy v) t | v `elem` vs = return [(v,t)]                                   | otherwise = case t of                                                   TyVarTy v' | maybe False (==v) (lookup v' as) -> return [(v,t)]@@ -237,7 +241,7 @@     let f ty1 ty2 | isKind ty1 && eqKind ty1 ty2 = return []                   | otherwise = foldMatchType vs as ty1 ty2     liftM concat $ zipWithM f kOrTys1 kOrTys2-    + foldMatchType vs as (FunTy ty1 ty2) (FunTy ty1' ty2') = do     x <- foldMatchType vs as ty1 ty1'     y <- foldMatchType vs as ty2 ty2'
src/HERMIT/Dictionary/Function.hs view
@@ -1,25 +1,34 @@-{-# LANGUAGE FlexibleContexts, RankNTypes #-}+{-# LANGUAGE CPP, FlexibleContexts, RankNTypes, ScopedTypeVariables #-} module HERMIT.Dictionary.Function     ( externals+    , appArgM+    , buildApplicationM+    , buildCompositionT+    , buildFixT+    , buildIdT     , staticArgR     , staticArgPosR     , staticArgPredR     , staticArgTypesR-    )-where+    ) where  import Control.Arrow+import Control.Monad.IO.Class  import Data.List (nub, intercalate, intersect, partition, transpose)+import Data.Maybe (isNothing)+import Data.String (fromString)  import HERMIT.Context import HERMIT.Core-import HERMIT.Monad-import HERMIT.Kure import HERMIT.External import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name  import HERMIT.Dictionary.Common+import HERMIT.Dictionary.GHC hiding (externals)  externals ::  [External] externals =@@ -34,15 +43,18 @@ ------------------------------------------------------------------------------------------------------  -- | Traditional Static Argument Transformation-staticArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => Rewrite c HermitM CoreDef+staticArgR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m)+           => Rewrite c m CoreDef staticArgR = staticArgPredR (return . map fst)  -- | Static Argument Transformation that only considers type arguments to be static.-staticArgTypesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => Rewrite c HermitM CoreDef+staticArgTypesR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m)+                => Rewrite c m CoreDef staticArgTypesR = staticArgPredR (return . map fst . filter (isTyVar . snd))  -- | Static Argument Transformations which requires that arguments in the given position are static.-staticArgPosR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c) => [Int] -> Rewrite c HermitM CoreDef+staticArgPosR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb, MonadCatch m, MonadUnique m)+              => [Int] -> Rewrite c m CoreDef staticArgPosR is' = staticArgPredR $ \ss' -> let is = nub is'                                                  ss = map fst ss'                                             in if is == (is `intersect` ss)@@ -50,9 +62,10 @@                                                else fail $ "args " ++ commas (filter (`notElem` ss) is) ++ " are not static."  -- | Generalized Static Argument Transformation, which allows static arguments to be filtered.-staticArgPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, HasEmptyContext c)-               => ([(Int, Var)] -> HermitM [Int]) -- ^ given list of static args and positions, decided which to transform-               -> Rewrite c HermitM CoreDef+staticArgPredR :: forall c m. (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadPath c Crumb+                              , MonadCatch m, MonadUnique m)+               => ([(Int, Var)] -> m [Int]) -- ^ given list of static args and positions, decided which to transform+               -> Rewrite c m CoreDef staticArgPredR decide = prefixFailMsg "static-arg failed: " $ do     Def f rhs <- idR     let (bnds, body) = collectBinders rhs@@ -60,9 +73,11 @@     contextonlyT $ \ c -> do         let bodyContext = foldl (flip addLambdaBinding) c bnds -        -- TODO: we convert an Id to string here, and callsT then uses cmpString2Var-        --       refactor to avoid intermediate string!-        callPats <- apply (callsT (var2String f) (callT >>> arr snd)) bodyContext (ExprCore body)+            callPatsT :: Transform c m CoreExpr [[CoreExpr]]+            callPatsT = extractT $ collectPruneT+                            (promoteExprT $ callPredT (const . (== f)) >>> arr snd :: Transform c m Core [CoreExpr])++        callPats <- applyT callPatsT bodyContext body         let argExprs = transpose callPats             numCalls = length callPats             allBinds = zip [0..] bnds@@ -92,17 +107,91 @@             $ "type variables in args " ++ commas (nub $ map fst unboundTys) ++ " would become unbound unless args "               ++ commas (nub $ map snd unboundTys) ++ " are included in the transformation." -        wkr <- newIdH (var2String f ++ "'") (exprType (mkCoreLams dbnds body))+        wkr <- newIdH (unqualifiedName f ++ "'") (exprType (mkCoreLams dbnds body))          let replaceCall :: Monad m => Rewrite c m CoreExpr             replaceCall = do-                (_,exprs) <- callT+                (_,exprs) <- callPredT (const . (== f))                 return $ mkApps (Var wkr) [ e | (p,e) <- zip [0..] exprs, (p::Int) `elem` ps ] -        ExprCore body' <- apply (callsR (var2String f) replaceCall) bodyContext (ExprCore body)+        body' <- applyT (extractR $ prunetdR (promoteExprR replaceCall :: Rewrite c m Core)) bodyContext body          return $ Def f $ mkCoreLams bnds $ Let (Rec [(wkr, mkCoreLams dbnds body')])                                              $ mkApps (Var wkr) (varsToCoreExprs dbnds) +------------------------------------------------------------------------------++-- | Get the nth argument of an application. Arg 0 is the function being applied.+appArgM :: Monad m => Int -> CoreExpr -> m CoreExpr+appArgM n e | n < 0     = fail "appArgM: arg must be non-negative"+            | otherwise = let (fn,args) = collectArgs e+                              l = fn : args+                          in if n > length args+                             then fail "appArgM: not enough arguments"+                             else return $ l !! n++-- | Build composition of two functions.+buildCompositionT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m)+                  => CoreExpr -> CoreExpr -> Transform c m x CoreExpr+buildCompositionT f g = do+    composeId <- findIdT $ fromString "Data.Function.."+    fDot <- buildApplicationM (varToCoreExpr composeId) f+    buildApplicationM fDot g++-- | Given expression for f and for x, build f x, figuring out the type arguments.+buildApplicationM :: (HasDynFlags m, MonadCatch m, MonadIO m) => CoreExpr -> CoreExpr -> m CoreExpr+buildApplicationM f x = do+    (vsF, domF, _) <- splitFunTypeM (exprType f)+    let (vsX, xTy) = splitForAllTys (exprType x)+        allTvs = vsF ++ vsX+        bindFn v = if v `elem` allTvs then BindMe else Skolem++    sub <- maybe (do d <- getDynFlags+                     liftIO $ putStrLn $ "f: " ++ showPpr d f+                     liftIO $ putStrLn $ "x: " ++ showPpr d x+                     liftIO $ putStrLn $ "vsF: " ++ showPpr d vsF+                     liftIO $ putStrLn $ "domF: " ++ showPpr d domF+                     liftIO $ putStrLn $ "vsX: " ++ showPpr d vsX+                     liftIO $ putStrLn $ "xTy: " ++ showPpr d xTy+                     fail "buildApplicationM - domain of f and type of x do not unify")+                 return+                 (tcUnifyTys bindFn [domF] [xTy])++    f' <- substOrApply f [ (v, Type $ substTyVar sub v) | v <- vsF ]+    x' <- substOrApply x [ (v, Type $ substTyVar sub v) | v <- vsX ]+    let vs = [ v | v <- vsF ++ vsX, isNothing $ lookupTyVar sub v ]  -- things we should stick back on as foralls+    -- TODO: make sure vsX don't capture anything in f'+    --       and vsF' doesn't capture anything in x'+    return $ mkCoreLams vs $ mkCoreApp f' x'++-- | Given expression for f, build fix f.+buildFixT :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+          => CoreExpr -> Transform c m x CoreExpr+buildFixT f = do+    (tvs, ty) <- endoFunExprTypeM f+    fixId <- findIdT $ fromString "Data.Function.fix"+    f' <- substOrApply f [ (v, varToCoreExpr v) | v <- tvs ]+    return $ mkCoreLams tvs $ mkCoreApps (varToCoreExpr fixId) [Type ty, f']++-- | Build an expression that is the monomorphic id function for given type.+buildIdT :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+         => Type -> Transform c m x CoreExpr+buildIdT ty = do+    idId <- findIdT $ fromString "Data.Function.id"+    return $ mkCoreApp (varToCoreExpr idId) (Type ty)++------------------------------------------------------------------------------+ commas :: Show a => [a] -> String commas = intercalate "," . map show++-- | Like mkCoreApps, but automatically beta-reduces when possible.+substOrApply :: Monad m => CoreExpr -> [(Var,CoreExpr)] -> m CoreExpr+substOrApply e         []         = return e+substOrApply (Lam b e) ((v,ty):r) = if b == v+                                    then substOrApply e r >>= return . substCoreExpr b ty+                                    else fail $ "substOrApply: unexpected binder - "+                                                ++ unqualifiedName b ++ " - " ++ unqualifiedName v+substOrApply e         rest       = return $ mkCoreApps e (map snd rest)++------------------------------------------------------------------------------
src/HERMIT/Dictionary/GHC.hs view
@@ -1,42 +1,47 @@ {-# LANGUAGE CPP, FlexibleContexts #-} module HERMIT.Dictionary.GHC-       ( -- * GHC-based Transformations-         -- | This module contains transformations that are reflections of GHC functions, or derived from GHC functions.-         externals-         -- ** Substitution-       , substR-       , substCoreAlt-       , substCoreExpr-         -- ** Utilities- --      , inScope-       , dynFlagsT-       , arityOf-         -- ** Lifted GHC capabilities-         -- A zombie is an identifer that has 'OccInfo' 'IAmDead', but still has occurrences.-       , lintExprT-       , lintModuleT-       , occurAnalyseR-       , occurAnalyseChangedR-       , occurAnalyseExprChangedR-       , occurAnalyseAndDezombifyR-       , dezombifyR-       )-where+    ( -- * GHC-based Transformations+     -- | This module contains transformations that are reflections of GHC functions, or derived from GHC functions.+     externals+     -- ** Substitution+    , substR+    , substCoreAlt+    , substCoreExpr+     -- ** Utilities+    --      , inScope+    , dynFlagsT+    , arityOf+     -- ** Lifted GHC capabilities+     -- A zombie is an identifer that has 'OccInfo' 'IAmDead', but still has occurrences.+    , lintExprT+    , lintModuleT+    , occurAnalyseR+    , occurAnalyseChangedR+    , occurAnalyseExprChangedR+    , occurAnalyseAndDezombifyR+    , dezombifyR+    , buildDictionary+    , buildDictionaryT+    , buildTypeable+    ) where  import qualified Bag import qualified CoreLint -import Control.Arrow--import Data.List (mapAccumL)+import           Control.Arrow+import           Control.Monad.IO.Class -import HERMIT.Core-import HERMIT.Context-import HERMIT.Kure-import HERMIT.External-import HERMIT.GHC+import           Data.Char (isSpace)+import           Data.List (mapAccumL) -import HERMIT.Dictionary.Debug hiding (externals)+import           HERMIT.Core+import           HERMIT.Context+import           HERMIT.Dictionary.Debug hiding (externals)+import           HERMIT.External+import           HERMIT.GHC+import           HERMIT.Kure+import           HERMIT.Monad+import           HERMIT.Name  ------------------------------------------------------------------------ @@ -125,11 +130,7 @@ lintModuleT =   do dynFlags <- dynFlagsT      bnds     <- arr mg_binds-#if __GLASGOW_HASKELL__ > 706      let (warns, errs)    = CoreLint.lintCoreBindings [] bnds -- [] are vars to treat as in scope, used by GHCi-#else-     let (warns, errs)    = CoreLint.lintCoreBindings bnds-#endif          dumpSDocs endMsg = Bag.foldBag (\ d r -> d ++ ('\n':r)) (showSDoc dynFlags) endMsg      if Bag.isEmptyBag errs        then return $ dumpSDocs "Core Lint Passed" warns@@ -143,11 +144,7 @@ lintExprT = transform $ \ c e -> do     dflags <- getDynFlags     maybe (return "Core Lint Passed") (fail . showSDoc dflags)-#if __GLASGOW_HASKELL__ > 706                  $ CoreLint.lintExpr (varSetElems $ boundVars c) e-#else-                 $ CoreLint.lintUnfolding noSrcLoc (varSetElems $ boundVars c) e-#endif  ------------------------------------------- @@ -168,13 +165,23 @@  -- | Apply 'occurAnalyseExprR' to all sub-expressions. occurAnalyseR :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, HasEmptyContext c, MonadCatch m) => Rewrite c m Core-occurAnalyseR = let r  = promoteExprR (arr occurAnalyseExpr)+occurAnalyseR = let r  = promoteExprR (arr occurAnalyseExpr_NoBinderSwap) -- See Note [No Binder Swap]                     go = r <+ anyR go                  in tryR go -- always succeed +{-+  Note [No Binder Swap]++  The binder swap performed by occurrence analysis in GHC <= 7.8.3 is buggy+  in that it can lead to unintended variable capture (Trac #9440). Concretely,+  this will send bash into a loop, or cause core lint to fail. As this is an+  un-expected change as far as HERMIT users are concerned anyway, we use the+  version that doesn't perform the binder swap.+-}+ -- | Occurrence analyse an expression, failing if the result is syntactically equal to the initial expression. occurAnalyseExprChangedR :: MonadCatch m => Rewrite c m CoreExpr-occurAnalyseExprChangedR = changedByR exprSyntaxEq (arr occurAnalyseExpr)+occurAnalyseExprChangedR = changedByR exprSyntaxEq (arr occurAnalyseExpr_NoBinderSwap) -- See Note [No Binder Swap]  -- | Occurrence analyse all sub-expressions, failing if the result is syntactically equal to the initial expression. occurAnalyseChangedR :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, HasEmptyContext c, MonadCatch m) => Rewrite c m Core@@ -198,3 +205,37 @@ -}  ----------------------------------------------------------------------++-- TODO: this is mostly an example, move somewhere?+buildTypeable :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => Type -> m (Id, [CoreBind])+buildTypeable ty = do+    evar <- runTcM $ do+        cls <- tcLookupClass typeableClassName+        let predTy = mkClassPred cls [typeKind ty, ty] -- recall that Typeable is now poly-kinded+        newWantedEvVar predTy+    buildDictionary evar++-- | Build a dictionary for the given+buildDictionary :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => Id -> m (Id, [CoreBind])+buildDictionary evar = do+    (i, bs) <- runTcM $ do+        loc <- getCtLoc $ GivenOrigin UnkSkol+        let predTy = varType evar+            nonC = mkNonCanonical $ CtWanted { ctev_pred = predTy, ctev_evar = evar, ctev_loc = loc }+            wCs = mkFlatWC [nonC]+        (wCs', bnds) <- solveWantedsTcM wCs+        reportAllUnsolved wCs'+        return (evar, bnds)+    bnds <- runDsM $ dsEvBinds bs+    return (i,bnds)++buildDictionaryT :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadUnique m)+                 => Transform c m Type CoreExpr+buildDictionaryT = prefixFailMsg "buildDictionaryT failed: " $ contextfreeT $ \ ty -> do+    dflags <- getDynFlags+    binder <- newIdH ("$d" ++ zEncodeString (filter (not . isSpace) (showPpr dflags ty))) ty+    (i,bnds) <- buildDictionary binder+    guardMsg (notNull bnds) "no dictionary bindings generated."+    return $ case bnds of+                [NonRec v e] | i == v -> e -- the common case that we would have gotten a single non-recursive let+                _ -> mkCoreLets bnds (varToCoreExpr i)
src/HERMIT/Dictionary/Induction.hs view
@@ -17,6 +17,7 @@ import HERMIT.GHC import HERMIT.Kure import HERMIT.Monad+import HERMIT.Name -- import HERMIT.Utilities (soleElement)  import HERMIT.Dictionary.Common@@ -30,7 +31,7 @@  ------------------------------------------------------------------------------ -inductionCaseSplit :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb) +inductionCaseSplit :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb)                    => [Var] -> Id -> CoreExpr -> CoreExpr -> Transform c HermitM x [(Maybe DataCon,[Var],CoreExpr,CoreExpr)] inductionCaseSplit vs i lhsE rhsE =     do -- first construct an expression containing both the LHS and the RHS
src/HERMIT/Dictionary/Inline.hs view
@@ -1,40 +1,30 @@ {-# LANGUAGE CPP, TupleSections, FlexibleContexts, ScopedTypeVariables #-} module HERMIT.Dictionary.Inline-         ( -- * Inlining-           externals-         , InlineConfig(..)-         , CaseBinderInlineOption(..)-         , getUnfoldingT-         , ensureBoundT-         , inlineR-         , inlineNameR-         , inlineNamesR-         , inlineMatchingPredR-         , inlineCaseScrutineeR-         , inlineCaseAlternativeR-         , configurableInlineR-         , inlineTargetsT-         )--where--#if __GLASGOW_HASKELL__ > 706-#else-import TcType (tcSplitDFunTy)-#endif+    ( -- * Inlining+      externals+    , InlineConfig(..)+    , CaseBinderInlineOption(..)+    , getUnfoldingT+    , ensureBoundT+    , inlineR+    , inlineNameR+    , inlineNamesR+    , inlineMatchingPredR+    , inlineCaseScrutineeR+    , inlineCaseAlternativeR+    , configurableInlineR+    , inlineTargetsT+    ) where  import Control.Arrow-import Control.Applicative import Control.Monad -import Data.List (intercalate)- import HERMIT.Context import HERMIT.Core import HERMIT.External import HERMIT.GHC import HERMIT.Kure-import HERMIT.Monad+import HERMIT.Name  import HERMIT.Dictionary.Common @@ -43,17 +33,17 @@ -- | 'External's for inlining variables. externals :: [External] externals =-            [ external "inline" (promoteExprR inlineR :: RewriteH Core)-                [ "(Var v) ==> <defn of v>" ].+ Eval .+ Deep-            , external "inline" (promoteExprR . inlineNameR :: String -> RewriteH Core)-                [ "Given a specific v, (Var v) ==> <defn of v>" ] .+ Eval .+ Deep-            , external "inline" (promoteExprR . inlineNamesR :: [String] -> RewriteH Core)-                [ "If the current variable matches any of the given names, then inline it." ] .+ Eval .+ Deep-            , external "inline-case-scrutinee" (promoteExprR inlineCaseScrutineeR :: RewriteH Core)-                [ "if v is a case binder, replace (Var v) with the bound case scrutinee." ] .+ Eval .+ Deep-            , external "inline-case-alternative" (promoteExprR inlineCaseAlternativeR :: RewriteH Core)-                [ "if v is a case binder, replace (Var v) with the bound case-alternative pattern." ] .+ Eval .+ Deep .+ Unsafe-            ]+    [ external "inline" (promoteExprR inlineR :: RewriteH Core)+        [ "(Var v) ==> <defn of v>" ].+ Eval .+ Deep+    , external "inline" (promoteExprR . inlineMatchingPredR . mkOccPred :: OccurrenceName -> RewriteH Core)+        [ "Given a specific v, (Var v) ==> <defn of v>" ] .+ Eval .+ Deep+    , external "inline" (promoteExprR . inlineNamesR :: [String] -> RewriteH Core)+        [ "If the current variable matches any of the given names, then inline it." ] .+ Eval .+ Deep+    , external "inline-case-scrutinee" (promoteExprR inlineCaseScrutineeR :: RewriteH Core)+        [ "if v is a case binder, replace (Var v) with the bound case scrutinee." ] .+ Eval .+ Deep+    , external "inline-case-alternative" (promoteExprR inlineCaseAlternativeR :: RewriteH Core)+        [ "if v is a case binder, replace (Var v) with the bound case-alternative pattern." ] .+ Eval .+ Deep .+ Unsafe+    ]  ------------------------------------------------------------------------ @@ -62,37 +52,50 @@ data InlineConfig           = CaseBinderOnly CaseBinderInlineOption | AllBinders deriving (Eq, Show)  -- | If the current variable matches the given name, then inline it.-inlineNameR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => String -> Rewrite c HermitM CoreExpr+inlineNameR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+               , ReadBindings c, HasEmptyContext c, MonadCatch m )+            => String -> Rewrite c m CoreExpr inlineNameR nm = inlineMatchingPredR (cmpString2Var nm)  -- | If the current variable matches any of the given names, then inline it.-inlineNamesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [String] -> Rewrite c HermitM CoreExpr+inlineNamesR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                , ReadBindings c, HasEmptyContext c, MonadCatch m )+             => [String] -> Rewrite c m CoreExpr inlineNamesR []  = fail "inline-names failed: no names given." inlineNamesR nms = inlineMatchingPredR (\ v -> any (flip cmpString2Var v) nms)  -- | If the current variable satisifies the predicate, then inline it.-inlineMatchingPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => (Id -> Bool) -> Rewrite c HermitM CoreExpr+inlineMatchingPredR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                       , ReadBindings c, HasEmptyContext c, MonadCatch m )+                    => (Id -> Bool) -> Rewrite c m CoreExpr inlineMatchingPredR idPred = configurableInlineR AllBinders (arr $ idPred)  -- | Inline the current variable.-inlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+inlineR :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c,+            ReadBindings c, ReadPath c Crumb, MonadCatch m )+        => Rewrite c m CoreExpr inlineR = configurableInlineR AllBinders (return True)  -- | Inline the current identifier if it is a case binder, using the scrutinee rather than the case-alternative pattern.-inlineCaseScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+inlineCaseScrutineeR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                        , ReadBindings c, HasEmptyContext c, MonadCatch m )+                     => Rewrite c m CoreExpr inlineCaseScrutineeR = configurableInlineR (CaseBinderOnly Scrutinee) (return True)  -- | Inline the current identifier if is a case binder, using the case-alternative pattern rather than the scrutinee.-inlineCaseAlternativeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+inlineCaseAlternativeR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                          , ReadBindings c, HasEmptyContext c, MonadCatch m )+                       => Rewrite c m CoreExpr inlineCaseAlternativeR = configurableInlineR (CaseBinderOnly Alternative) (return True)  -- | The implementation of inline, an important transformation. -- This *only* works if the current expression has the form @Var v@ (it does not traverse the expression). -- It can trivially be prompted to more general cases using traversal strategies.-configurableInlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c)+configurableInlineR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c+                       , ReadPath c Crumb, MonadCatch m )                     => InlineConfig-                    -> (Transform c HermitM Id Bool) -- ^ Only inline identifiers that satisfy this predicate.-                    -> Rewrite c HermitM CoreExpr+                    -> (Transform c m Id Bool) -- ^ Only inline identifiers that satisfy this predicate.+                    -> Rewrite c m CoreExpr configurableInlineR config p =    prefixFailMsg "Inline failed: " $    do b <- varT p@@ -106,8 +109,8 @@ -- Fails, listing unbound variables if not. ensureBoundT :: (Monad m, ReadBindings c) => Transform c m CoreExpr () ensureBoundT = do-    unbound <- transform $ \ c -> return . filter (not . inScope c) . varSetElems . localFreeVarsExpr-    guardMsg (null unbound) $ "the following variables are unbound: " ++ intercalate ", " (map getOccString unbound)+    unbound <- transform $ \ c -> return . filterVarSet (not . inScope c) . localFreeVarsExpr+    guardMsg (isEmptyVarSet unbound) $ "the following variables are unbound: " ++ showVarSet unbound  -- NOTE: When inlining, we have to take care to avoid variable capture. --       Our approach is to track the binding depth of the inlined identifier.@@ -136,29 +139,25 @@      all uncaptured `liftM` extractT collectDepthsT  -- | Return the unfolding of an identifier, and a predicate over the binding depths of all variables within that unfolding to determine if they have been captured in their new location.-getUnfoldingT :: ReadBindings c+getUnfoldingT :: (ReadBindings c, MonadCatch m)               => InlineConfig-              -> Transform c HermitM Id (CoreExpr, BindingDepth -> Bool)+              -> Transform c m Id (CoreExpr, BindingDepth -> Bool) getUnfoldingT config = transform $ \ c i ->     case lookupHermitBinding i c of       Nothing -> do requireAllBinders config                     let uncaptured = (<= 0) -- i.e. is global-		    -- this check is necessary because idInfo panics on TyVars, though it-		    -- should never be the case that a type variable is NOT in the context,-		    -- at least this will give a reasonable error message, instead of a GHC panic.-		    guardMsg (isId i) "type variable is not in Env (this should not happen)."+                    -- This check is necessary because idInfo panics on TyVars. Type variables should+                    -- ALWAYS be in the context (so we should never be in this branch), but at least this+                    -- will give a reasonable error message if something goes wrong, instead of a GHC panic.+                    guardMsg (isId i) "type variable is not in Env (this should not happen)."                     case unfoldingInfo (idInfo i) of                       CoreUnfolding { uf_tmpl = uft } -> return (uft, uncaptured)-#if __GLASGOW_HASKELL__ > 706-                      dunf@(DFunUnfolding {})         -> (,uncaptured) <$> dFunExpr dunf-#else-                      DFunUnfolding _arity dc args    -> (,uncaptured) <$> dFunExpr dc args (idType i)-#endif+                      dunf@(DFunUnfolding {})         -> liftM (,uncaptured) $ dFunExpr dunf                       _                               -> fail $ "cannot find unfolding in Env or IdInfo."       Just b -> let depth = hbDepth b                 in case hbSite b of                           CASEBINDER s alt -> let tys             = tyConAppArgs (idType i)-                                                  altExprDepthM   = (, (<= depth+1)) <$> alt2Exp tys alt+                                                  altExprDepthM   = liftM (, (<= depth+1)) $ alt2Exp tys alt                                                   scrutExprDepthM = return (s, (< depth))                                                in case config of                                                     CaseBinderOnly Scrutinee   -> scrutExprDepthM@@ -200,44 +199,14 @@ alt2Exp tys (DataAlt dc, vs) = return $ mkCoreConApps dc (map Type tys ++ map (varToCoreExpr . zapVarOccInfo) vs)  -- | Get list of possible inline targets. Used by shell for completion.-inlineTargetsT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Transform c HermitM Core [String]-inlineTargetsT = collectT $ promoteT $ whenM (testM inlineR) (varT $ arr var2String)+inlineTargetsT :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                  , ReadBindings c, HasEmptyContext c, MonadCatch m )+               => Transform c m Core [String]+inlineTargetsT = collectT $ promoteT $ whenM (testM inlineR) (varT $ arr unqualifiedName)  -- | Build a CoreExpr for a DFunUnfolding-#if __GLASGOW_HASKELL__ > 706-{--data Unfolding-  = ...-  | DFunUnfolding {     -- The Unfolding of a DFunId-                -- See Note [DFun unfoldings]-                --     df = /\a1..am. \d1..dn. MkD t1 .. tk-                        --                                 (op1 a1..am d1..dn)-                    --                                 (op2 a1..am d1..dn)-        df_bndrs :: [Var],      -- The bound variables [a1..m],[d1..dn]-        df_con   :: DataCon,    -- The dictionary data constructor (never a newtype datacon)-        df_args  :: [CoreExpr]  -- Args of the data con: types, superclasses and methods,-    }                           -- in positional order--}-dFunExpr :: Unfolding -> HermitM CoreExpr--- TODO: is this correct?-dFunExpr dunf@(DFunUnfolding {}) = return $ mkCoreConApps (df_con dunf) (df_args dunf)+dFunExpr :: Monad m => Unfolding -> m CoreExpr+dFunExpr dunf@(DFunUnfolding {}) = return $ mkCoreLams (df_bndrs dunf) $ mkCoreConApps (df_con dunf) (df_args dunf) dFunExpr _ = fail "dFunExpr: not a DFunUnfolding"-#else-dFunExpr :: DataCon -> [DFunArg CoreExpr] -> Type -> HermitM CoreExpr-dFunExpr dc args ty = do-    let (_, _, _, tcArgs) = tcSplitDFunTy ty-        (forallTvs, ty')  = splitForAllTys ty-        (argTys, _resTy)  = splitFunTys ty'--    ids <- mapM (uncurry newIdH) $ zip [ [ch] | ch <- cycle ['a'..'z'] ] argTys-    vars <- mapM (cloneVarH id) forallTvs--    let allVars = varsToCoreExprs $ vars ++ ids--        mkArg (DFunLamArg i) = allVars !! i-        mkArg (DFunPolyArg e) = mkCoreApps e allVars--    return $ mkCoreConApps dc $ map Type tcArgs ++ map mkArg args-#endif  ------------------------------------------------------------------------
src/HERMIT/Dictionary/Kure.hs view
@@ -1,11 +1,11 @@ {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}  module HERMIT.Dictionary.Kure-       ( -- * KURE Strategies-         externals-       , anyCallR-       )-where+    ( -- * KURE Strategies+      externals+    , anyCallR+    , betweenR+    ) where  import Control.Arrow import Control.Monad (liftM)@@ -98,6 +98,8 @@        [ "Promote a RewriteCore to a RewriteCoreTC" ]    , external "extract"    (extractR :: RewriteH CoreTC -> RewriteH Core)        [ "Extract a RewriteCore from a RewriteCoreTC" ]+   , external "between"    (betweenR :: Int -> Int -> RewriteH CoreTC -> RewriteH CoreTC)+       [ "between x y rr -> perform rr at least x times and at most y times." ]    ]  ------------------------------------------------------------------------------------@@ -137,3 +139,14 @@           rec = anyCallR rr  ------------------------------------------------------------------------------------++-- | betweenR x y rr -> perform rr at least x times and at most y times.+betweenR :: MonadCatch m => Int -> Int -> Rewrite c m a -> Rewrite c m a+betweenR l h rr | l < 0 = fail "betweenR: lower limit below zero"+                | h < l = fail "betweenR: upper limit less than lower limit"+                | otherwise = go 0+    where -- 'c' is number of times rr has run already+          go c | c >= h = idR               -- done+               | c < l  = rr >>> go (c+1)   -- haven't hit lower bound yet+               | otherwise = tryR (rr >>> go (c+1))  -- met lower bound+
src/HERMIT/Dictionary/Local.hs view
@@ -1,37 +1,36 @@ {-# LANGUAGE FlexibleContexts #-}  module HERMIT.Dictionary.Local-       ( -- * Local Structural Manipulations-         HERMIT.Dictionary.Local.externals-         -- ** Binding Groups-       , module HERMIT.Dictionary.Local.Bind-         -- ** Case Expressions-       , module HERMIT.Dictionary.Local.Case-         -- ** Cast Expressions-       , module HERMIT.Dictionary.Local.Cast-         -- ** Let Expressions-       , module HERMIT.Dictionary.Local.Let-         -- ** Miscellaneous-       , abstractR-       , pushR-       , betaReduceR-       , betaReducePlusR-       , betaExpandR-       , etaReduceR-       , etaExpandR-       , multiEtaExpandR-       , flattenModuleR-       , flattenProgramR-       , flattenProgramT-       )-where+    ( -- * Local Structural Manipulations+      HERMIT.Dictionary.Local.externals+      -- ** Binding Groups+    , module HERMIT.Dictionary.Local.Bind+      -- ** Case Expressions+    , module HERMIT.Dictionary.Local.Case+      -- ** Cast Expressions+    , module HERMIT.Dictionary.Local.Cast+      -- ** Let Expressions+    , module HERMIT.Dictionary.Local.Let+      -- ** Miscellaneous+    , abstractR+    , pushR+    , betaReduceR+    , betaExpandR+    , etaReduceR+    , etaExpandR+    , multiEtaExpandR+    , flattenModuleR+    , flattenProgramR+    , flattenProgramT+    ) where  import HERMIT.Core import HERMIT.Context-import HERMIT.Kure-import HERMIT.Monad import HERMIT.External import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name import HERMIT.Utilities  import HERMIT.Dictionary.Common@@ -57,8 +56,6 @@         [ "((\\ v -> E1) E2) ==> let v = E2 in E1"         , "This form of beta-reduction is safe if E2 is an arbitrary expression"         , "(won't duplicate work)." ]                                 .+ Eval .+ Shallow-    , external "beta-reduce-plus" (promoteExprR betaReducePlusR :: RewriteH Core)-        [ "Perform one or more beta-reductions."]                               .+ Eval .+ Shallow     , external "beta-expand" (promoteExprR betaExpandR :: RewriteH Core)         [ "(let v = e1 in e2) ==> (\\ v -> e2) e1" ]                            .+ Shallow     , external "eta-reduce" (promoteExprR etaReduceR :: RewriteH Core)@@ -71,7 +68,7 @@     , external "flatten-program" (promoteProgR flattenProgramR :: RewriteH Core)         [ "Flatten all the top-level binding groups in a program (list of binding groups) to a single"         , "recursive binding group.  This can be useful if you intend to apply GHC RULES." ]-    , external "abstract" (promoteExprR . abstractR :: String -> RewriteH Core)+    , external "abstract" (promoteExprR . abstractR . mkOccPred :: OccurrenceName -> RewriteH Core)         [ "Abstract over a variable using a lambda."         , "e  ==>  (\\ x -> e) x" ]                                             .+ Shallow .+ Introduce .+ Context     , external "push" ((\ nm strictf -> push (Just strictf) (cmpString2Var nm)) :: String -> RewriteH Core -> RewriteH Core)@@ -96,49 +93,6 @@     do App (Lam v e1) e2 <- idR        return $ Let (NonRec v e2) e1 --multiBetaReduceR :: MonadCatch m =>  (Int -> Bool) -> Rewrite c m CoreExpr-multiBetaReduceR p = prefixFailMsg "Multi-Beta-Reduce failed: " $-    do-        e <- idR-        let (f,xs) = collectArgs e-        guardMsg (p (length xs)) "incorrect number of arguments."--        let (vs,e0) = collectBinders f--        guardMsg (length vs >= length xs) "insufficent lambdas."--        let (vs1,vs2) = splitAt (length xs) vs--        return-           $ mkLets (zipWith NonRec vs1 xs)-           $ mkLams vs2 e0---- TODO: inline this everywhere--- Neil: Are we sure we want to inline this?--- | Perform one or more beta-reductions.-betaReducePlusR :: MonadCatch m => Rewrite c m CoreExpr-betaReducePlusR = multiBetaReduceR (> 0)--{---        tagFailR "betaReducePlus failed." $-        appT liftLambda idR App >>> beta_reduce-  where-          -- lift lambda finds the (perhaps hidden) lambda, and brings it out-          liftLambda = observeR "pre-liftLambda" >>> liftLambda' >>> observeR "post-liftLambda"-          liftLambda' =-                   (do e@(Lam {}) <- idR-                       return e)-                <+ (betaReducePlus-                        >>> observeR "liftLambda(UP)"-                            -- let v = e in ...-                            -- TODO: check scope here-                        >>> (do Let bds (Lam v e) <- idR-                                return (Lam v (Let bds e)))-                   )--}- -- | (let v = e1 in e2) ==> (\\ v -> e2) e1 betaExpandR :: MonadCatch m => Rewrite c m CoreExpr betaExpandR = setFailMsg ("Beta-expansion failed: " ++ wrongExprForm "Let (NonRec v e1) e2") $@@ -158,7 +112,7 @@                                Nothing -> fail "the argument expression is not a type variable."                                Just v2 -> guardMsg (v1 == v2) "type variables are not equal."                   _       -> fail "the argument expression is not a variable."-               guardMsg (v1 `notElemVarSet` freeVarsExpr f) $ var2String v1 ++ " is free in the function being applied."+               guardMsg (v1 `notElemVarSet` freeVarsExpr f) $ unqualifiedName v1 ++ " is free in the function being applied."                return f  -- | e1 ==> (\\ v -> e1 v)@@ -199,12 +153,13 @@  -- | Abstract over a variable using a lambda. --   e  ==>  (\ x. e) x-abstractR :: (ReadBindings c) => String -> Rewrite c HermitM CoreExpr-abstractR nm = prefixFailMsg "abstraction failed: " $-   do v  <- findBoundVarT nm-      v' <- constT (cloneVarH id v) -- currently uses the same visible name (via "id").  We could do something else here, e.g. add a prime suffix.+abstractR :: (ReadBindings c, MonadCatch m, MonadUnique m) => (Var -> Bool) -> Rewrite c m CoreExpr+abstractR p = prefixFailMsg "abstraction failed: " $+   do v  <- findBoundVarT p+      v' <- constT (cloneVarH id v) -- currently uses the same visible name (via "id").+                                    -- We could do something else here, e.g. add a prime suffix.       e  <- arr (substCoreExpr v (varToCoreExpr v'))-      return $ App (Lam v' e) (varToCoreExpr v)+      return $ mkCoreApp (Lam v' e) (varToCoreExpr v)  ------------------------------------------------------------------------------------------------------ 
src/HERMIT/Dictionary/Local/Bind.hs view
@@ -1,10 +1,9 @@ module HERMIT.Dictionary.Local.Bind-       ( -- * Rewrites on Binding Groups-         externals-       , nonrecToRecR-       , recToNonrecR-       )-where+    ( -- * Rewrites on Binding Groups+      externals+    , nonrecToRecR+    , recToNonrecR+    ) where  import HERMIT.Core import HERMIT.External@@ -41,7 +40,7 @@ recToNonrecR = prefixFailMsg "Converting singleton recursive binding to non-recursive binding failed: " $                withPatFailMsg (wrongExprForm "Rec [Def v e]") $   do Rec [(v,e)] <- idR-     guardMsg (v `notElemVarSet` freeIdsExpr e) ("'" ++ uqName v ++ " is recursively defined.")+     guardMsg (v `notElemVarSet` freeIdsExpr e) ("'" ++ unqualifiedName v ++ " is recursively defined.")      return (NonRec v e)  ------------------------------------------------------------------------------
src/HERMIT/Dictionary/Local/Case.hs view
@@ -5,6 +5,7 @@       externals     , caseFloatAppR     , caseFloatArgR+    , caseFloatArgLemmaR     , caseFloatCaseR     , caseFloatCastR     , caseFloatLetR@@ -15,7 +16,7 @@     , caseReduceR     , caseReduceDataconR     , caseReduceLiteralR-    , caseReduceIdR+    -- , caseReduceIdR     , caseReduceUnfoldR     , caseSplitR     , caseSplitInlineR@@ -28,29 +29,32 @@     , caseElimMergeAltsR     , caseIntroSeqR     , caseElimSeqR-    )-where+    ) where -import Data.List-import Data.Monoid import Control.Arrow import Control.Applicative+import Control.Monad+import Control.Monad.IO.Class +import Data.List+import Data.Monoid+ import HERMIT.Core import HERMIT.Context-import HERMIT.Monad-import HERMIT.Kure-import HERMIT.GHC import HERMIT.External-import HERMIT.Utilities+import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name import HERMIT.ParserCore+import HERMIT.Utilities  import HERMIT.Dictionary.Common import HERMIT.Dictionary.Inline hiding (externals) import HERMIT.Dictionary.AlphaConversion hiding (externals) import HERMIT.Dictionary.Fold (foldVarR) import HERMIT.Dictionary.GHC (substCoreExpr)-import HERMIT.Dictionary.Undefined (verifyStrictT)+import HERMIT.Dictionary.Undefined (verifyStrictT, buildStrictnessLemmaT) import HERMIT.Dictionary.Unfold (unfoldR)  -- NOTE: these are hard to test in small examples, as GHC does them for us, so use with caution@@ -60,30 +64,33 @@ externals :: [External] externals =     [ external "case-float-app" (promoteExprR caseFloatAppR :: RewriteH Core)-        [ "(case ec of alt -> e) v ==> case ec of alt -> e v" ]              .+ Commute .+ Shallow+        [ "(case ec of alt -> e) v ==> case ec of alt -> e v" ] .+ Commute .+ Shallow     , external "case-float-arg" ((\ strict -> promoteExprR (caseFloatArg Nothing (Just strict))) :: RewriteH Core -> RewriteH Core)         [ "Given a proof that f is strict, then"-        , "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow+        , "f (case s of alt -> e) ==> case s of alt -> f e" ]   .+ Commute .+ Shallow     , external "case-float-arg" ((\ f strict -> promoteExprR (caseFloatArg (Just f) (Just strict))) :: CoreString -> RewriteH Core -> RewriteH Core)         [ "For a specified f, given a proof that f is strict, then"-        , "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow+        , "f (case s of alt -> e) ==> case s of alt -> f e" ]   .+ Commute .+ Shallow     , external "case-float-arg-unsafe" ((\ f -> promoteExprR (caseFloatArg (Just f) Nothing)) :: CoreString -> RewriteH Core)         [ "For a specified f,"-        , "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow .+ PreCondition+        , "f (case s of alt -> e) ==> case s of alt -> f e" ]   .+ Commute .+ Shallow .+ PreCondition .+ Strictness     , external "case-float-arg-unsafe" (promoteExprR (caseFloatArg Nothing Nothing) :: RewriteH Core)-        [ "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow .+ PreCondition+        [ "f (case s of alt -> e) ==> case s of alt -> f e" ]   .+ Commute .+ Shallow .+ PreCondition .+ Strictness+    , external "case-float-arg-lemma" (promoteExprR . caseFloatArgLemmaR :: LemmaName -> RewriteH Core)+        [ "f (case s of alt -> e) ==> case s of alt -> f e"+        , "Generates a lemma with given name for strictness side condition on f." ] .+ Commute .+ Shallow .+ PreCondition .+ Strictness     , external "case-float-case" (promoteExprR caseFloatCaseR :: RewriteH Core)         [ "case (case ec of alt1 -> e1) of alta -> ea ==> case ec of alt1 -> case e1 of alta -> ea" ] .+ Commute .+ Eval     , external "case-float-cast" (promoteExprR caseFloatCastR :: RewriteH Core)         [ "cast (case s of p -> e) co ==> case s of p -> cast e co" ]        .+ Shallow .+ Commute     , external "case-float-let" (promoteExprR caseFloatLetR :: RewriteH Core)-        [ "let v = case ec of alt1 -> e1 in e ==> case ec of alt1 -> let v = e1 in e" ] .+ Commute .+ Shallow+        [ "let v = case ec of alt1 -> e1 in e ==> case ec of alt1 -> let v = e1 in e" ] .+ Commute .+ Shallow .+ Strictness     , external "case-float" (promoteExprR caseFloatR :: RewriteH Core)-        [ "case-float = case-float-app <+ case-float-case <+ case-float-let <+ case-float-cast" ]    .+ Commute .+ Shallow+        [ "case-float = case-float-app <+ case-float-case <+ case-float-let <+ case-float-cast" ] .+ Commute .+ Shallow .+ Strictness     , external "case-float-in" (promoteExprR caseFloatInR :: RewriteH Core)         [ "Float in a Case whatever the context." ]                             .+ Commute .+ Shallow .+ PreCondition     , external "case-float-in-args" (promoteExprR caseFloatInArgsR :: RewriteH Core)-        [ "Float in a Case whose alternatives are parallel applications of the same function." ] .+ Commute .+ Shallow .+ PreCondition+        [ "Float in a Case whose alternatives are parallel applications of the same function." ] .+ Commute .+ Shallow .+ PreCondition .+ Strictness     -- , external "case-float-in-app" (promoteExprR caseFloatInApp :: RewriteH Core)     --     [ "Float in a Case whose alternatives are applications of different functions with the same arguments." ] .+ Commute .+ Shallow .+ PreCondition     , external "case-reduce" (promoteExprR (caseReduceR True) :: RewriteH Core)@@ -95,21 +102,19 @@     , external "case-reduce-literal" (promoteExprR (caseReduceLiteralR True) :: RewriteH Core)         [ "Case of Known Constructor"         , "case L of L -> e ==> e" ]                                         .+ Shallow .+ Eval-    , external "case-reduce-id" (promoteExprR (caseReduceIdR True) :: RewriteH Core)-        [ "Inline the case scrutinee (if it is an identifier) and then case-reduce." ] .+ Shallow .+ Eval .+ Context     , external "case-reduce-unfold" (promoteExprR (caseReduceUnfoldR True) :: RewriteH Core)-        [ "Unfold the case scrutinee (if it is a function application) and then case-reduce." ] .+ Shallow .+ Eval .+ Context+        [ "Unfold the case scrutinee and then case-reduce." ] .+ Shallow .+ Eval .+ Context     , external "case-split" (promoteExprR . caseSplitR . cmpString2Var :: String -> RewriteH Core)         [ "case-split 'x"-        , "e ==> case x of C1 vs -> e; C2 vs -> e, where x is free in e" ] .+ Shallow+        , "e ==> case x of C1 vs -> e; C2 vs -> e, where x is free in e" ] .+ Shallow .+ Strictness     , external "case-split-inline" (promoteExprR . caseSplitInlineR . cmpString2Var :: String -> RewriteH Core)         [ "Like case-split, but additionally inlines the matched constructor "-        , "applications for all occurances of the named variable." ] .+ Deep+        , "applications for all occurances of the named variable." ] .+ Deep .+ Strictness     , external "case-intro-seq" (promoteExprR . caseIntroSeqR . cmpString2Var :: String -> RewriteH Core)         [ "Force evaluation of a variable by introducing a case."-        , "case-seq 'v is is equivalent to adding @(seq v)@ in the source code." ] .+ Shallow .+ Introduce+        , "case-intro-seq 'v is is equivalent to adding @(seq v)@ in the source code." ] .+ Shallow .+ Introduce .+ Strictness     , external "case-elim-seq" (promoteExprR caseElimSeqR :: RewriteH Core)-        [ "Eliminate a case that corresponds to a pointless seq."  ] .+ Deep .+ Eval+        [ "Eliminate a case that corresponds to a pointless seq."  ] .+ Deep .+ Eval .+ Strictness     , external "case-inline-alternative" (promoteExprR caseInlineAlternativeR :: RewriteH Core)         [ "Inline the case binder as the case-alternative pattern everywhere in the case alternatives." ] .+ Deep     , external "case-inline-scrutinee" (promoteExprR caseInlineScrutineeR :: RewriteH Core)@@ -122,7 +127,7 @@         [ "A cleverer version of 'mergeCaseAlts' that first attempts to"         , "abstract out any occurrences of the alternative pattern using the case binder." ] .+ Deep     , external "case-elim" (promoteExprR caseElimR :: RewriteH Core)-        [ "case s of w; C vs -> e ==> e if w and vs are not free in e" ]     .+ Shallow+        [ "case s of w; C vs -> e ==> e if w and vs are not free in e" ]     .+ Shallow .+ Strictness     , external "case-elim-inline-scrutinee" (promoteExprR caseElimInlineScrutineeR :: RewriteH Core)         [ "Eliminate a case, inlining any occurrences of the case binder as the scrutinee." ] .+ Deep     , external "case-elim-merge-alts" (promoteExprR caseElimMergeAltsR :: RewriteH Core)@@ -135,7 +140,7 @@ ------------------------------------------------------------------------------  -- | case s of w; C vs -> e ==> e if w and vs are not free in e-caseElimR :: Rewrite c HermitM CoreExpr+caseElimR :: MonadCatch m => Rewrite c m CoreExpr caseElimR = prefixFailMsg "Case elimination failed: " $             withPatFailMsg (wrongExprForm "Case s bnd ty alts") $  do Case _ bnd _ alts <- idR@@ -148,10 +153,11 @@ ------------------------------------------------------------------------------  -- | (case s of alt1 -> e1; alt2 -> e2) v ==> case s of alt1 -> e1 v; alt2 -> e2 v-caseFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m)+              => Rewrite c m CoreExpr caseFloatAppR = prefixFailMsg "Case floating from App function failed: " $   do-    captures    <- appT (map mkVarSet <$> caseAltVarsT) (arr freeVarsExpr) (flip (map . intersectVarSet))+    captures    <- appT (liftM (map mkVarSet) caseAltVarsT) (arr freeVarsExpr) (flip (map . intersectVarSet))     bndrCapture <- appT caseBinderIdT (arr freeVarsExpr) elemVarSet     appT ((if not bndrCapture then idR else alphaCaseBinderR Nothing)           >>> caseAllR idR idR idR (\i -> if isEmptyVarSet (captures !! i) then idR else alphaAltR)@@ -169,9 +175,10 @@  -- | @f (case s of alt1 -> e1; alt2 -> e2)@ ==> @case s of alt1 -> f e1; alt2 -> f e2@ --   Only safe if @f@ is strict.-caseFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c)-              => Maybe CoreExpr -> Maybe (Rewrite c HermitM CoreExpr) -- ^ Maybe the function to float past, and maybe a proof of its strictness.-              -> Rewrite c HermitM CoreExpr+caseFloatArgR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c+                 , HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+              => Maybe CoreExpr -> Maybe (Rewrite c m CoreExpr) -- ^ Maybe the function to float past, and maybe a proof of its strictness.+              -> Rewrite c m CoreExpr caseFloatArgR mf mstrict = prefixFailMsg "Case floating from App argument failed: " $                            withPatFailMsg "App f (Case s w ty alts)" $   do App f (Case s w _ alts) <- idR@@ -191,39 +198,41 @@                                                                              )                                                        ) >>> caseFloatArgR Nothing Nothing --- caseFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, HasGlobalRdrEnv c)---               => Maybe (CoreExpr, Maybe (Rewrite c HermitM CoreExpr)) -- ^ Maybe the function to float past, and maybe a proof of its strictness.---               -> Rewrite c HermitM CoreExpr--- caseFloatArgR mfstrict = prefixFailMsg "Case floating from App argument failed: " $---                          withPatFailMsg "App f (Case s w ty alts)" $---   do App f (Case s w _ alts) <- idR---      whenJust (\ (f', mstrict) ->---                      do guardMsg (exprAlphaEq f f') "given function does not match current application."---                         whenJust (verifyStrictT f) mstrict---               )---               mfstrict+-- | @f (case s of alt1 -> e1; alt2 -> e2)@ ==> @case s of alt1 -> f e1; alt2 -> f e2@+--   Only safe if @f@ is strict, so introduces a lemma to prove.+caseFloatArgLemmaR :: ( AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, HasHermitMEnv m+                      , HasHscEnv m, HasDynFlags m, HasLemmas m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+                   => LemmaName -> Rewrite c m CoreExpr+caseFloatArgLemmaR nm = prefixFailMsg "Case floating from application argument failed: " $+                        withPatFailMsg "App f (Case s w ty alts)" $ do+    App f (Case s w _ alts) <- idR ---      let fvs         = freeVarsExpr f---          altCaptures = map (intersectVarSet fvs . mkVarSet . altVars) alts---          bndrCapture = elemVarSet w fvs+    let fvs         = freeVarsExpr f+        altCaptures = map (intersectVarSet fvs . mkVarSet . altVars) alts+        bndrCapture = elemVarSet w fvs ---      if | bndrCapture                   -> appAllR idR (alphaCaseBinderR Nothing) >>> caseFloatArgR Nothing---         | all isEmptyVarSet altCaptures -> let new_alts = mapAlts (App f) alts---                                             in return $ Case s w (coreAltsType new_alts) new_alts---         | otherwise                     -> appAllR idR (caseAllR idR idR idR (\ n -> let vs = varSetElems (altCaptures !! n)---                                                                                       in if null vs then idR else alphaAltVarsR vs---                                                                              )---                                                        ) >>> caseFloatArgR Nothing+    if | bndrCapture ->+            appAllR idR (alphaCaseBinderR Nothing) >>> caseFloatArgR Nothing Nothing+       | all isEmptyVarSet altCaptures -> do+            let new_alts = mapAlts (App f) alts+            buildStrictnessLemmaT nm f+            return $ Case s w (coreAltsType new_alts) new_alts+       | otherwise ->+            appAllR idR (caseAllR idR idR idR (\ n -> let vs = varSetElems (altCaptures !! n)+                                                      in if null vs then idR else alphaAltVarsR vs+                                              )+                        ) >>> caseFloatArgR Nothing Nothing  -- | case (case s1 of alt11 -> e11; alt12 -> e12) of alt21 -> e21; alt22 -> e22 --   ==> --   case s1 of --     alt11 -> case e11 of alt21 -> e21; alt22 -> e22 --     alt12 -> case e12 of alt21 -> e21; alt22 -> e22-caseFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m)+               => Rewrite c m CoreExpr caseFloatCaseR = prefixFailMsg "Case floating from Case failed: " $   do-    captures <- caseT (map mkVarSet <$> caseAltVarsT) idR mempty (const $ arr freeVarsAlt) (\ vss w () fvs -> map (intersectVarSet (delVarSet (unionVarSets fvs) w)) vss)+    captures <- caseT (liftM (map mkVarSet) caseAltVarsT) idR mempty (const $ arr freeVarsAlt) (\ vss w () fvs -> map (intersectVarSet (delVarSet (unionVarSets fvs) w)) vss)     -- does the binder of the inner case, shadow a free variable in any of the outer case alts?     bndrCapture <- caseT caseBinderIdT idR mempty (const $ arr freeVarsAlt) (\ innerBndr w () fvs -> innerBndr `elemVarSet` (delVarSet (unionVarSets fvs) w))     caseT ((if not bndrCapture then idR else alphaCaseBinderR Nothing)@@ -235,7 +244,8 @@           (\ (Case s1 b1 _ alts1) b2 ty alts2 -> Case s1 b1 ty $ mapAlts (\s -> Case s b2 ty alts2) alts1)  -- | let v = case s of alt1 -> e1 in e ==> case s of alt1 -> let v = e1 in e-caseFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m)+              => Rewrite c m CoreExpr caseFloatLetR = prefixFailMsg "Case floating from Let failed: " $   do vs <- letNonRecT idR caseAltVarsT mempty (\ letVar caseVars () -> letVar `elem` concat caseVars)      let bdsAction = if not vs then idR else nonRecAllR idR alphaCaseR@@ -252,7 +262,8 @@  -- | caseFloatR = caseFloatAppR <+ caseFloatCaseR <+ caseFloatLetR <+ caseFloatCastR --   Note: does NOT include caseFloatArg-caseFloatR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m)+           => Rewrite c m CoreExpr caseFloatR = setFailMsg "Unsuitable expression for Case floating." $     caseFloatAppR <+ caseFloatCaseR <+ caseFloatLetR <+ caseFloatCastR @@ -288,20 +299,18 @@  ------------------------------------------------------------------------------ --- | Inline the case scrutinee (if it is an identifier), and then perform case reduction.---   If first argument is True, perform substitution in RHS, if False, build let expressions.-caseReduceIdR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Bool -> Rewrite c HermitM CoreExpr-caseReduceIdR subst = caseAllR inlineR idR idR (const idR) >>> caseReduceR subst---- | Inline the case scrutinee (if it is an identifier), and then perform case reduction.+-- | Unfold the case scrutinee and then perform case reduction. --   If first argument is True, perform substitution in RHS, if False, build let expressions.-caseReduceUnfoldR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Bool -> Rewrite c HermitM CoreExpr+caseReduceUnfoldR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                     , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                  => Bool -> Rewrite c m CoreExpr caseReduceUnfoldR subst = caseAllR unfoldR idR idR (const idR) >>> caseReduceR subst  -- | Case of Known Constructor. --   Eliminate a case if the scrutinee is a data constructor or a literal. --   If first argument is True, perform substitution in RHS, if False, build let expressions.-caseReduceR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Bool -> Rewrite c HermitM CoreExpr+caseReduceR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m)+            => Bool -> Rewrite c m CoreExpr caseReduceR subst =     setFailMsg "Unsuitable expression for Case reduction." $     caseReduceDataconR subst <+ caseReduceLiteralR subst@@ -315,12 +324,8 @@     prefixFailMsg "Case reduction failed: " $     withPatFailMsg (wrongExprForm "Case (Lit l) v t alts") $ do         Case s bndr _ alts <- idR-#if __GLASGOW_HASKELL__ > 706         let in_scope = mkInScopeSet (localFreeVarsExpr s)         case exprIsLiteral_maybe (in_scope, idUnfolding) s of-#else-        case exprIsLiteral_maybe idUnfolding s of-#endif             Nothing -> fail "scrutinee is not a literal."             Just l  -> do guardMsg (not (litIsLifted l)) "cannot case-reduce lifted literals" -- see Trac #5603                           case findAlt (LitAlt l) alts of@@ -332,19 +337,17 @@ -- | Case of Known Constructor. --   Eliminate a case if the scrutinee is a data constructor. --   If first argument is True, perform substitution in RHS, if False, build let expressions.-caseReduceDataconR :: forall c. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Bool -> Rewrite c HermitM CoreExpr+caseReduceDataconR :: forall c m. ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                                  , ReadBindings c, MonadCatch m, MonadUnique m )+                   => Bool -> Rewrite c m CoreExpr caseReduceDataconR subst = prefixFailMsg "Case reduction failed: " $                            withPatFailMsg (wrongExprForm "Case e v t alts") go     where-        go :: Rewrite c HermitM CoreExpr+        go :: Rewrite c m CoreExpr         go = do             Case e bndr _ alts <- idR-#if __GLASGOW_HASKELL__ > 706             let in_scope = mkInScopeSet (localFreeVarsExpr e)             case exprIsConApp_maybe (in_scope, idUnfolding) e of-#else-            case exprIsConApp_maybe idUnfolding e of-#endif                 Nothing                -> fail "head of scrutinee is not a data constructor."                 Just (dc, univTys, es) -> case findAlt (DataAlt dc) alts of                     Nothing             -> fail "no matching alternative."@@ -367,12 +370,12 @@ -- e ==> case i of i --         []     -> e --         (a:as) -> e-caseSplitR :: (Id -> Bool) -> Rewrite c HermitM CoreExpr+caseSplitR :: (MonadCatch m, MonadUnique m) => (Id -> Bool) -> Rewrite c m CoreExpr caseSplitR idPred = prefixFailMsg "caseSplit failed: " $                do i            <- matchingFreeIdT idPred                   (tycon, tys) <- splitTyConAppM (idType i)                   let aNms     = map (:[]) $ cycle ['a'..'z']-                  contextfreeT $ \ e -> do dcsAndVars <- mapM (\ dc -> (dc,) <$> sequence [ newIdH a ty | (a,ty) <- zip aNms $ dataConInstArgTys dc tys ])+                  contextfreeT $ \ e -> do dcsAndVars <- mapM (\ dc -> liftM (dc,) (sequence [ newIdH a ty | (a,ty) <- zip aNms $ dataConInstArgTys dc tys ]))                                                               (tyConDataCons tycon)                                            w <- cloneVarH (++ "'") i                                            let e' = substCoreExpr i (Var w) e@@ -384,7 +387,7 @@ -- -- e -> case v of v --        _ -> e-caseIntroSeqR :: (Id -> Bool) -> Rewrite c HermitM CoreExpr+caseIntroSeqR :: (MonadCatch m, MonadUnique m) => (Id -> Bool) -> Rewrite c m CoreExpr caseIntroSeqR idPred = prefixFailMsg "case-intro-seq failed: " $              do i <- matchingFreeIdT idPred                 contextfreeT $ \ e -> do guardMsg (not $ isTyCoArg e) "cannot case on a type or coercion."@@ -406,25 +409,33 @@ -- for each occurance of the named variable. -- -- > caseSplitInline idPred = caseSplit idPred >>> caseInlineAlternativeR-caseSplitInlineR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => (Id -> Bool) -> Rewrite c HermitM CoreExpr+caseSplitInlineR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                    , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                 => (Id -> Bool) -> Rewrite c m CoreExpr caseSplitInlineR idPred = caseSplitR idPred >>> caseInlineAlternativeR  ------------------------------------------------------------------------------ -caseInlineBinderR :: forall c. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => CaseBinderInlineOption -> Rewrite c HermitM CoreExpr+caseInlineBinderR :: forall c m. ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                                 , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                  => CaseBinderInlineOption -> Rewrite c m CoreExpr caseInlineBinderR opt =   do w <- caseBinderIdT      caseAllR idR idR idR $ \ _ -> setFailMsg "no inlinable occurrences." $                                    do depth <- varBindingDepthT w-                                      extractR $ anybuR (promoteExprR (configurableInlineR (CaseBinderOnly opt) (varIsOccurrenceOfT w depth)) :: Rewrite c HermitM Core)+                                      extractR $ anybuR (promoteExprR (configurableInlineR (CaseBinderOnly opt) (varIsOccurrenceOfT w depth)) :: Rewrite c m Core)  -- | Inline the case binder as the case scrutinee everywhere in the case alternatives.-caseInlineScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+caseInlineScrutineeR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                        , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                     => Rewrite c m CoreExpr caseInlineScrutineeR = prefixFailMsg "case-inline-scrutinee failed: " $                        caseInlineBinderR Scrutinee  -- | Inline the case binder as the case-alternative pattern everywhere in the case alternatives.-caseInlineAlternativeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+caseInlineAlternativeR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                          , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                       => Rewrite c m CoreExpr caseInlineAlternativeR = prefixFailMsg "case-inline-alternative failed: " $                          caseInlineBinderR Alternative @@ -444,31 +455,42 @@                     return $ Case e w ty [(DEFAULT,[],head rhss)]  -- | In the case alternatives, fold any occurrences of the case alt patterns to the case binder.-caseFoldBinderR :: forall c.  (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+caseFoldBinderR :: forall c m. ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                               , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                => Rewrite c m CoreExpr caseFoldBinderR = prefixFailMsg "case-fold-binder failed: " $ do     w <- caseBinderIdT     caseAllR idR idR idR $ \ _ -> do depth <- varBindingDepthT w-                                     extractR $ anybuR (promoteExprR (foldVarR w (Just depth)) :: Rewrite c HermitM Core)+                                     extractR $ anybuR (promoteExprR (foldVarR (Just depth) w) :: Rewrite c m Core)  -- | A cleverer version of 'mergeCaseAlts' that first attempts to abstract out any occurrences of the alternative pattern using the case binder.-caseMergeAltsWithBinderR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+caseMergeAltsWithBinderR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                            , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                         => Rewrite c m CoreExpr caseMergeAltsWithBinderR =     prefixFailMsg "merge-case-alts-with-binder failed: " $     withPatFailMsg (wrongExprForm "Case e w ty alts") $     tryR caseFoldBinderR >>> caseMergeAltsR  -- | Eliminate a case, inlining any occurrences of the case binder as the scrutinee.-caseElimInlineScrutineeR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+caseElimInlineScrutineeR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                            , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                         => Rewrite c m CoreExpr caseElimInlineScrutineeR = alphaCaseBinderR Nothing >>> tryR caseInlineScrutineeR >>> caseElimR --- | Eliminate a case, merging the case alternatives into a single default alternative and inlining the case binder as the scrutinee (if possible).-caseElimMergeAltsR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+-- | Eliminate a case, merging the case alternatives into a single default alternative+-- and inlining the case binder as the scrutinee (if possible).+caseElimMergeAltsR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                      , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+                   => Rewrite c m CoreExpr caseElimMergeAltsR = tryR caseFoldBinderR >>> tryR caseMergeAltsR >>> caseElimInlineScrutineeR  ------------------------------------------------------------------------------  -- | Eliminate a case that corresponds to a pointless 'seq'.-caseElimSeqR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr+caseElimSeqR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c+                , ReadBindings c, HasEmptyContext c, MonadCatch m, MonadUnique m )+             => Rewrite c m CoreExpr caseElimSeqR = prefixFailMsg "case-elim-seq failed: " $                withPatFailMsg "not a seq case." $   do Case s w _ [(DEFAULT,[],rhs)] <- idR
src/HERMIT/Dictionary/Local/Cast.hs view
@@ -70,11 +70,7 @@                 withPatFailMsg (wrongExprForm "App (Cast e1 co) e2") $     do App (Cast e1 co) e2 <- idR        case co of-#if __GLASGOW_HASKELL__ > 706             TyConAppCo _r t [c1, c2] -> do-#else-            TyConAppCo t [c1, c2] -> do-#endif                 True <- return (isFunTyCon t)                 return $ Cast (App e1 (Cast e2 (SymCo c1))) c2             ForAllCo t c2 -> do@@ -82,14 +78,12 @@                 return (Cast (App e1 e2) (Coercion.substCo (Coercion.extendTvSubst emptyCvSubst t x') c2))             _ -> fail "castFloatApp" -#if __GLASGOW_HASKELL__ > 706 -- | Attempts to tease a coercion apart into a type constructor and the application -- of a number of coercion arguments to that constructor splitTyConAppCo_maybe :: Coercion -> Maybe (TyCon, [Coercion]) splitTyConAppCo_maybe (Refl ro ty)          = (fmap . second . map) (Refl ro) (splitTyConApp_maybe ty) splitTyConAppCo_maybe (TyConAppCo _r tc cs) = Just (tc, cs) splitTyConAppCo_maybe _                     = Nothing-#endif  -- TODO: revisit castElimSymPlusR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr
src/HERMIT/Dictionary/Local/Let.hs view
@@ -1,48 +1,49 @@ {-# LANGUAGE FlexibleContexts, ScopedTypeVariables, MultiWayIf, LambdaCase #-}  module HERMIT.Dictionary.Local.Let-       ( -- * Rewrites on Let Expressions-         externals-         -- ** Let Elimination-       , letNonRecSubstR-       , letNonRecSubstSafeR-       , letSubstR-       , letSubstSafeR-       , letElimR-       , letNonRecElimR-       , letRecElimR-       , progBindElimR-       , progBindNonRecElimR-       , progBindRecElimR-         -- ** Let Introduction-       , letIntroR-       , letNonRecIntroR-       , progNonRecIntroR-       , nonRecIntroR-       , letIntroUnfoldingR-         -- ** Let Floating Out-       , letFloatAppR-       , letFloatArgR-       , letFloatLetR-       , letFloatLamR-       , letFloatCaseR-       , letFloatCastR-       , letFloatExprR-       , letFloatTopR-         -- ** Let Floating In-       , letFloatInR-       , letFloatInAppR-       , letFloatInCaseR-       , letFloatInLamR-         -- ** Miscallaneous-       , reorderNonRecLetsR-       , letTupleR-       , letToCaseR-       )-where+    ( -- * Rewrites on Let Expressions+      externals+      -- ** Let Elimination+    , letNonRecSubstR+    , letNonRecSubstSafeR+    , letSubstR+    , letSubstSafeR+    , letElimR+    , letNonRecElimR+    , letRecElimR+    , progBindElimR+    , progBindNonRecElimR+    , progBindRecElimR+      -- ** Let Introduction+    , letIntroR+    , letNonRecIntroR+    , progNonRecIntroR+    , nonRecIntroR+    , letIntroUnfoldingR+      -- ** Let Floating Out+    , letFloatAppR+    , letFloatArgR+    , letFloatLetR+    , letFloatLamR+    , letFloatCaseR+    , letFloatCaseAltR+    , letFloatCastR+    , letFloatExprR+    , letFloatTopR+      -- ** Let Floating In+    , letFloatInR+    , letFloatInAppR+    , letFloatInCaseR+    , letFloatInLamR+      -- ** Miscallaneous+    , reorderNonRecLetsR+    , letTupleR+    , letToCaseR+    ) where  import Control.Arrow import Control.Monad+import Control.Monad.IO.Class  import Data.List import Data.Monoid@@ -53,6 +54,7 @@ import HERMIT.Kure import HERMIT.External import HERMIT.GHC+import HERMIT.Name import HERMIT.Utilities  import HERMIT.Dictionary.Common@@ -83,7 +85,7 @@     --     , "only matches non-recursive lets" ]  .+ Deep .+ Eval     , external "let-intro" (promoteExprR . letIntroR :: String -> RewriteH Core)         [ "e => (let v = e in v), name of v is provided" ]                      .+ Shallow .+ Introduce-    , external "let-intro-unfolding" (promoteExprR . letIntroUnfoldingR :: String -> RewriteH Core)+    , external "let-intro-unfolding" (promoteExprR . letIntroUnfoldingR :: HermitName -> RewriteH Core)         [ "e => let f' = defn[f'/f] in e[f'/f], name of f is provided" ]     , external "let-elim" (promoteExprR letElimR :: RewriteH Core)         [ "Remove an unused let binding."@@ -102,6 +104,13 @@         [ "let v = (let w = ew in ev) in e ==> let w = ew in let v = ev in e" ] .+ Commute .+ Shallow     , external "let-float-case" (promoteExprR letFloatCaseR :: RewriteH Core)         [ "case (let v = ev in e) of ... ==> let v = ev in case e of ..." ]     .+ Commute .+ Shallow .+ Eval+    , external "let-float-case-alt" (promoteExprR (letFloatCaseAltR Nothing) :: RewriteH Core)+        [ "case s of { ... ; p -> let v = ev in e ; ... } "+        , "==> let v = ev in case s of { ... ; p -> e ; ... } " ]               .+ Commute .+ Shallow .+ Eval+    , external "let-float-case-alt" (promoteExprR . letFloatCaseAltR . Just :: Int -> RewriteH Core)+        [ "Float a let binding from specified alternative."+        , "case s of { ... ; p -> let v = ev in e ; ... } "+        , "==> let v = ev in case s of { ... ; p -> e ; ... } " ]               .+ Commute .+ Shallow .+ Eval     , external "let-float-cast" (promoteExprR letFloatCastR :: RewriteH Core)         [ "cast (let bnds in e) co ==> let bnds in cast e co" ]                 .+ Commute .+ Shallow     , external "let-float-top" (promoteProgR letFloatTopR :: RewriteH Core)@@ -157,6 +166,29 @@     do Let (NonRec v rhs) body <- idR        return (substCoreExpr v rhs body) +{-+TODO: This was written very early in the project by Andy.+      It was later modified somewhat by Neil, but without reassessing the heurisitc as a whole.+      It may need revisiting.++Safe Subst Heuristic+--------------------++Substitution is safe if (A) OR (B) OR (C).++(A) The let-bound variable is a type or coercion.++(B) The let-bound value is either:+      (i)   a variable;+      (ii)  a lambda;+      (iii) an application that requires more value arguments before it can perform any computation.++(C) In the body, the let-bound variable must NOT occur:+      (i)  more than once;+      (ii) inside a lambda.++-}+ -- | Currently we always substitute types and coercions, and use a heuristic to decide whether to substitute expressions. --   This may need revisiting. letNonRecSubstSafeR :: forall c m. (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, ReadBindings c, HasEmptyContext c, MonadCatch m) => Rewrite c m CoreExpr@@ -270,7 +302,8 @@ -------------------------------------------------------------------------------------------  -- | @let v = ev in e@ ==> @case ev of v -> e@-letToCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+letToCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m, MonadUnique m)+           => Rewrite c m CoreExpr letToCaseR = prefixFailMsg "Converting Let to Case failed: " $             withPatFailMsg (wrongExprForm "Let (NonRec v e1) e2") $   do Let (NonRec v ev) _ <- idR@@ -281,7 +314,8 @@ -------------------------------------------------------------------------------------------  -- | @(let v = ev in e) x@ ==> @let v = ev in e x@-letFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatAppR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+             => Rewrite c m CoreExpr letFloatAppR = prefixFailMsg "Let floating from App function failed: " $                withPatFailMsg (wrongExprForm "App (Let bnds body) e") $   do App (Let bnds body) e <- idR@@ -291,7 +325,8 @@         else appAllR (alphaLetVarsR $ varSetElems vs) idR >>> letFloatAppR  -- | @f (let v = ev in e)@ ==> @let v = ev in f e@-letFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatArgR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+             => Rewrite c m CoreExpr letFloatArgR = prefixFailMsg "Let floating from App argument failed: " $                withPatFailMsg (wrongExprForm "App f (Let bnds body)") $   do App f (Let bnds body) <- idR@@ -301,7 +336,8 @@         else appAllR idR (alphaLetVarsR $ varSetElems vs) >>> letFloatArgR  -- | @let v = (let bds in e1) in e2@ ==> @let bds in let v = e1 in e2@-letFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatLetR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+             => Rewrite c m CoreExpr letFloatLetR = prefixFailMsg "Let floating from Let failed: " $                withPatFailMsg (wrongExprForm "Let (NonRec v (Let bds e1)) e2") $   do Let (NonRec v (Let bds e1)) e2 <- idR@@ -313,20 +349,22 @@ -- | @(\ v -> let binds in e2)@  ==>  @let binds in (\ v1 -> e2)@ --   Fails if @v@ occurs in the RHS of @binds@. --   If @v@ is shadowed in binds, then @v@ will be alpha-renamed.-letFloatLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatLamR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+             => Rewrite c m CoreExpr letFloatLamR = prefixFailMsg "Let floating from Lam failed: " $                withPatFailMsg (wrongExprForm "Lam v1 (Let bds body)") $   do Lam v (Let binds body) <- idR      let bs  = bindVars binds          fvs = freeVarsBind binds-     guardMsg (v `notElemVarSet` fvs) (var2String v ++ " occurs in the RHS of the let-bindings.")+     guardMsg (v `notElemVarSet` fvs) (unqualifiedName v ++ " occurs in the RHS of the let-bindings.")      if v `elem` bs       then alphaLamR Nothing >>> letFloatLamR       else return $ Let binds (Lam v body)  -- | @case (let bnds in e) of bndr alts@ ==> @let bnds in (case e of bndr alts)@ --   Fails if any variables bound in @bnds@ occurs in @alts@.-letFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatCaseR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+              => Rewrite c m CoreExpr letFloatCaseR = prefixFailMsg "Let floating from Case failed: " $                 withPatFailMsg (wrongExprForm "Case (Let bnds e) w ty alts") $   do Case (Let bnds e) w ty alts <- idR@@ -335,6 +373,57 @@        then return $ Let bnds (Case e w ty alts)        else caseAllR (alphaLetVarsR $ varSetElems captures) idR idR (const idR) >>> letFloatCaseR +-- | case e of w { ... ; p -> let b = rhs in body ; ... }  ==>+--   let b = rhs in case e of { ... ; p -> body ; ... }+--+-- where no variable in `p` or `w` occurs freely in `rhs`,+-- and where `b` does not capture a free variable in the overall case,+-- and where `w` is not rebound in `b`.+letFloatCaseAltR :: MonadCatch m => Maybe Int -> Rewrite c m CoreExpr+letFloatCaseAltR maybeN = prefixFailMsg "Let float from case alternative failed: " $+                          withPatFailMsg (wrongExprForm "Case s w ty alts") $ do+        -- Perform the first safe let-floating out of a case alternative+    let letFloatOneAltM :: MonadCatch m => Id -> VarSet -> [CoreAlt] -> m (CoreBind,[CoreAlt])+        letFloatOneAltM w fvs = go+            where go [] = fail "no lets can be safely floated from alternatives."+                  go (alt:rest) = (do (bind,alt') <- letFloatAltM w fvs alt+                                      return (bind,alt':rest))+                                  <+ liftM (second (alt :)) (go rest)++        -- (p -> let bnds in body) ==> (bnds, p -> body)+        letFloatAltM :: Monad m => Id -> VarSet -> CoreAlt -> m (CoreBind,CoreAlt)+        letFloatAltM w fvs (con, vs, Let bnds body) = do+          let bSet = mkVarSet (bindVars bnds)+              vSet = mkVarSet (w:vs)++          -- 'w' is not in 'fvs', but if it is rebound by 'b', doing this rewrite+          -- would cause it to bind things that were previously bound by 'b'.+          guardMsg (not (w `elemVarSet` bSet)) "floating would allow case binder to capture variables."++          -- no free vars in 'rhs' are bound by 'p' or 'w'+          guardMsg (isEmptyVarSet $ vSet `intersectVarSet` freeVarsBind bnds)+                   "floating would cause variables in rhs to become unbound."++          -- no free vars in overall case are bound by 'b'+          guardMsg (isEmptyVarSet $ bSet `intersectVarSet` fvs)+                   "floating would cause let binders to capture variables in case expression."++          return (bnds, (con, vs, body))+        letFloatAltM _ _ _ = fail "no let expression on alternative right-hand side."++    Case e w ty alts <- idR+    fvs <- arr freeVarsExpr+    let l = length alts - 1+    case maybeN of+        Just n | n < 0 || n > l -> fail $ "valid alternative indices: 0 to " ++ show l+               | otherwise      -> do+            let (pre, alt:suf) = splitAt n alts+            (bnds,alt') <- letFloatAltM w fvs alt+            return $ Let bnds $ Case e w ty $ pre ++ (alt':suf)+        Nothing -> do+            (bnds,alts') <- letFloatOneAltM w fvs alts+            return $ Let bnds $ Case e w ty alts'+ -- | @cast (let bnds in e) co@ ==> @let bnds in cast e co@ letFloatCastR :: MonadCatch m => Rewrite c m CoreExpr letFloatCastR = prefixFailMsg "Let floating from Cast failed: " $@@ -343,12 +432,15 @@      return $ Let bnds (Cast e co)  -- | Float a 'Let' through an expression, whatever the context.-letFloatExprR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr-letFloatExprR = setFailMsg "Unsuitable expression for Let floating." $-               letFloatArgR <+ letFloatAppR <+ letFloatLetR <+ letFloatLamR <+ letFloatCaseR <+ letFloatCastR+letFloatExprR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+              => Rewrite c m CoreExpr+letFloatExprR = setFailMsg "Unsuitable expression for Let floating."+              $ letFloatArgR <+ letFloatAppR <+ letFloatLetR <+ letFloatLamR+                  <+ letFloatCaseR <+ letFloatCaseAltR Nothing <+ letFloatCastR  -- | @'ProgCons' ('NonRec' v ('Let' bds e)) p@ ==> @'ProgCons' bds ('ProgCons' ('NonRec' v e) p)@-letFloatTopR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg+letFloatTopR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, MonadCatch m, MonadUnique m)+             => Rewrite c m CoreProg letFloatTopR = prefixFailMsg "Let floating to top level failed: " $                withPatFailMsg (wrongExprForm "NonRec v (Let bds e) `ProgCons` p") $                do ProgCons (NonRec v (Let bds e)) p <- idR@@ -362,12 +454,14 @@ -------------------------------------------------------------------------------------------  -- | Float in a 'Let' if possible.-letFloatInR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr+letFloatInR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m)+            => Rewrite c m CoreExpr letFloatInR = letFloatInCaseR <+ letFloatInAppR <+ letFloatInLamR  -- | @let v = ev in case s of p -> e@ ==> @case (let v = ev in s) of p -> let v = ev in e@, --   if @v@ does not shadow a pattern binder in @p@-letFloatInCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr+letFloatInCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m)+                => Rewrite c m CoreExpr letFloatInCaseR = prefixFailMsg "Let floating in to case failed: " $                   withPatFailMsg (wrongExprForm "Let bnds (Case s w ty alts)") $   do Let bnds (Case s w ty alts) <- idR@@ -379,7 +473,8 @@      return (Case (Let bnds s) w ty alts) >>> caseAllR idR idR idR (\_ -> altAllR idR (\_ -> idR) (arr (Let bnds) >>> alphaLetR))  -- | @let v = ev in f a@ ==> @(let v = ev in f) (let v = ev in a)@-letFloatInAppR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb) => Rewrite c HermitM CoreExpr+letFloatInAppR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, MonadUnique m)+               => Rewrite c m CoreExpr letFloatInAppR = prefixFailMsg "Let floating in to app failed: " $                 withPatFailMsg (wrongExprForm "Let bnds (App e1 e2)") $   do Let bnds (App e1 e2) <- idR@@ -434,7 +529,7 @@  -- | Combine nested non-recursive lets into case of a tuple. --   E.g. let {v1 = e1 ; v2 = e2 ; v3 = e3} in body ==> case (e1,e2,e3) of {(v1,v2,v3) -> body}-letTupleR :: String -> Rewrite c HermitM CoreExpr+letTupleR :: (MonadCatch m, MonadUnique m) => String -> Rewrite c m CoreExpr letTupleR nm = prefixFailMsg "Let-tuple failed: " $       do (bnds, body) <- arr collectLets          let numBnds = length bnds@@ -465,32 +560,29 @@ -- This code could be factored better.  -- | @e@ ==> @let v = e in v@-letIntroR :: String -> Rewrite c HermitM CoreExpr+letIntroR :: (MonadCatch m, MonadUnique m) => String -> Rewrite c m CoreExpr letIntroR nm = do e <- idR                   Let (NonRec v e') _ <- letNonRecIntroR nm e                   return $ Let (NonRec v e') (varToCoreExpr v)  -- | @body@ ==> @let v = e in body@-letNonRecIntroR :: String -> CoreExpr -> Rewrite c HermitM CoreExpr+letNonRecIntroR :: (MonadCatch m, MonadUnique m) => String -> CoreExpr -> Rewrite c m CoreExpr letNonRecIntroR nm e = prefixFailMsg "Let-introduction failed: " $-     contextfreeT $ \ body -> do let tyk = exprKindOrType e-                                 v <- if | isTypeArg e  -> newTyVarH nm tyk-                                         | isCoArg e    -> newCoVarH nm tyk-                                         | otherwise    -> newIdH nm tyk+     contextfreeT $ \ body -> do v <- newVarH nm $ exprKindOrType e                                  return $ Let (NonRec v e) body   -- This isn't a "Let", but it's serving the same role.  Maybe create a Local/Prog module?  -- | @prog@ ==> @'ProgCons' (v = e) prog@-progNonRecIntroR :: String -> CoreExpr -> Rewrite c HermitM CoreProg+progNonRecIntroR :: (MonadCatch m, MonadUnique m) => String -> CoreExpr -> Rewrite c m CoreProg progNonRecIntroR nm e = prefixFailMsg "Top-level binding introduction failed: " $   do guardMsg (not $ isTyCoArg e) "Top-level type or coercion definitions are prohibited."      contextfreeT $ \ prog -> do i <- newIdH nm (exprType e)                                  return $ ProgCons (NonRec i e) prog  -- | nonRecIntroR nm e = 'letNonRecIntroR nm e' <+ 'progNonRecIntroR nm e'-nonRecIntroR :: String -> CoreExpr -> Rewrite c HermitM Core+nonRecIntroR :: (MonadCatch m, MonadUnique m) => String -> CoreExpr -> Rewrite c m Core nonRecIntroR nm e = readerT $ \case                       ExprCore{} -> promoteExprR (letNonRecIntroR nm e)                       ProgCore{} -> promoteProgR (progNonRecIntroR nm e)@@ -498,7 +590,9 @@  -- | Introduce a local definition for a (possibly imported) identifier. -- Rewrites occurences of the identifier to point to this new local definiton.-letIntroUnfoldingR :: (BoundVars c, ReadBindings c) => String -> Rewrite c HermitM CoreExpr+letIntroUnfoldingR :: ( BoundVars c, ReadBindings c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m+                      , MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+                   => HermitName -> Rewrite c m CoreExpr letIntroUnfoldingR nm = do     i <- findIdT nm     (rhs,_) <- getUnfoldingT AllBinders <<< return i
src/HERMIT/Dictionary/Navigation.hs view
@@ -1,33 +1,35 @@-{-# LANGUAGE ScopedTypeVariables, FlexibleContexts, FlexibleInstances, InstanceSigs #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, FlexibleInstances, InstanceSigs, ScopedTypeVariables, TypeFamilies #-}  module HERMIT.Dictionary.Navigation-       ( -- * Navigation-         externals-       , occurrenceOfT-       , bindingOfT-       , bindingGroupOfT-       , rhsOfT-       , parentOfT-       , occurrenceOfTargetsT-       , bindingOfTargetsT-       , bindingGroupOfTargetsT-       , rhsOfTargetsT-       , Considerable(..)-       , considerables-       , considerConstructT-       , nthArgPath-       )-where+    ( -- * Navigation+      externals+    , occurrenceOfT+    , bindingOfT+    , bindingGroupOfT+    , rhsOfT+    , parentOfT+    , occurrenceOfTargetsT+    , bindingOfTargetsT+    , bindingGroupOfTargetsT+    , rhsOfTargetsT+    , Considerable(..)+    , considerables+    , considerConstructT+    , nthArgPath+    , string2considerable+    ) where +import Data.Dynamic (Typeable) import Data.Monoid  import Control.Arrow  import HERMIT.Core import HERMIT.Context-import HERMIT.Kure import HERMIT.External import HERMIT.GHC hiding ((<>))+import HERMIT.Kure+import HERMIT.Name  import HERMIT.Dictionary.Navigation.Crumbs @@ -35,32 +37,33 @@  -- | 'External's involving navigating to named entities. externals :: [External]-externals = crumbExternals ++ map (.+ Navigation)-            [ external "rhs-of" (rhsOfT . cmpString2Var :: String -> TransformH Core LocalPathH)-                [ "Find the path to the RHS of the binding of the named variable." ]-            , external "binding-group-of" (bindingGroupOfT . cmpString2Var :: String -> TransformH CoreTC LocalPathH)-                [ "Find the path to the binding group of the named variable." ]-            , external "binding-of" (bindingOfT . cmpString2Var :: String -> TransformH CoreTC LocalPathH)-                [ "Find the path to the binding of the named variable." ]-            , external "occurrence-of" (occurrenceOfT . cmpString2Var :: String -> TransformH CoreTC LocalPathH)-                [ "Find the path to the first occurrence of the named variable." ]-            , external "consider" (considerConstruct :: String -> TransformH Core LocalPathH)-                [ "consider <c> focuses on the first construct <c>.",-                  recognizedConsiderables]-            , external "arg" (promoteExprT . nthArgPath :: Int -> TransformH Core LocalPathH)-                [ "arg n focuses on the (n-1)th argument of a nested application." ]-            , external "lams-body" (promoteExprT lamsBodyT :: TransformH Core LocalPathH)-                [ "Descend into the body after a sequence of lambdas." ]-            , external "lets-body" (promoteExprT letsBodyT :: TransformH Core LocalPathH)-                [ "Descend into the body after a sequence of let bindings." ]-            , external "prog-end" (promoteModGutsT gutsProgEndT <+ promoteProgT progEndT :: TransformH Core LocalPathH)-                [ "Descend to the end of a program." ]--            , external "parent-of" (parentOfT :: TransformH Core LocalPathH -> TransformH Core LocalPathH)-                [ "Focus on the parent of another focal point." ]-            , external "parent-of" (parentOfT :: TransformH CoreTC LocalPathH -> TransformH CoreTC LocalPathH)-                [ "Focus on the parent of another focal point." ]-            ]+externals = crumbExternals+    ++ map (.+ Navigation)+        [ external "rhs-of" (rhsOfT . mkRhsOfPred :: RhsOfName -> TransformH Core LocalPathH)+            [ "Find the path to the RHS of the binding of the named variable." ]+        , external "binding-group-of" (bindingGroupOfT . cmpString2Var :: String -> TransformH CoreTC LocalPathH)+            [ "Find the path to the binding group of the named variable." ]+        , external "binding-of" (bindingOfT . mkBindingPred :: BindingName -> TransformH CoreTC LocalPathH)+            [ "Find the path to the binding of the named variable." ]+        , external "occurrence-of" (occurrenceOfT . mkOccPred :: OccurrenceName -> TransformH CoreTC LocalPathH)+            [ "Find the path to the first occurrence of the named variable." ]+        , external "application-of" (applicationOfT . mkOccPred :: OccurrenceName -> TransformH CoreTC LocalPathH)+            [ "Find the path to the first application of the named variable." ]+        , external "consider" (considerConstructT :: Considerable -> TransformH Core LocalPathH)+            [ "consider <c> focuses on the first construct <c>.", recognizedConsiderables ]+        , external "arg" (promoteExprT . nthArgPath :: Int -> TransformH Core LocalPathH)+            [ "arg n focuses on the (n-1)th argument of a nested application." ]+        , external "lams-body" (promoteExprT lamsBodyT :: TransformH Core LocalPathH)+            [ "Descend into the body after a sequence of lambdas." ]+        , external "lets-body" (promoteExprT letsBodyT :: TransformH Core LocalPathH)+            [ "Descend into the body after a sequence of let bindings." ]+        , external "prog-end" (promoteModGutsT gutsProgEndT <+ promoteProgT progEndT :: TransformH Core LocalPathH)+            [ "Descend to the end of a program." ]+        , external "parent-of" (parentOfT :: TransformH Core LocalPathH -> TransformH Core LocalPathH)+            [ "Focus on the parent of another focal point." ]+        , external "parent-of" (parentOfT :: TransformH CoreTC LocalPathH -> TransformH CoreTC LocalPathH)+            [ "Focus on the parent of another focal point." ]+        ]  --------------------------------------------------------------------------------------- @@ -99,6 +102,12 @@ occurrenceOfT p = prefixFailMsg ("occurrence-of failed: ") $                   oneNonEmptyPathToT (arr $ occurrenceOf p) +-- | Find the path to an application of a given function.+applicationOfT :: (AddBindings c, ExtendPath c Crumb, HasEmptyContext c, MonadCatch m, ReadPath c Crumb)+               => (Var -> Bool) -> Transform c m CoreTC LocalPathH+applicationOfT p = prefixFailMsg "application-of failed:" $ oneNonEmptyPathToT go+    where go = promoteExprT (appT (extractT go) successT const) <+ arr (occurrenceOf p)+ -----------------------------------------------------------------------  bindingGroupOf :: (Var -> Bool) -> CoreBind -> Bool@@ -186,7 +195,13 @@  -- | Language constructs that can be zoomed to. data Considerable = Binding | Definition | CaseAlt | Variable | Literal | Application | Lambda | LetExpr | CaseOf | Casty | Ticky | TypeExpr | CoercionExpr+    deriving Typeable +instance Extern Considerable where+    type Box Considerable = Considerable+    box = id+    unbox = id+ recognizedConsiderables :: String recognizedConsiderables = "Recognized constructs are: " ++ show (map fst considerables) @@ -206,12 +221,6 @@                   , ("type",TypeExpr)                   , ("coerce",CoercionExpr)                   ]--considerConstruct :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, HasEmptyContext c, MonadCatch m) => String -> Transform c m Core LocalPathH-considerConstruct str = case string2considerable str of-                          Nothing -> fail $ "Unrecognized construct \"" ++ str ++ "\". Perhaps you meant \"binding-of '" ++ str ++ "\"? "-                                            ++ recognizedConsiderables ++ "."-                          Just c  -> considerConstructT c  -- | Find the path to the first matching construct. considerConstructT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, HasEmptyContext c, MonadCatch m) => Considerable -> Transform c m Core LocalPathH
src/HERMIT/Dictionary/Query.hs view
@@ -1,13 +1,12 @@ {-# LANGUAGE CPP, LambdaCase, FlexibleContexts #-}  module HERMIT.Dictionary.Query-  ( -- * Queries and Predicates-    externals-  , infoT-  , compareCoreAtT-  , compareBoundIdsT-  )-where+    ( -- * Queries and Predicates+      externals+    , infoT+    , compareCoreAtT+    , compareBoundIdsT+    ) where  import Control.Arrow @@ -20,6 +19,7 @@ import HERMIT.GHC import HERMIT.Kure import HERMIT.Monad+import HERMIT.Name  import HERMIT.Dictionary.AlphaConversion hiding (externals) import HERMIT.Dictionary.Common@@ -31,13 +31,13 @@ -- | Externals that reflect GHC functions, or are derived from GHC functions. externals :: [External] externals =-         [ external "info" (infoT :: TransformH CoreTC String)-                [ "Display information about the current node." ] .+ Query-         , external "compare-bound-ids" (compareBoundIds :: String -> String -> TransformH CoreTC ())-                [ "Compare the definitions of two in-scope identifiers for alpha equality."] .+ Query .+ Predicate-         , external "compare-core-at" (compareCoreAtT ::  TransformH Core LocalPathH -> TransformH Core LocalPathH -> TransformH Core ())-                [ "Compare the core fragments at the end of the given paths for alpha-equality."] .+ Query .+ Predicate-         ]+    [ external "info" (infoT :: TransformH CoreTC String)+        [ "Display information about the current node." ] .+ Query+    , external "compare-bound-ids" (compareBoundIds :: HermitName -> HermitName -> TransformH CoreTC ())+        [ "Compare the definitions of two in-scope identifiers for alpha equality."] .+ Query .+ Predicate+    , external "compare-core-at" (compareCoreAtT ::  TransformH Core LocalPathH -> TransformH Core LocalPathH -> TransformH Core ())+        [ "Compare the core fragments at the end of the given paths for alpha-equality."] .+ Query .+ Predicate+    ]  -------------------------------------------------------- @@ -52,7 +52,7 @@               pa       =   "Path:     " ++ showCrumbs (snocPathToPath $ absPath c)               children =   "Children: " ++ showCrumbs crumbs               bds      =   "Local bindings in scope: " ++ concat-                                [ "\n  " ++ var2String k ++  " : " ++ hermitBindingSummary hbs+                                [ "\n  " ++ unqualifiedName k ++  " : " ++ hermitBindingSummary hbs                                 | (k,hbs) <- Map.toList (hermitBindings c)                                 ]               freevars = [ "Free local identifiers:  " ++ showVarSet (filterVarSet isLocalId fvs)@@ -63,11 +63,14 @@                typeId   = case coreTC of                              Core (ExprCore e)      -> let tyK = exprKindOrType e+                                                           modName i = case nameModule_maybe (getName i) of+                                                                        Nothing -> "no module name."+                                                                        Just m -> moduleNameString (moduleName m)                                                         in [(if isKind tyK then "Kind:        " else "Type:        ") ++ showPpr dynFlags tyK] ++                                                            case e of                                                              Var i -> [ ""                                                                       , "OccName:                  " ++ getOccString i-                                                                      , if isLocalVar i then "Local" else "Global"+                                                                      , if isLocalVar i then "Local" else "Global: " ++ modName i                                                                       , "Unique:                   " ++ show (getUnique i)                                                                       , "Identifier arity:         " ++ show (arityOf c i)                                                                       , "Identifier binding depth: " ++ runKureM show id (lookupHermitBindingDepth i c)@@ -151,14 +154,10 @@                          TransCo{}     -> "TransCo"                          NthCo{}       -> "NthCo"                          InstCo{}      -> "InstCo"-#if __GLASGOW_HASKELL__ > 706                          AxiomRuleCo{} -> "AxiomRuleCo"                          LRCo{}        -> "LRCo"                          SubCo{}       -> "SubCo"                          UnivCo{}      -> "UnivCo"-#else-                         UnsafeCo{}    -> "UnsafeCo"-#endif  -------------------------------------------------------- @@ -180,7 +179,8 @@      guardMsg (e1 `exprAlphaEq` e2) "bindings are not alpha-equivalent."  -- | Compare the definitions of the two named identifiers for alpha-equality.-compareBoundIds :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c) => String -> String -> Transform c HermitM x ()+compareBoundIds :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c)+                => HermitName -> HermitName -> Transform c HermitM x () compareBoundIds nm1 nm2 = do i1 <- findIdT nm1                              i2 <- findIdT nm2                              compareBoundIdsT i1 i2
src/HERMIT/Dictionary/Reasoning.hs view
@@ -4,16 +4,19 @@ module HERMIT.Dictionary.Reasoning     ( -- * Equational Reasoning       externals-    , CoreExprEquality(..)-    , RewriteCoreExprEqualityBox(..)-    , TransformCoreExprEqualityStringBox(..)-    , CoreExprEqualityProof-    , flipCoreExprEquality+    , EqualityProof+    , flipEquality     , eqLhsIntroR     , eqRhsIntroR     , birewrite     , extensionalityR-    -- ** Lifting transformations over 'CoreExprEquality'+    , getLemmasT+    , getLemmaByNameT+    , insertLemmaR+    , lemmaR+    , markLemmaUsedR+    , modifyLemmaR+    -- ** Lifting transformations over 'Equality'     , lhsT     , rhsT     , bothT@@ -21,9 +24,9 @@     , lhsR     , rhsR     , bothR-    , ppCoreExprEqualityT-    , proveCoreExprEqualityT-    , verifyCoreExprEqualityT+    , ppEqualityT+    , proveEqualityT+    , verifyEqualityT     , verifyEqualityLeftToRightT     , verifyEqualityCommonTargetT     , verifyIsomorphismT@@ -38,36 +41,34 @@     , discardUniVars     ) where -import Control.Applicative-import Control.Arrow-import Control.Monad-import Control.Monad.IO.Class--import Data.List (nubBy)-import Data.Maybe (fromMaybe)-import Data.Monoid-import Data.Typeable--import HERMIT.Context-import HERMIT.Core-import HERMIT.External-import HERMIT.GHC-import HERMIT.Kure-import HERMIT.Monad-import HERMIT.ParserCore-#if __GLASGOW_HASKELL__ >= 708-import HERMIT.ParserType-#endif-import HERMIT.Utilities+import           Control.Applicative+import           Control.Arrow+import           Control.Monad+import           Control.Monad.IO.Class -import HERMIT.Dictionary.AlphaConversion hiding (externals)-import HERMIT.Dictionary.Common-import HERMIT.Dictionary.Fold hiding (externals)-import HERMIT.Dictionary.GHC hiding (externals)-import HERMIT.Dictionary.Local.Let (nonRecIntroR)-import HERMIT.Dictionary.Unfold hiding (externals)+import qualified Data.Map as Map+import           Data.List (nubBy)+import           Data.Maybe (fromMaybe)+import           Data.Monoid -import HERMIT.PrettyPrinter.Common+import           HERMIT.Context+import           HERMIT.Core+import           HERMIT.External+import           HERMIT.GHC+import           HERMIT.Kure+import           HERMIT.Monad+import           HERMIT.Name+import           HERMIT.ParserCore+import           HERMIT.ParserType+import           HERMIT.PrettyPrinter.Common+import           HERMIT.Utilities+                +import           HERMIT.Dictionary.AlphaConversion hiding (externals)+import           HERMIT.Dictionary.Common+import           HERMIT.Dictionary.Fold hiding (externals)+import           HERMIT.Dictionary.GHC hiding (externals)+import           HERMIT.Dictionary.Local.Let (nonRecIntroR)+import           HERMIT.Dictionary.Unfold hiding (externals)  import qualified Text.PrettyPrint.MarkedHughesPJ as PP @@ -88,72 +89,91 @@         [ "Alpha-rename a universally quantified variable." ]     , external "unshadow-equality" unshadowEqualityR         [ "Unshadow an equality." ]+    , external "lemma" (promoteExprBiR . lemmaR :: LemmaName -> BiRewriteH Core)+        [ "Generate a bi-directional rewrite from a lemma." ]+    , external "lemma-lhs-intro" (lemmaLhsIntroR :: LemmaName -> RewriteH Core)+        [ "Introduce the LHS of a lemma as a non-recursive binding, in either an expression or a program."+        , "body ==> let v = lhs in body" ] .+ Introduce .+ Shallow+    , external "lemma-rhs-intro" (lemmaRhsIntroR :: LemmaName -> RewriteH Core)+        [ "Introduce the RHS of a lemma as a non-recursive binding, in either an expression or a program."+        , "body ==> let v = rhs in body" ] .+ Introduce .+ Shallow+    , external "inst-lemma" (\ nm v cs -> modifyLemmaR nm id (instantiateEqualityVarR (cmpString2Var v) cs) id id :: RewriteH Core)+        [ "Instantiate one of the universally quantified variables of the given lemma,"+        , "with the given Core expression, creating a new lemma. Instantiating an"+        , "already proven lemma will result in the new lemma being considered proven." ]+    , external "inst-lemma-dictionaries" (\ nm -> modifyLemmaR nm id instantiateDictsR id id :: RewriteH Core)+        [ "Instantiate all of the universally quantified dictionaries of the given lemma."+        , "Only works on dictionaries whose types are monomorphic (no free type variables)." ]+    , external "copy-lemma" (\ nm newName -> modifyLemmaR nm (const newName) idR id id :: RewriteH Core)+        [ "Copy a given lemma, with a new name." ]+    , external "modify-lemma" (\ nm rr -> modifyLemmaR nm id rr (const False) (const False) :: RewriteH Core)+        [ "Modify a given lemma. Resets the proven status to Not Proven and used status to Not Used." ]+    , external "query-lemma" ((\ nm t -> getLemmaByNameT nm >>> arr lemmaEq >>> t) :: LemmaName -> TransformH Equality String -> TransformH Core String)+        [ "Apply a transformation to a lemma, returning the result." ]+    , external "extensionality" (extensionalityR . Just :: String -> RewriteH Equality)+        [ "Given a name 'x, then"+        , "f == g  ==>  forall x.  f x == g x" ]+    , external "extensionality" (extensionalityR Nothing :: RewriteH Equality)+        [ "f == g  ==>  forall x.  f x == g x" ]+    , external "lhs" (lhsR . extractR :: RewriteH Core -> RewriteH Equality)+        [ "Apply a rewrite to the LHS of an equality." ]+    , external "lhs" (lhsT . extractT :: TransformH CoreTC String -> TransformH Equality String)+        [ "Apply a transformation to the LHS of an equality." ]+    , external "rhs" (rhsR . extractR :: RewriteH Core -> RewriteH Equality)+        [ "Apply a rewrite to the RHS of an equality." ]+    , external "rhs" (rhsT . extractT :: TransformH CoreTC String -> TransformH Equality String)+        [ "Apply a transformation to the RHS of an equality." ]+    , external "both" (bothR . extractR :: RewriteH Core -> RewriteH Equality)+        [ "Apply a rewrite to both sides of an equality, succeeding if either succeed." ]+    , external "both" ((\t -> liftM (\(r,s) -> unlines [r,s]) (bothT (extractT t))) :: TransformH CoreTC String -> TransformH Equality String)+        [ "Apply a transformation to the RHS of an equality." ]     ]  ------------------------------------------------------------------------------ --- | An equality is represented as a set of universally quantified binders, and then the LHS and RHS of the equality.-data CoreExprEquality = CoreExprEquality [CoreBndr] CoreExpr CoreExpr--data RewriteCoreExprEqualityBox =-        RewriteCoreExprEqualityBox (RewriteH CoreExprEquality) deriving Typeable--instance Extern (RewriteH CoreExprEquality) where-    type Box (RewriteH CoreExprEquality) = RewriteCoreExprEqualityBox-    box = RewriteCoreExprEqualityBox-    unbox (RewriteCoreExprEqualityBox r) = r--data TransformCoreExprEqualityStringBox =-        TransformCoreExprEqualityStringBox (TransformH CoreExprEquality String) deriving Typeable--instance Extern (TransformH CoreExprEquality String) where-    type Box (TransformH CoreExprEquality String) = TransformCoreExprEqualityStringBox-    box = TransformCoreExprEqualityStringBox-    unbox (TransformCoreExprEqualityStringBox t) = t--type CoreExprEqualityProof c m = (Rewrite c m CoreExpr, Rewrite c m CoreExpr)+type EqualityProof c m = (Rewrite c m CoreExpr, Rewrite c m CoreExpr) --- | Flip the LHS and RHS of a 'CoreExprEquality'.-flipCoreExprEquality :: CoreExprEquality -> CoreExprEquality-flipCoreExprEquality (CoreExprEquality xs lhs rhs) = CoreExprEquality xs rhs lhs+-- | Flip the LHS and RHS of a 'Equality'.+flipEquality :: Equality -> Equality+flipEquality (Equality xs lhs rhs) = Equality xs rhs lhs  -- | f == g  ==>  forall x.  f x == g x-extensionalityR :: Maybe String -> Rewrite c HermitM CoreExprEquality+extensionalityR :: Maybe String -> Rewrite c HermitM Equality extensionalityR mn = prefixFailMsg "extensionality failed: " $-  do CoreExprEquality vs lhs rhs <- idR+  do Equality vs lhs rhs <- idR       let tyL = exprKindOrType lhs          tyR = exprKindOrType rhs      guardMsg (tyL `typeAlphaEq` tyR) "type mismatch between sides of equality.  This shouldn't happen, so is probably a bug."       -- TODO: use the fresh-name-generator in AlphaConversion to avoid shadowing.-     (argTy,_) <- splitFunTypeM tyL+     (_,argTy,_) <- splitFunTypeM tyL      v <- constT $ newVarH (fromMaybe "x" mn) argTy       let x = varToCoreExpr v -     return $ CoreExprEquality (vs ++ [v])-                               (mkCoreApp lhs x)-                               (mkCoreApp rhs x)+     return $ Equality (vs ++ [v]) (mkCoreApp lhs x) (mkCoreApp rhs x)  ------------------------------------------------------------------------------  -- | @e@ ==> @let v = lhs in e@-eqLhsIntroR :: CoreExprEquality -> Rewrite c HermitM Core-eqLhsIntroR (CoreExprEquality bs lhs _) = nonRecIntroR "lhs" (mkCoreLams bs lhs)+eqLhsIntroR :: Equality -> Rewrite c HermitM Core+eqLhsIntroR (Equality bs lhs _) = nonRecIntroR "lhs" (mkCoreLams bs lhs)  -- | @e@ ==> @let v = rhs in e@-eqRhsIntroR :: CoreExprEquality -> Rewrite c HermitM Core-eqRhsIntroR (CoreExprEquality bs _ rhs) = nonRecIntroR "rhs" (mkCoreLams bs rhs)+eqRhsIntroR :: Equality -> Rewrite c HermitM Core+eqRhsIntroR (Equality bs _ rhs) = nonRecIntroR "rhs" (mkCoreLams bs rhs)  ------------------------------------------------------------------------------ --- | Create a 'BiRewrite' from a 'CoreExprEquality'.+-- | Create a 'BiRewrite' from a 'Equality'. -- -- The high level idea: create a temporary function with two definitions. -- Fold one of the defintions, then immediately unfold the other.-birewrite :: (AddBindings c, ReadBindings c, ExtendPath c Crumb, ReadPath c Crumb, HasEmptyContext c) => CoreExprEquality -> BiRewrite c HermitM CoreExpr-birewrite (CoreExprEquality bnds l r) = bidirectional (foldUnfold l r) (foldUnfold r l)+birewrite :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c+             , ReadPath c Crumb, MonadCatch m, MonadUnique m )+          => Equality -> BiRewrite c m CoreExpr+birewrite (Equality bnds l r) = bidirectional (foldUnfold l r) (foldUnfold r l)     where foldUnfold lhs rhs = transform $ \ c e -> do             let lhsLam = mkCoreLams bnds lhs             -- we use a unique, transitory variable for the 'function' we are folding@@ -163,46 +183,46 @@                 -- create a temporary context with an unfolding for the                 -- transitory function so we can reuse unfoldR.                 c' = addHermitBindings [(v, NONREC rhsLam, mempty)] c-            apply unfoldR c' e'+            applyT unfoldR c' e' --- | Lift a transformation over 'CoreExpr' into a transformation over the left-hand side of a 'CoreExprEquality'.-lhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m CoreExprEquality b-lhsT t = idR >>= \ (CoreExprEquality vs lhs _) -> return lhs >>> withVarsInScope vs t+-- | Lift a transformation over 'CoreExpr' into a transformation over the left-hand side of a 'Equality'.+lhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m Equality b+lhsT t = idR >>= \ (Equality vs lhs _) -> return lhs >>> withVarsInScope vs t --- | Lift a transformation over 'CoreExpr' into a transformation over the right-hand side of a 'CoreExprEquality'.-rhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m CoreExprEquality b-rhsT t = idR >>= \ (CoreExprEquality vs _ rhs) -> return rhs >>> withVarsInScope vs t+-- | Lift a transformation over 'CoreExpr' into a transformation over the right-hand side of a 'Equality'.+rhsT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m Equality b+rhsT t = idR >>= \ (Equality vs _ rhs) -> return rhs >>> withVarsInScope vs t --- | Lift a transformation over 'CoreExpr' into a transformation over both sides of a 'CoreExprEquality'.-bothT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m CoreExprEquality (b,b)+-- | Lift a transformation over 'CoreExpr' into a transformation over both sides of a 'Equality'.+bothT :: (AddBindings c, Monad m, ReadPath c Crumb) => Transform c m CoreExpr b -> Transform c m Equality (b,b) bothT t = liftM2 (,) (lhsT t) (rhsT t) -- Can't wait for Applicative to be a superclass of Monad --- | Lift a transformation over '[Var]' into a transformation over the universally quantified variables of a 'CoreExprEquality'.-forallVarsT :: Monad m => Transform c m [Var] b -> Transform c m CoreExprEquality b-forallVarsT t = idR >>= \ (CoreExprEquality vs _ _) -> return vs >>> t+-- | Lift a transformation over '[Var]' into a transformation over the universally quantified variables of a 'Equality'.+forallVarsT :: Monad m => Transform c m [Var] b -> Transform c m Equality b+forallVarsT t = idR >>= \ (Equality vs _ _) -> return vs >>> t --- | Lift a rewrite over 'CoreExpr' into a rewrite over the left-hand side of a 'CoreExprEquality'.-lhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m CoreExprEquality+-- | Lift a rewrite over 'CoreExpr' into a rewrite over the left-hand side of a 'Equality'.+lhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m Equality lhsR r = do-    CoreExprEquality vs lhs rhs <- idR+    Equality vs lhs rhs <- idR     lhs' <- withVarsInScope vs r <<< return lhs-    return $ CoreExprEquality vs lhs' rhs+    return $ Equality vs lhs' rhs --- | Lift a rewrite over 'CoreExpr' into a rewrite over the right-hand side of a 'CoreExprEquality'.-rhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m CoreExprEquality+-- | Lift a rewrite over 'CoreExpr' into a rewrite over the right-hand side of a 'Equality'.+rhsR :: (AddBindings c, Monad m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m Equality rhsR r = do-    CoreExprEquality vs lhs rhs <- idR+    Equality vs lhs rhs <- idR     rhs' <- withVarsInScope vs r <<< return rhs-    return $ CoreExprEquality vs lhs rhs'+    return $ Equality vs lhs rhs' --- | Lift a rewrite over 'CoreExpr' into a rewrite over both sides of a 'CoreExprEquality'.-bothR :: (AddBindings c, MonadCatch m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m CoreExprEquality+-- | Lift a rewrite over 'CoreExpr' into a rewrite over both sides of a 'Equality'.+bothR :: (AddBindings c, MonadCatch m, ReadPath c Crumb) => Rewrite c m CoreExpr -> Rewrite c m Equality bothR r = lhsR r >+> rhsR r  ------------------------------------------------------------------------------ -ppCoreExprEqualityT :: PrettyPrinter -> TransformH CoreExprEquality DocH-ppCoreExprEqualityT pp = do+ppEqualityT :: PrettyPrinter -> TransformH Equality DocH+ppEqualityT pp = do     let pos = pOptions pp     d1 <- forallVarsT (liftPrettyH pos $ pForall pp)     (d2,d3) <- bothT (liftPrettyH pos $ extractT $ pCoreTC pp)@@ -219,30 +239,30 @@ -- -- TODO: need to know type of 'x' to generate a variable. class BuildEquality a where-    mkEquality :: a -> HermitM CoreExprEquality+    mkEquality :: a -> HermitM Equality  instance BuildEquality (CoreExpr,CoreExpr) where-    mkEquality :: (CoreExpr,CoreExpr) -> HermitM CoreExprEquality-    mkEquality (lhs,rhs) = return $ CoreExprEquality [] lhs rhs+    mkEquality :: (CoreExpr,CoreExpr) -> HermitM Equality+    mkEquality (lhs,rhs) = return $ Equality [] lhs rhs  instance BuildEquality a => BuildEquality (CoreExpr -> a) where-    mkEquality :: (CoreExpr -> a) -> HermitM CoreExprEquality+    mkEquality :: (CoreExpr -> a) -> HermitM Equality     mkEquality f = do         x <- newIdH "x" (error "need to create a type")-        CoreExprEquality bnds lhs rhs <- mkEquality (f (varToCoreExpr x))-        return $ CoreExprEquality (x:bnds) lhs rhs+        Equality bnds lhs rhs <- mkEquality (f (varToCoreExpr x))+        return $ Equality (x:bnds) lhs rhs  ------------------------------------------------------------------------------ --- | Verify that a 'CoreExprEquality' holds, by applying a rewrite to each side, and checking that the results are equal.-proveCoreExprEqualityT :: forall c m. (AddBindings c, Monad m, ReadPath c Crumb)-                        => CoreExprEqualityProof c m -> Transform c m CoreExprEquality ()-proveCoreExprEqualityT (l,r) = lhsR l >>> rhsR r >>> verifyCoreExprEqualityT+-- | Verify that a 'Equality' holds, by applying a rewrite to each side, and checking that the results are equal.+proveEqualityT :: forall c m. (AddBindings c, Monad m, ReadPath c Crumb)+                        => EqualityProof c m -> Transform c m Equality ()+proveEqualityT (l,r) = lhsR l >>> rhsR r >>> verifyEqualityT --- | Verify that the left- and right-hand sides of a 'CoreExprEquality' are alpha equivalent.-verifyCoreExprEqualityT :: Monad m => Transform c m CoreExprEquality ()-verifyCoreExprEqualityT = do-    CoreExprEquality _ lhs rhs <- idR+-- | Verify that the left- and right-hand sides of a 'Equality' are alpha equivalent.+verifyEqualityT :: Monad m => Transform c m Equality ()+verifyEqualityT = do+    Equality _ lhs rhs <- idR     guardMsg (exprAlphaEq lhs rhs) "the two sides of the equality do not match."  ------------------------------------------------------------------------------@@ -257,7 +277,7 @@      guardMsg (exprAlphaEq targetExpr resultExpr) "result of running proof on lhs of equality does not match rhs of equality."  -- | Given two expressions, and a rewrite to apply to each, verify that the resulting expressions are equal.-verifyEqualityCommonTargetT :: MonadCatch m => CoreExpr -> CoreExpr -> CoreExprEqualityProof c m -> Transform c m a ()+verifyEqualityCommonTargetT :: MonadCatch m => CoreExpr -> CoreExpr -> EqualityProof c m -> Transform c m a () verifyEqualityCommonTargetT lhs rhs (l,r) =   prefixFailMsg "equality verification failed: " $   do lhsResult <- l <<< return lhs@@ -317,16 +337,14 @@ ------------------------------------------------------------------------------  -- TODO: revisit this for binder re-ordering issue-instantiateDictsR :: RewriteH CoreExprEquality-#if __GLASGOW_HASKELL__ >= 708+instantiateDictsR :: RewriteH Equality instantiateDictsR = prefixFailMsg "Dictionary instantiation failed: " $ do     bs <- forallVarsT idR     let dArgs = filter (\b -> isId b && isDictTy (varType b)) bs         uniqDs = nubBy (\ b1 b2 -> eqType (varType b1) (varType b2)) dArgs     guardMsg (not (null uniqDs)) "no universally quantified dictionaries can be instantiated."     ds <- forM uniqDs $ \ b -> constT $ do-            guts <- getModGuts-            (i,bnds) <- liftCoreM $ buildDictionary guts b+            (i,bnds) <- buildDictionary b             let dExpr = case bnds of                             [NonRec v e] | i == v -> e -- the common case that we would have gotten a single non-recursive let                             _ -> mkCoreLets bnds (varToCoreExpr i)@@ -344,15 +362,12 @@                 then return $ lookup3 b ds                 else buildSubst b     contextfreeT $ instantiateEquality allDs-#else-instantiateDictsR = fail "Dictionaries cannot be instantiated in GHC 7.6"-#endif  ------------------------------------------------------------------------------ -alphaEqualityR :: (Var -> Bool) -> (String -> String) -> RewriteH CoreExprEquality+alphaEqualityR :: (Var -> Bool) -> (String -> String) -> RewriteH Equality alphaEqualityR p f = prefixFailMsg "Alpha-renaming binder in equality failed: " $ do-    CoreExprEquality bs lhs rhs <- idR+    Equality bs lhs rhs <- idR     guardMsg (any p bs) "specified variable is not universally quantified."      let (bs',i:vs) = break p bs -- this is safe because we know i is in bs@@ -363,11 +378,11 @@         (subst', vs') = substBndrs subst vs         lhs'          = substExpr (text "coreExprEquality-lhs") subst' lhs         rhs'          = substExpr (text "coreExprEquality-rhs") subst' rhs-    return $ CoreExprEquality (bs'++(i':vs')) lhs' rhs'+    return $ Equality (bs'++(i':vs')) lhs' rhs' -unshadowEqualityR :: RewriteH CoreExprEquality+unshadowEqualityR :: RewriteH Equality unshadowEqualityR = prefixFailMsg "Unshadowing equality failed: " $ do-    c@(CoreExprEquality bs _ _) <- idR+    c@(Equality bs _ _) <- idR     bvs <- boundVarsT     let visible = unionVarSets [bvs , freeVarsEquality c]     ss <- varSetElems <$> detectShadowsM bs visible@@ -375,39 +390,35 @@     let f = freshNameGenAvoiding Nothing . extendVarSet visible     andR [ alphaEqualityR (==s) (f s) | s <- reverse ss ] >>> bothR (tryR unshadowExprR) -freeVarsEquality :: CoreExprEquality -> VarSet-freeVarsEquality (CoreExprEquality bs lhs rhs) =+freeVarsEquality :: Equality -> VarSet+freeVarsEquality (Equality bs lhs rhs) =     delVarSetList (unionVarSets (map freeVarsExpr [lhs,rhs])) bs  ------------------------------------------------------------------------------ -instantiateEqualityVarR :: (Var -> Bool) -> CoreString -> RewriteH CoreExprEquality+instantiateEqualityVarR :: (Var -> Bool) -> CoreString -> RewriteH Equality instantiateEqualityVarR p cs = prefixFailMsg "instantiation failed: " $ do     bs <- forallVarsT idR     (e,new) <- case filter p bs of                 [] -> fail "no universally quantified variables match predicate."                 (b:_) | isId b    -> let (before,_) = break (==b) bs                                      in liftM (,[]) $ withVarsInScope before $ parseCoreExprT cs-#if __GLASGOW_HASKELL__ >= 708                       | otherwise -> do let (before,_) = break (==b) bs                                         (ty, tvs) <- withVarsInScope before $ parseTypeWithHolesT cs                                         return (Type ty, tvs)-#else-                      | otherwise -> fail "cannot instantiate type binders in GHC 7.6"-#endif     eq <- contextfreeT $ instantiateEqualityVar p e new     (_,_) <- return eq >>> bothT lintExprT -- sanity check     return eq --- | Instantiate one of the universally quantified variables in a 'CoreExprEquality'.+-- | Instantiate one of the universally quantified variables in a 'Equality'. -- Note: assumes implicit ordering of variables, such that substitution happens to the right -- as it does in case alternatives. Only first variable that matches predicate is -- instantiated. instantiateEqualityVar :: MonadIO m => (Var -> Bool) -- predicate to select var                                     -> CoreExpr      -- expression to instantiate with                                     -> [Var]         -- new binders to add in place of var-                                    -> CoreExprEquality -> m CoreExprEquality-instantiateEqualityVar p e new (CoreExprEquality bs lhs rhs)+                                    -> Equality -> m Equality+instantiateEqualityVar p e new (Equality bs lhs rhs)     | not (any p bs) = fail "specified variable is not universally quantified."     | otherwise = do         let (bs',i:vs) = break p bs -- this is safe because we know i is in bs@@ -427,21 +438,68 @@         let inS           = delVarSetList (unionVarSets (map localFreeVarsExpr [lhs, rhs, e] ++ map freeVarsVar vs)) (i:vs)             subst         = extendSubst (mkEmptySubst (mkInScopeSet inS)) i e             (subst', vs') = substBndrs subst vs-            lhs'          = substExpr (text "coreExprEquality-lhs") subst' lhs-            rhs'          = substExpr (text "coreExprEquality-rhs") subst' rhs-        instantiateEquality (noAdds tvs) $ CoreExprEquality (bs'++new++vs') lhs' rhs'+            lhs'          = substExpr (text "equality-lhs") subst' lhs+            rhs'          = substExpr (text "equality-rhs") subst' rhs+        instantiateEquality (noAdds tvs) $ Equality (bs'++new++vs') lhs' rhs'  noAdds :: [(Var,CoreExpr)] -> [(Var,CoreExpr,[Var])] noAdds ps = [ (v,e,[]) | (v,e) <- ps ] --- | Instantiate a set of universally quantified variables in a 'CoreExprEquality'.+-- | Instantiate a set of universally quantified variables in a 'Equality'. -- It is important that all type variables appear before any value-level variables in the first argument.-instantiateEquality :: MonadIO m => [(Var,CoreExpr,[Var])] -> CoreExprEquality -> m CoreExprEquality+instantiateEquality :: MonadIO m => [(Var,CoreExpr,[Var])] -> Equality -> m Equality instantiateEquality = flip (foldM (\ eq (v,e,vs) -> instantiateEqualityVar (==v) e vs eq)) . reverse -- foldM is a left-to-right fold, so the reverse is important to do substitutions in reverse order -- which is what we want (all value variables should be instantiated before type variables).  ------------------------------------------------------------------------------ -discardUniVars :: CoreExprEquality -> CoreExprEquality-discardUniVars (CoreExprEquality _ lhs rhs) = CoreExprEquality [] lhs rhs+discardUniVars :: Equality -> Equality+discardUniVars (Equality _ lhs rhs) = Equality [] lhs rhs++------------------------------------------------------------------------------++getLemmasT :: HasLemmas m => Transform c m x Lemmas+getLemmasT = constT getLemmas++getLemmaByNameT :: (HasLemmas m, Monad m) => LemmaName -> Transform c m x Lemma+getLemmaByNameT nm = getLemmasT >>= maybe (fail $ "No lemma named: " ++ show nm) return . Map.lookup nm++lemmaR :: LemmaName -> BiRewriteH CoreExpr+lemmaR nm = afterBiR (beforeBiR (getLemmaByNameT nm) (birewrite . lemmaEq)) (markLemmaUsedR nm)++------------------------------------------------------------------------------++-- We use sideEffectR because only rewrites generate new state in the Kernel.++insertLemmaR :: (HasLemmas m, Monad m) => LemmaName -> Lemma -> Rewrite c m a+insertLemmaR nm l = sideEffectR $ \ _ _ -> insertLemma nm l++modifyLemmaR :: (HasLemmas m, Monad m)+             => LemmaName+             -> (LemmaName -> LemmaName) -- ^ modify lemma name+             -> Rewrite c m Equality     -- ^ rewrite the equality+             -> (Bool -> Bool)           -- ^ modify proven status+             -> (Bool -> Bool)           -- ^ modify used status+             -> Rewrite c m a+modifyLemmaR nm nFn rr pFn uFn = do+    Lemma eq p u <- getLemmaByNameT nm+    eq' <- rr <<< return eq+    sideEffectR $ \ _ _ -> insertLemma (nFn nm) $ Lemma eq' (pFn p) (uFn u)++markLemmaUsedR :: (HasLemmas m, Monad m) => LemmaName -> Rewrite c m a+markLemmaUsedR nm = modifyLemmaR nm id idR id (const True)++------------------------------------------------------------------------------++lemmaNameToEqualityT :: (HasLemmas m, Monad m) => LemmaName -> Transform c m x Equality+lemmaNameToEqualityT nm = liftM lemmaEq $ getLemmaByNameT nm++-- | @e@ ==> @let v = lhs in e@  (also works in a similar manner at Program nodes)+lemmaLhsIntroR :: LemmaName -> RewriteH Core+lemmaLhsIntroR = lemmaNameToEqualityT >=> eqLhsIntroR++-- | @e@ ==> @let v = rhs in e@  (also works in a similar manner at Program nodes)+lemmaRhsIntroR :: LemmaName -> RewriteH Core+lemmaRhsIntroR = lemmaNameToEqualityT >=> eqRhsIntroR+
src/HERMIT/Dictionary/Rules.hs view
@@ -1,33 +1,31 @@-{-# LANGUAGE CPP, FlexibleContexts #-}+{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, FlexibleInstances, TypeFamilies #-} module HERMIT.Dictionary.Rules-       ( -- * GHC Rewrite Rules and Specialisation-         externals-         -- ** Rules-       , RuleNameString-       , ruleR-       , rulesR-       , ruleToEqualityT-       , ruleNameToEqualityT-       , getHermitRuleT-       , getHermitRulesT-       -- , verifyCoreRuleT-       -- , verifyRuleT-       -- , ruleLhsIntroR-       -- , ruleRhsIntroR-         -- ** Specialisation-       , specConstrR-       )-where+    ( -- * GHC Rewrite Rules and Specialisation+      externals+      -- ** Rules+    , RuleName(..)+    , RuleNameListBox(..)+    , ruleR+    , rulesR+    , ruleToEqualityT+    , ruleNameToEqualityT+    , getHermitRuleT+    , getHermitRulesT+      -- ** Specialisation+    , specConstrR+    , specialiseR+    ) where -import IOEnv hiding (liftIO) import qualified SpecConstr import qualified Specialise  import Control.Arrow import Control.Monad +import Data.Dynamic (Typeable) import Data.Function (on) import Data.List (deleteFirstsBy,intercalate)+import Data.String (IsString(..))  import HERMIT.Core import HERMIT.Context@@ -36,166 +34,117 @@ import HERMIT.External import HERMIT.GHC -import HERMIT.Dictionary.Common (inScope,callT) import HERMIT.Dictionary.GHC (dynFlagsT)--- import HERMIT.Dictionary.Induction import HERMIT.Dictionary.Kure (anyCallR) import HERMIT.Dictionary.Reasoning hiding (externals)-import HERMIT.Dictionary.Unfold (cleanupUnfoldR)+import HERMIT.Dictionary.Unfold (betaReducePlusR) +import IOEnv hiding (liftIO)+ ------------------------------------------------------------------------ --- | Externals that reflect GHC functions, or are derived from GHC functions.+-- | Externals dealing with GHC rewrite rules. externals :: [External] externals =-         [ external "rules-help-list" (rulesHelpListT :: TransformH CoreTC String)-                [ "List all the rules in scope." ] .+ Query-         , external "rule-help" (ruleHelpT :: RuleNameString -> TransformH CoreTC String)-                [ "Display details on the named rule." ] .+ Query-         , external "apply-rule" (promoteExprR . ruleR :: RuleNameString -> RewriteH Core)-                [ "Apply a named GHC rule" ] .+ Shallow-         , external "apply-rules" (promoteExprR . rulesR :: [RuleNameString] -> RewriteH Core)-                [ "Apply named GHC rules, succeed if any of the rules succeed" ] .+ Shallow-         , external "add-rule" ((\ rule_name id_name -> promoteModGutsR (addCoreBindAsRule rule_name id_name)) :: String -> String -> RewriteH Core)-                [ "add-rule \"rule-name\" <id> -- adds a new rule that freezes the right hand side of the <id>"]  .+ Introduce-         , external "unfold-rule" ((\ nm -> promoteExprR (ruleR nm >>> cleanupUnfoldR)) :: String -> RewriteH Core)-                [ "Unfold a named GHC rule" ] .+ Deep .+ Context .+ TODO -- TODO: does not work with rules with no arguments-         , external "spec-constr" (promoteModGutsR specConstrR :: RewriteH Core)-                [ "Run GHC's SpecConstr pass, which performs call pattern specialization."] .+ Deep-         , external "specialise" (promoteModGutsR specialise :: RewriteH Core)-                [ "Run GHC's specialisation pass, which performs type and dictionary specialisation."] .+ Deep-         ]+    [ external "rule-help" (rulesHelpListT :: TransformH CoreTC String)+        [ "List all the rules in scope." ] .+ Query+    , external "rule-help" (ruleHelpT :: RuleName -> TransformH CoreTC String)+        [ "Display details on the named rule." ] .+ Query+    , external "apply-rule" (promoteExprR . ruleR :: RuleName -> RewriteH Core)+        [ "Apply a named GHC rule" ] .+ Shallow+    , external "apply-rules" (promoteExprR . rulesR :: [RuleName] -> RewriteH Core)+        [ "Apply named GHC rules, succeed if any of the rules succeed" ] .+ Shallow+    , external "unfold-rule" ((\ nm -> promoteExprR (ruleR nm >>> tryR betaReducePlusR)) :: RuleName -> RewriteH Core)+        [ "Unfold a named GHC rule" ] .+ Deep .+ Context .+ TODO -- TODO: does not work with rules with no arguments+    , external "rule-to-lemma" (\nm -> do eq <- ruleNameToEqualityT nm+                                          insertLemmaR (fromString (show nm)) $ Lemma eq False False :: RewriteH Core)+        [ "Create a lemma from a GHC RULE." ]+    , external "spec-constr" (promoteModGutsR specConstrR :: RewriteH Core)+        [ "Run GHC's SpecConstr pass, which performs call pattern specialization."] .+ Deep+    , external "specialise" (promoteModGutsR specialiseR :: RewriteH Core)+        [ "Run GHC's specialisation pass, which performs type and dictionary specialisation."] .+ Deep+    ]  ------------------------------------------------------------------------ -{--lookupRule :: (Activation -> Bool)	-- When rule is active-	    -> IdUnfoldingFun		-- When Id can be unfolded-            -> InScopeSet-	    -> Id -> [CoreExpr]-	    -> [CoreRule] -> Maybe (CoreRule, CoreExpr)--GHC HEAD:-type InScopeEnv = (InScopeSet, IdUnfoldingFun)+newtype RuleName = RuleName String deriving (Eq, Typeable) -lookupRule :: DynFlags -> InScopeEnv-           -> (Activation -> Bool)      -- When rule is active-           -> Id -> [CoreExpr]-           -> [CoreRule] -> Maybe (CoreRule, CoreExpr)--}+instance Extern RuleName where+    type Box RuleName = RuleName+    box = id+    unbox = id --- Neil: Commented this out as it's not (currently) used.--- rulesToEnv :: [CoreRule] -> Map.Map String (Rewrite c m CoreExpr)--- rulesToEnv rs = Map.fromList---         [ ( unpackFS (ruleName r), rulesToRewrite c m [r] )---         | r <- rs---         ]+instance IsString RuleName where fromString = RuleName+instance Show RuleName where show (RuleName s) = s -type RuleNameString = String+newtype RuleNameListBox = RuleNameListBox [RuleName] deriving Typeable --- TODO: deprecate this (and related functions) in favor of 'biRuleUnsafeR'-#if __GLASGOW_HASKELL__ > 706-rulesToRewriteH :: (ReadBindings c, HasDynFlags m, MonadCatch m) => [CoreRule] -> Rewrite c m CoreExpr-#else-rulesToRewriteH :: (ReadBindings c, MonadCatch m) => [CoreRule] -> Rewrite c m CoreExpr-#endif-rulesToRewriteH rs = prefixFailMsg "RulesToRewrite failed: " $-                     withPatFailMsg "rule not matched." $ do-    (Var fn, args) <- callT-    transform $ \ c e -> do-        let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- varSetElems (localFreeVarsExpr e) ])-#if __GLASGOW_HASKELL__ > 706-        dflags <- getDynFlags-        case lookupRule dflags (in_scope, const NoUnfolding) (const True) fn args [r | r <- rs, ru_fn r == idName fn] of-#else-        case lookupRule (const True) (const NoUnfolding) in_scope fn args [r | r <- rs, ru_fn r == idName fn] of-#endif-            Nothing         -> fail "rule not matched"-            Just (r, expr)  -> do-                let e' = mkApps expr (drop (ruleArity r) args)-                if all (inScope c) $ varSetElems $ localFreeVarsExpr e' -- TODO: The problem with this check, is that it precludes the case where this is an intermediate transformation.  I can imagine situations where some variables would be out-of-scope at this point, but in scope again after a subsequent transformation.-                  then return e'-                  else fail $ unlines ["Resulting expression after rule application contains variables that are not in scope."-                                      ,"This can probably be solved by running the flatten-module command at the top level."]+instance Extern [RuleName] where+    type Box [RuleName] = RuleNameListBox+    box = RuleNameListBox+    unbox (RuleNameListBox l) = l --- | Lookup a rule and attempt to construct a corresponding rewrite.-ruleR :: (ReadBindings c, HasCoreRules c) => RuleNameString -> Rewrite c HermitM CoreExpr-ruleR r = do-    theRules <- getHermitRulesT-    case lookup r theRules of-        Nothing -> fail $ "failed to find rule: " ++ show r ++ ". If you think the rule exists, try running the flatten-module command at the top level."-        Just rr -> rulesToRewriteH [rr]+-- | Lookup a rule by name, attempt to apply it. If successful, record it as an unproven lemma.+ruleR :: ( AddBindings c, ExtendPath c Crumb, HasCoreRules c, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+         , HasDynFlags m, HasHermitMEnv m, HasLemmas m, LiftCoreM m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+      => RuleName -> Rewrite c m CoreExpr+ruleR nm = do+    eq <- ruleNameToEqualityT nm+    forwardT (birewrite eq) >>> sideEffectR (\ _ _ -> addLemma (fromString (show nm)) $ Lemma eq False True) -rulesR :: (ReadBindings c, HasCoreRules c) => [RuleNameString] -> Rewrite c HermitM CoreExpr+rulesR :: ( AddBindings c, ExtendPath c Crumb, HasCoreRules c, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+          , HasDynFlags m, HasHermitMEnv m, HasLemmas m, LiftCoreM m, MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+       => [RuleName] -> Rewrite c m CoreExpr rulesR = orR . map ruleR --- | Return all the RULES (including specialization RULES on binders) currently in scope.-getHermitRulesT :: HasCoreRules c => Transform c HermitM a [(RuleNameString, CoreRule)]+-- | Return all in-scope CoreRules (including specialization RULES on binders), with their names.+getHermitRulesT :: (HasCoreRules c, HasHermitMEnv m, LiftCoreM m, MonadIO m) => Transform c m a [(RuleName, CoreRule)] getHermitRulesT = contextonlyT $ \ c -> do     rb      <- liftCoreM getRuleBase     mgRules <- liftM mg_rules getModGuts     hscEnv  <- liftCoreM getHscEnv     rb'     <- liftM eps_rule_base $ liftIO $ runIOEnv () $ readMutVar (hsc_EPS hscEnv)-    return [ (unpackFS (ruleName r), r)-           | r <- hermitCoreRules c ++ mgRules ++ concat (nameEnvElts rb) ++ concat (nameEnvElts rb')-           ]+    let allRules = hermitCoreRules c ++ mgRules ++ concat (nameEnvElts rb) ++ concat (nameEnvElts rb')+    return [ (fromString (unpackFS (ruleName r)), r) | r <- allRules ] -getHermitRuleT :: HasCoreRules c => RuleNameString -> Transform c HermitM a CoreRule+-- | Get a GHC CoreRule by name.+getHermitRuleT :: (HasCoreRules c, HasHermitMEnv m, LiftCoreM m, MonadIO m) => RuleName -> Transform c m a CoreRule getHermitRuleT name =   do rulesEnv <- getHermitRulesT      case filter ((name ==) . fst) rulesEnv of-       []      -> fail ("Rule \"" ++ name ++ "\" not found.")+       []      -> fail $ "failed to find rule: " ++ show name ++ ". If you think the rule exists, "+                         ++ "try running the flatten-module command at the top level."        [(_,r)] -> return r-       _       -> fail ("Rule name \"" ++ name ++ "\" is ambiguous.")+       _       -> fail ("Rule name \"" ++ show name ++ "\" is ambiguous.") -rulesHelpListT :: HasCoreRules c => Transform c HermitM a String+-- | List names of all CoreRules in scope.+rulesHelpListT :: (HasCoreRules c, HasHermitMEnv m, LiftCoreM m, MonadIO m) => Transform c m a String rulesHelpListT = do     rulesEnv <- getHermitRulesT-    return (intercalate "\n" $ reverse $ map fst rulesEnv)--ruleHelpT :: HasCoreRules c => RuleNameString -> Transform c HermitM a String-ruleHelpT name = showSDoc <$> dynFlagsT <*> ((pprRulesForUser . (:[])) <$> getHermitRuleT name)---- Too much information.--- rulesHelpT :: HasCoreRules c => Transform c HermitM a String--- rulesHelpT = do---     rulesEnv <- getHermitRulesT---     dynFlags <- dynFlagsT---     return  $ (show (map fst rulesEnv) ++ "\n") ++---               showSDoc dynFlags (pprRulesForUser $ concatMap snd rulesEnv)+    return (intercalate "\n" $ reverse $ map (show.fst) rulesEnv) -makeRule :: RuleNameString -> Id -> CoreExpr -> CoreRule-makeRule rule_name nm =   mkRule True   -- auto-generated-                                 False  -- local-                                 (mkFastString rule_name)-                                 NeverActive    -- because we need to call for these-                                 (varName nm)-                                 []-                                 []+-- | Print a named CoreRule using GHC's pretty printer for rewrite rules.+-- TODO: use our own Equality pretty printer.+ruleHelpT :: (HasCoreRules c, HasDynFlags m, HasHermitMEnv m, LiftCoreM m, MonadIO m)+          => RuleName -> Transform c m a String+ruleHelpT nm = do+    r <- getHermitRuleT nm+    dflags <- dynFlagsT+    return $ showSDoc dflags $ pprRulesForUser [r] --- TODO: check if a top-level binding-addCoreBindAsRule :: Monad m => RuleNameString -> String -> Rewrite c m ModGuts-addCoreBindAsRule rule_name nm = contextfreeT $ \ modGuts ->-        case [ (v,e)-             | bnd   <- mg_binds modGuts-             , (v,e) <- bindToVarExprs bnd-             ,  nm `cmpString2Var` v-             ] of-         [] -> fail $ "cannot find binding " ++ nm-         [(v,e)] -> return $ modGuts { mg_rules = mg_rules modGuts-                                              ++ [makeRule rule_name v e]-                                     }-         _ -> fail $ "found multiple bindings for " ++ nm+-- | Build an Equality from a named GHC rewrite rule.+ruleNameToEqualityT :: ( BoundVars c, HasCoreRules c, HasDynFlags m, HasHermitMEnv m+                       , LiftCoreM m, MonadCatch m, MonadIO m, MonadThings m )+                    => RuleName -> Transform c m a Equality+ruleNameToEqualityT name = getHermitRuleT name >>> ruleToEqualityT --- | Returns the universally quantified binders, the LHS, and the RHS.-ruleToEqualityT :: (BoundVars c, HasDynFlags m, HasModGuts m, MonadThings m, MonadCatch m) => Transform c m CoreRule CoreExprEquality+-- | Transform GHC's CoreRule into an Equality.+ruleToEqualityT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, MonadThings m, MonadCatch m)+                => Transform c m CoreRule Equality ruleToEqualityT = withPatFailMsg "HERMIT cannot handle built-in rules yet." $   do r@Rule{} <- idR -- other possibility is "BuiltinRule"-     f <- lookupId $ ru_fn r -     return $ CoreExprEquality (ru_bndrs r) (mkCoreApps (Var f) (ru_args r)) (ru_rhs r)--ruleNameToEqualityT :: (BoundVars c, HasCoreRules c) => RuleNameString -> Transform c HermitM a CoreExprEquality-ruleNameToEqualityT name = getHermitRuleT name >>> ruleToEqualityT+     f <- lookupId $ ru_fn r+     return $ Equality (ru_bndrs r) (mkCoreApps (Var f) (ru_args r)) (ru_rhs r)  ------------------------------------------------------------------------ @@ -207,20 +156,20 @@     rs' <- return e' >>> extractT specRules     let specRs = deleteFirstsBy ((==) `on` ru_name) rs' rs     guardMsg (notNull specRs) "no rules created."-    return e' >>> extractR (repeatR (anyCallR (promoteExprR $ rulesToRewriteH specRs)))+    let applyAllR = extractR+                  $ repeatR+                  $ anyCallR+                  $ promoteExprR+                  $ rulesToRewrite specRs+    return e' >>> applyAllR  -- | Run GHC's specialisation pass, and apply any rules generated.-specialise :: RewriteH ModGuts-specialise = prefixFailMsg "specialisation failed: " $ do+specialiseR :: RewriteH ModGuts+specialiseR = prefixFailMsg "specialisation failed: " $ do     gRules <- arr mg_rules     lRules <- extractT specRules -#if __GLASGOW_HASKELL__ <= 706-    dflags <- dynFlagsT-    guts <- contextfreeT $ liftCoreM . Specialise.specProgram dflags-#else     guts <- contextfreeT $ liftCoreM . Specialise.specProgram-#endif      lRules' <- return guts >>> extractT specRules -- spec rules on bindings in this module     let gRules' = mg_rules guts            -- plus spec rules on imported bindings@@ -229,7 +178,7 @@         specRs = gSpecRs ++ lSpecRs     guardMsg (notNull specRs) "no rules created."     liftIO $ putStrLn $ unlines $ map (unpackFS . ru_name) specRs-    return guts >>> extractR (repeatR (anyCallR (promoteExprR $ rulesToRewriteH specRs)))+    return guts >>> extractR (repeatR (anyCallR (promoteExprR $ rulesToRewrite specRs)))  -- | Get all the specialization rules on a binding. --   These are created by SpecConstr and other GHC passes.@@ -246,5 +195,13 @@ -- | Find all specialization rules in a Core fragment. specRules :: TransformH Core [CoreRule] specRules = crushtdT $ promoteBindT bindSpecRules++-- | Turn a list of rules into a rewrite which succeeds on the first successful rule.+-- Note: this should only be used for built-in and compiler-generated rules which we assume+-- are correct, because it does not record a lemma obligation for the rules used.+rulesToRewrite :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+                  , HasDynFlags m, HasHermitMEnv m, MonadCatch m, MonadThings m, MonadUnique m )+               => [CoreRule] -> Rewrite c m CoreExpr+rulesToRewrite rs = catchesM [ (return r >>> ruleToEqualityT) >>= forwardT . birewrite | r <- rs ]  ------------------------------------------------------------------------
src/HERMIT/Dictionary/Undefined.hs view
@@ -3,6 +3,7 @@     ( -- * Working with Undefined Values       -- | Note that many of these operations require 'GHC.Err.undefined' to be explicitly imported if it is not used in the source file.       externals+    , buildStrictnessLemmaT     , verifyStrictT     , mkUndefinedValT     , isUndefinedValT@@ -18,12 +19,12 @@     , undefinedCaseR     , undefinedCastR     , undefinedTickR-    )-where+    ) where -import Control.Monad ((>=>))+import Control.Monad ((>=>), liftM) import Control.Monad.IO.Class import Data.Monoid+import Data.String (fromString)  import HERMIT.Context import HERMIT.Core@@ -31,6 +32,7 @@ import HERMIT.GHC hiding ((<>)) import HERMIT.Kure import HERMIT.Monad+import HERMIT.Name  import HERMIT.Dictionary.Common import HERMIT.Dictionary.GHC (substR)@@ -43,7 +45,7 @@     [ external "replace-current-expr-with-undefined" (promoteExprR replaceCurrentExprWithUndefinedR :: RewriteH Core)         [ "Set the current expression to \"undefined\"."         ] .+ Shallow .+ Context .+ Unsafe-    , external "replace-id-with-undefined" (replaceIdWithUndefined :: String -> RewriteH Core)+    , external "replace-id-with-undefined" (replaceIdWithUndefined :: HermitName -> RewriteH Core)         [ "Replace the specified identifier with \"undefined\"."         ] .+ Deep .+ Context .+ Unsafe     , external "error-to-undefined" (promoteExprR errorToUndefinedR :: RewriteH Core)@@ -79,48 +81,46 @@  ------------------------------------------------------------------------ -undefinedLocation :: String-undefinedLocation = "GHC.Err.undefined"+undefinedLocation :: HermitName+undefinedLocation = fromString "GHC.Err.undefined" --- TODO: will crash if 'undefined' is not used (or explicitly imported) in the source file.-findUndefinedIdT :: (BoundVars c, MonadCatch m, HasModGuts m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m a Id+findUndefinedIdT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m a Id findUndefinedIdT = findIdT undefinedLocation  -- | Check if the current expression is an undefined value.-isUndefinedValT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m CoreExpr ()+isUndefinedValT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m CoreExpr () isUndefinedValT = prefixFailMsg "not an undefined value: " $                   withPatFailMsg (wrongExprForm "App (Var undefined) (Type ty)") $                   do App (Var un) (Type _) <- idR                      un' <- findUndefinedIdT-                     guardMsg (un == un') ("identifier is not " ++ undefinedLocation)+                     guardMsg (un == un') ("identifier is not " ++ show undefinedLocation)  ------------------------------------------------------------------------ -errorLocation :: String-errorLocation = "GHC.Err.error"+errorLocation :: HermitName+errorLocation = fromString "GHC.Err.error" --- TODO: will crash if 'error' is not used (or explicitly imported) in the source file.-findErrorIdT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m a Id+findErrorIdT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m a Id findErrorIdT = findIdT errorLocation  -- | Check if the current expression is an undefined value.-isErrorValT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m CoreExpr ()+isErrorValT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Transform c m CoreExpr () isErrorValT = prefixFailMsg "not an error value: " $               withPatFailMsg (wrongExprForm "App (App (Var error) (Type ty)) string") $               do App (App (Var er) (Type _)) _ <- idR                  er' <- findErrorIdT-                 guardMsg (er == er') ("identifier is not " ++ errorLocation)+                 guardMsg (er == er') ("identifier is not " ++ show errorLocation)  ------------------------------------------------------------------------  -- | error ty string ==> undefined ty-errorToUndefinedR :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+errorToUndefinedR :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr errorToUndefinedR = prefixFailMsg "error-to-undefined failed: " (isErrorValT >> replaceCurrentExprWithUndefinedR)  ------------------------------------------------------------------------  -- | Make an undefined value of the given type.-mkUndefinedValT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Type -> Transform c m a CoreExpr+mkUndefinedValT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Type -> Transform c m a CoreExpr mkUndefinedValT ty =   do un <- findUndefinedIdT      return $ App (varToCoreExpr un) (Type ty)@@ -128,67 +128,67 @@ ------------------------------------------------------------------------------------------------------  -- | Set the current expression to 'undefined'.-replaceCurrentExprWithUndefinedR :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+replaceCurrentExprWithUndefinedR :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr replaceCurrentExprWithUndefinedR = contextfreeT exprTypeM >>= mkUndefinedValT  -- | Replace all occurrences of the specified identifier with 'undefined'.-replaceIdWithUndefinedR :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Id -> Rewrite c m Core+replaceIdWithUndefinedR :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Id -> Rewrite c m Core replaceIdWithUndefinedR i = mkUndefinedValT (idType i) >>= substR i -replaceIdWithUndefined :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => String -> Rewrite c m Core+replaceIdWithUndefined :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m)                        => HermitName -> Rewrite c m Core replaceIdWithUndefined = findIdT >=> replaceIdWithUndefinedR  ------------------------------------------------------------------------------------------------------  -- | undefinedExprR = undefinedAppR <+ undefinedLamR <+ undefinedLetR <+ undefinedCastR <+ undefinedTickR <+ undefinedCaseR-undefinedExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedExprR = setFailMsg "undefined-expr failed."                    (undefinedAppR <+ undefinedLamR <+ undefinedLetR <+ undefinedCastR <+ undefinedTickR <+ undefinedCaseR)  ------------------------------------------------------------------------------------------------------  -- | @(undefined ty1) e@ ==> @undefined ty2@-undefinedAppR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedAppR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedAppR = prefixFailMsg "undefined-app failed: " $                 do appT isUndefinedValT successT (<>)                    replaceCurrentExprWithUndefinedR  -- | @(\ v -> undefined ty1)@ ==> @undefined ty2@  (where v is not a 'TyVar')-undefinedLamR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedLamR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedLamR = prefixFailMsg "undefined-lam failed: " $                 do lamT successT isUndefinedValT (<>)                    replaceCurrentExprWithUndefinedR  -- | let bds in (undefined ty) ==> undefined ty-undefinedLetR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedLetR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedLetR = prefixFailMsg "undefined-let failed: " $                 do letT successT isUndefinedValT (<>)                    replaceCurrentExprWithUndefinedR  -- | Cast (undefined ty1) co ==> undefined ty2-undefinedCastR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedCastR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedCastR = prefixFailMsg "undefined-cast failed: " $                 do castT isUndefinedValT successT (<>)                    replaceCurrentExprWithUndefinedR  -- | Tick tick (undefined ty1) ==> undefined ty1-undefinedTickR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedTickR :: (BoundVars c, ExtendPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedTickR = prefixFailMsg "undefined-tick failed: " $                 do tickT successT isUndefinedValT (<>)                    replaceCurrentExprWithUndefinedR  -- | undefinedCaseR = undefinedCaseScrutineeR <+ undefinedCaseAltsR-undefinedCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedCaseR = setFailMsg "undefined-case failed" (undefinedCaseScrutineeR <+ undefinedCaseAltsR)  -- | case (undefined ty) of alts ==> undefined ty-undefinedCaseScrutineeR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedCaseScrutineeR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedCaseScrutineeR = prefixFailMsg "undefined-case failed: " $                  do caseT isUndefinedValT successT successT (const successT) (\ _ _ _ _ -> ())                     replaceCurrentExprWithUndefinedR  -- | case e of {pat_1 -> undefined ty ; pat_2 -> undefined ty ; ... ; pat_n -> undefined ty} ==> undefined ty-undefinedCaseAltsR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr+undefinedCaseAltsR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => Rewrite c m CoreExpr undefinedCaseAltsR = prefixFailMsg "undefined-case-alts failed: " $                      do caseAltT successT successT successT (const (successT,const successT,isUndefinedValT)) (\ _ _ _ _ -> ())                         replaceCurrentExprWithUndefinedR@@ -196,12 +196,30 @@ ------------------------------------------------------------------------  -- | Verify that the given rewrite is a proof that the given expression is a strict function.-verifyStrictT :: (BoundVars c, MonadCatch m, HasModGuts m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => CoreExpr -> Rewrite c m CoreExpr -> Transform c m a ()+verifyStrictT :: (BoundVars c, MonadCatch m, HasHermitMEnv m, HasDynFlags m, HasHscEnv m, MonadIO m, MonadThings m) => CoreExpr -> Rewrite c m CoreExpr -> Transform c m a () verifyStrictT f r = prefixFailMsg "strictness verification failed: " $-  do (argTy, resTy) <- constT (funExprArgResTypes f)+  do (_, argTy, resTy) <- constT (funExprArgResTypesM f)      undefArg       <- mkUndefinedValT argTy      rhs            <- mkUndefinedValT resTy      let lhs = App f undefArg      verifyEqualityLeftToRightT lhs rhs r++-- | Apply the given expression to undefined, at the proper type.+applyToUndefinedT :: (BoundVars c, HasDynFlags m, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+                  => CoreExpr -> Transform c m x CoreExpr+applyToUndefinedT f = do+    let (tvs, body) = collectTyBinders f+    (_,dom,_) <- splitFunTypeM (exprType body)+    undef <- mkUndefinedValT dom+    return $ mkCoreLams tvs $ mkCoreApp body undef++-- | Add a lemma for the strictness of a function.+-- Note: assumes added lemma has been used+buildStrictnessLemmaT :: (BoundVars c, HasDynFlags m, HasHscEnv m, HasHermitMEnv m, HasLemmas m, MonadCatch m, MonadIO m, MonadThings m)+                      => LemmaName -> CoreExpr -> Transform c m x ()+buildStrictnessLemmaT nm f = do+    (tvs, lhs) <- liftM collectTyBinders $ applyToUndefinedT f+    rhs <- mkUndefinedValT (exprType lhs)+    constT $ insertLemma nm $ Lemma (Equality tvs lhs rhs) False True  ------------------------------------------------------------------------
src/HERMIT/Dictionary/Unfold.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE FlexibleContexts, ScopedTypeVariables, TupleSections, LambdaCase #-} module HERMIT.Dictionary.Unfold     ( externals-    , cleanupUnfoldR+    , betaReducePlusR     , rememberR     , showStashT     , unfoldR@@ -22,15 +22,16 @@ import HERMIT.PrettyPrinter.Common (DocH, PrettyH, TransformDocH(..), PrettyC)  import HERMIT.Dictionary.Common+import HERMIT.Dictionary.GHC (substCoreExpr) import HERMIT.Dictionary.Inline (inlineR)-import HERMIT.Dictionary.Local.Let (letNonRecSubstR)  import HERMIT.Core import HERMIT.Context-import HERMIT.Kure-import HERMIT.Monad import HERMIT.External import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name  import Prelude hiding (exp) @@ -40,17 +41,17 @@  externals :: [External] externals =-    [ external "cleanup-unfold" (promoteExprR cleanupUnfoldR :: RewriteH Core)-        [ "Clean up immediately nested fully-applied lambdas, from the bottom up" ] .+ Deep-    , external "remember" (rememberR :: Label -> RewriteH Core)+    [ external "beta-reduce-plus" (promoteExprR betaReducePlusR :: RewriteH Core)+        [ "Perform one or more beta-reductions."]                               .+ Eval .+ Shallow+    , external "remember" (rememberR :: RememberedName -> RewriteH Core)         [ "Remember the current binding, allowing it to be folded/unfolded in the future." ] .+ Context-    , external "unfold-remembered" (promoteExprR . unfoldStashR :: String -> RewriteH Core)+    , external "unfold-remembered" (promoteExprR . unfoldStashR :: RememberedName -> RewriteH Core)         [ "Unfold a remembered definition." ] .+ Deep .+ Context     , external "unfold" (promoteExprR unfoldR :: RewriteH Core)         [ "In application f x y z, unfold f." ] .+ Deep .+ Context-    , external "unfold" (promoteExprR . unfoldNameR :: String -> RewriteH Core)+    , external "unfold" (promoteExprR . unfoldNameR . unOccurrenceName :: OccurrenceName -> RewriteH Core)         [ "Inline a definition, and apply the arguments; traditional unfold." ] .+ Deep .+ Context-    , external "unfold" (promoteExprR . unfoldNamesR :: [String] -> RewriteH Core)+    , external "unfold" (promoteExprR . unfoldNamesR . map unOccurrenceName:: [OccurrenceName] -> RewriteH Core)         [ "Unfold a definition if it is named in the list." ] .+ Deep .+ Context     , external "unfold-saturated" (promoteExprR unfoldSaturatedR :: RewriteH Core)         [ "Unfold a definition only if the function is fully applied." ] .+ Deep .+ Context@@ -62,44 +63,41 @@  ------------------------------------------------------------------------ --- | cleanupUnfoldR cleans a unfold operation---  (for example, an inline or rule application)--- It is used at the level of the top-redex.--- Invariant: will not introduce let bindings-cleanupUnfoldR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr-cleanupUnfoldR = do-    (f, args) <- callT <+ arr (,[])-    let (vs, body) = collectBinders f-        lenargs = length args-        lenvs = length vs-        comp = compare lenargs lenvs-        body' = case comp of-                    LT -> mkCoreLams (drop lenargs vs) body-                    _  -> body-        bnds = zipWith NonRec vs args-    body'' <- andR (replicate (length bnds) letNonRecSubstR) <<< return (mkCoreLets bnds body')-    return $ case comp of-                GT -> mkCoreApps body'' $ drop lenvs args-                _  -> body''+-- | Perform one or more beta reductions.+betaReducePlusR :: MonadCatch m => Rewrite c m CoreExpr+betaReducePlusR = prefixFailMsg "Multi-beta-reduction failed: " $ do+    (f,args) <- callT+    let (f',args',atLeastOne) = reduceAll f args False+        reduceAll (Lam v body) (a:as) _ = reduceAll (substCoreExpr v a body) as True+        reduceAll e            as     b = (e,as,b)+    guardMsg atLeastOne "no beta reductions possible."+    return $ mkCoreApps f' args'  -- | A more powerful 'inline'. Matches two cases: --      Var ==> inlines --      App ==> inlines the head of the function call for the app tree-unfoldR :: forall c. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr-unfoldR = prefixFailMsg "unfold failed: " (go >>> cleanupUnfoldR)-    where go :: Rewrite c HermitM CoreExpr+unfoldR :: forall c m. ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c+                       , ReadBindings c, ReadPath c Crumb, MonadCatch m )+        => Rewrite c m CoreExpr+unfoldR = prefixFailMsg "unfold failed: " (go >>> tryR betaReducePlusR)+    where go :: Rewrite c m CoreExpr           go = appAllR go idR <+ inlineR -- this order gives better error messages -unfoldPredR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => (Id -> [CoreExpr] -> Bool) -> Rewrite c HermitM CoreExpr+unfoldPredR :: ( AddBindings c, ExtendPath c Crumb, HasEmptyContext c, ReadBindings c, ReadPath c Crumb+               , MonadCatch m )+            => (Id -> [CoreExpr] -> Bool) -> Rewrite c m CoreExpr unfoldPredR p = callPredT p >> unfoldR -unfoldNameR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => String -> Rewrite c HermitM CoreExpr-unfoldNameR nm = prefixFailMsg ("unfold '" ++ nm ++ " failed: ") (callNameT nm >> unfoldR)+unfoldNameR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c+               , MonadCatch m )+            => HermitName -> Rewrite c m CoreExpr+unfoldNameR nm = prefixFailMsg ("unfold '" ++ show nm ++ " failed: ") (callNameT nm >> unfoldR) -unfoldNamesR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => [String] -> Rewrite c HermitM CoreExpr+unfoldNamesR :: ( ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c+                , MonadCatch m )+             => [HermitName] -> Rewrite c m CoreExpr unfoldNamesR []  = fail "unfold-names failed: no names given."-unfoldNamesR nms = setFailMsg "unfold-names failed." $-                   orR (map unfoldNameR nms)+unfoldNamesR nms = setFailMsg "unfold-names failed." $ orR (map unfoldNameR nms)  unfoldSaturatedR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, HasEmptyContext c) => Rewrite c HermitM CoreExpr unfoldSaturatedR = callSaturatedT >> unfoldR@@ -112,7 +110,7 @@  -- | Stash a binding with a name for later use. -- Allows us to look at past definitions.-rememberR :: Label -> Rewrite c HermitM Core+rememberR :: RememberedName -> Rewrite c HermitM Core rememberR label = sideEffectR $ \ _ -> \case                                           DefCore def           -> saveDef label def                                           BindCore (NonRec i e) -> saveDef label (Def i e)@@ -128,7 +126,7 @@ --         _           -> fail "remember: not a binding"  -- | Apply a stashed definition (like inline, but looks in stash instead of context).-unfoldStashR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr+unfoldStashR :: ReadBindings c => RememberedName -> Rewrite c HermitM CoreExpr unfoldStashR label = prefixFailMsg "Inlining stashed definition failed: " $                      withPatFailMsg (wrongExprForm "Var v") $     do (c, Var v) <- exposeT@@ -139,12 +137,12 @@                         in if all (inScope c) fvars                            then return rhs                            else fail $ "free variables " ++ intercalate "," (map (showPpr dflags) (filter (not . inScope c) fvars)) ++ " in stashed definition are no longer in scope."-                   else fail $ "stashed definition applies to " ++ var2String i ++ " not " ++ var2String v+                   else fail $ "stashed definition applies to " ++ unqualifiedName i ++ " not " ++ unqualifiedName v  showStashT :: Injection CoreDef a => PrettyC -> PrettyH a -> Transform c HermitM a DocH showStashT pctx pp = do     stash <- constT getStash     docs <- forM (Map.toList stash) $ \ (l,d) -> do-                dfn <- constT $ apply (extractT pp) pctx d-                return $ PP.text ("[ " ++ l ++ " ]") PP.$+$ dfn PP.$+$ PP.space+                dfn <- constT $ applyT (extractT pp) pctx d+                return $ PP.text ("[ " ++ show l ++ " ]") PP.$+$ dfn PP.$+$ PP.space     return $ PP.vcat docs
src/HERMIT/Dictionary/Unsafe.hs view
@@ -20,10 +20,10 @@ externals :: [External] externals = map (.+ Unsafe)     [ external "unsafe-replace" (promoteExprR . unsafeReplaceR :: CoreString -> RewriteH Core)-        [ "replace the currently focused expression with a new expression" +        [ "replace the currently focused expression with a new expression"         , "DOES NOT ensure that free variables in the replacement expression are in scope" ]-    , external "unsafe-replace" (promoteExprR . unsafeReplaceStashR :: String -> RewriteH Core)-        [ "replace the currently focused expression with an expression from the stash"+    , external "unsafe-replace" (promoteExprR . unsafeReplaceStashR :: RememberedName -> RewriteH Core)+        [ "replace the currently focused expression with a remembered expression"         , "DOES NOT ensure that free variables in the replacement expression are in scope" ]     ] @@ -36,7 +36,7 @@         guardMsg (eqType (exprKindOrType e) (exprKindOrType e')) "expression types differ."         return e' -unsafeReplaceStashR :: String -> RewriteH CoreExpr+unsafeReplaceStashR :: RememberedName -> RewriteH CoreExpr unsafeReplaceStashR label = prefixFailMsg "unsafe-replace failed: " $     contextfreeT $ \ e -> do         Def _ rhs <- lookupDef label
src/HERMIT/Dictionary/WorkerWrapper/Common.hs view
@@ -1,12 +1,82 @@-module HERMIT.Dictionary.WorkerWrapper.Common where+{-# LANGUAGE CPP, DeriveDataTypeable, TypeFamilies #-}+module HERMIT.Dictionary.WorkerWrapper.Common+    ( externals+    , WWAssumptionTag(..)+    , WWAssumption(..)+    , assumptionAEqualityT+    , assumptionBEqualityT+    , assumptionCEqualityT+    , split1BetaR+    , split2BetaR+    , workLabel+    ) where -import HERMIT.Monad-import HERMIT.Kure+import Control.Monad.IO.Class++import Data.String (fromString)+import Data.Typeable++import HERMIT.Context+import HERMIT.Core+import HERMIT.External import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.ParserCore +import HERMIT.Dictionary.Common+import HERMIT.Dictionary.Function hiding (externals)+import HERMIT.Dictionary.Reasoning hiding (externals)+import HERMIT.Name+ -------------------------------------------------------------------------------------------------- -data WWAssumptionTag = A | B | C deriving (Eq,Ord,Show,Read)+-- | New Worker/Wrapper-related externals.+externals :: [External]+externals = map (.+ Proof)+    [ external "intro-ww-assumption-A"+        (\nm absC repC -> do+            eq <- parse2BeforeT assumptionAEqualityT absC repC+            insertLemmaR nm $ Lemma eq False False :: RewriteH Core)+        [ "Introduce a lemma for worker/wrapper assumption A"+        , "using given abs and rep functions." ]+    , external "intro-ww-assumption-B"+        (\nm absC repC bodyC -> do+            eq <- parse3BeforeT assumptionBEqualityT absC repC bodyC+            insertLemmaR nm $ Lemma eq False False :: RewriteH Core)+        [ "Introduce a lemma for worker/wrapper assumption B"+        , "using given abs, rep, and body functions." ]+    , external "intro-ww-assumption-C"+        (\nm absC repC bodyC -> do+            eq <- parse3BeforeT assumptionCEqualityT absC repC bodyC+            insertLemmaR nm $ Lemma eq False False :: RewriteH Core)+        [ "Introduce a lemma for worker/wrapper assumption C"+        , "using given abs, rep, and body functions." ]+    , external "split-1-beta" (\ nm absC -> promoteExprR . parse2BeforeT (split1BetaR nm) absC :: CoreString -> RewriteH Core)+        [ "split-1-beta <name> <abs expression> <rep expression>"+        , "Perform worker/wrapper split with condition 1-beta."+        , "Given lemma name argument is used as prefix to two introduced lemmas."+        , "  <name>-assumption: unproven lemma for w/w assumption C."+        , "  <name>-fusion: assumed lemma for w/w fusion."+        ]+    , external "split-2-beta" (\ nm absC -> promoteExprR . parse2BeforeT (split2BetaR nm) absC :: CoreString -> RewriteH Core)+        [ "split-2-beta <name> <abs expression> <rep expression>"+        , "Perform worker/wrapper split with condition 2-beta."+        , "Given lemma name argument is used as prefix to two introduced lemmas."+        , "  <name>-assumption: unproven lemma for w/w assumption C."+        , "  <name>-fusion: assumed lemma for w/w fusion."+        ]+    ]++--------------------------------------------------------------------------------------------------++data WWAssumptionTag = A | B | C deriving (Eq,Ord,Show,Read,Typeable)++instance Extern WWAssumptionTag where+    type Box WWAssumptionTag = WWAssumptionTag+    box i = i+    unbox i = i+ data WWAssumption = WWAssumption WWAssumptionTag (RewriteH CoreExpr)  --------------------------------------------------------------------------------------------------@@ -17,7 +87,94 @@ -- That would have to exist at the Shell level though.  -- This isn't entirely safe, as a malicious the user could define a label with this name.-workLabel :: Label-workLabel = "recursive-definition-of-work-for-use-by-ww-fusion"+workLabel :: RememberedName+workLabel = fromString "recursive-definition-of-work-for-use-by-ww-fusion"  --------------------------------------------------------------------------------------------------++-- Given abs and rep expressions, build "abs . rep = id"+assumptionAEqualityT :: ( BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m+                        , MonadCatch m, MonadIO m, MonadThings m )+                     => CoreExpr -> CoreExpr -> Transform c m x Equality+assumptionAEqualityT absE repE = prefixFailMsg "Building assumption A failed: " $ do+    comp <- buildCompositionT absE repE+    let (_,compBody) = collectTyBinders comp+    (tvs, xTy, _) <- splitFunTypeM (exprType comp)+    idE <- buildIdT xTy+    return $ Equality tvs compBody idE++-- Given abs, rep, and f expressions, build "abs . rep . f = f"+assumptionBEqualityT :: ( BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m+                        , MonadCatch m, MonadIO m, MonadThings m)+                     => CoreExpr -> CoreExpr -> CoreExpr -> Transform c m x Equality+assumptionBEqualityT absE repE fE = prefixFailMsg "Building assumption B failed: " $ do+    repAfterF <- buildCompositionT repE fE+    comp <- buildCompositionT absE repAfterF+    let (tvs,lhs) = collectTyBinders comp+    rhs <- appArgM 5 lhs >>= appArgM 5 -- get f with proper tvs applied+    return $ Equality tvs lhs rhs++-- Given abs, rep, and f expressions, build "fix (abs . rep . f) = fix f"+assumptionCEqualityT :: (BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m)+                     => CoreExpr -> CoreExpr -> CoreExpr -> Transform c m x Equality+assumptionCEqualityT absE repE fE = prefixFailMsg "Building assumption C failed: " $ do+    Equality vs lhs rhs <- assumptionBEqualityT absE repE fE+    lhs' <- buildFixT lhs+    rhs' <- buildFixT rhs+    return $ Equality vs lhs' rhs'++-- Given abs, rep, and 'fix g' expressions, build "rep (abs (fix g)) = fix g"+wwFusionEqualityT :: (HasDynFlags m, MonadCatch m, MonadIO m)+                  => CoreExpr -> CoreExpr -> CoreExpr -> Transform c m x Equality+wwFusionEqualityT absE repE fixgE = prefixFailMsg "Building worker/wrapper fusion lemma failed: " $ do+    protoLhs <- buildApplicationM repE =<< buildApplicationM absE fixgE+    let (tvs, lhs) = collectTyBinders protoLhs+    -- This way, the rhs is applied to the proper type variables.+    rhs <- case lhs of+            (App _ (App _ rhs)) -> return rhs+            _                   -> fail "lhs malformed"+    return $ Equality tvs lhs rhs++-- Perform the worker/wrapper split using condition 1-beta, introducing+-- an unproven lemma for assumption C, and an appropriate w/w fusion lemma.+split1BetaR :: ( BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, HasLemmas m+               , MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+            => LemmaName -> CoreExpr -> CoreExpr -> Rewrite c m CoreExpr+split1BetaR nm absE repE = do+    (_fixId, [_tyA, f]) <- callNameT $ fromString "Data.Function.fix"++    g <- buildCompositionT repE =<< buildCompositionT f absE+    gId <- constT $ newIdH "g" $ exprType g++    workRhs <- buildFixT $ varToCoreExpr gId+    workId <- constT $ newIdH "worker" $ exprType workRhs++    newRhs <- buildApplicationM absE (varToCoreExpr workId)++    assumptionEq <- assumptionCEqualityT absE repE f+    _ <- insertLemmaR (fromString (show nm ++ "-assumption")) $ Lemma assumptionEq False True -- unproven, used++    wwFusionEq <- wwFusionEqualityT absE repE workRhs+    _ <- insertLemmaR (fromString (show nm ++ "-fusion")) $ Lemma wwFusionEq True False -- proven (assumed), unused++    return $ mkCoreLets [NonRec gId g, NonRec workId workRhs] newRhs++split2BetaR :: ( BoundVars c, HasDynFlags m, HasHermitMEnv m, HasHscEnv m, HasLemmas m+               , MonadCatch m, MonadIO m, MonadThings m, MonadUnique m )+            => LemmaName -> CoreExpr -> CoreExpr -> Rewrite c m CoreExpr+split2BetaR nm absE repE = do+    (_fixId, [_tyA, f]) <- callNameT $ fromString "Data.Function.fix"+    fixfE <- idR++    repFixFE <- buildApplicationM repE fixfE+    workId <- constT $ newIdH "worker" $ exprType repFixFE++    newRhs <- buildApplicationM absE (varToCoreExpr workId)++    assumptionEq <- assumptionCEqualityT absE repE f+    _ <- insertLemmaR (fromString (show nm ++ "-assumption")) $ Lemma assumptionEq False True -- unproven, used++    wwFusionEq <- wwFusionEqualityT absE repE (varToCoreExpr workId)+    _ <- insertLemmaR (fromString (show nm ++ "-fusion")) $ Lemma wwFusionEq True False -- proven (assumed), unused++    return $ mkCoreLets [NonRec workId repFixFE] newRhs
src/HERMIT/Dictionary/WorkerWrapper/Fix.hs view
@@ -1,28 +1,30 @@ module HERMIT.Dictionary.WorkerWrapper.Fix-       ( -- * The Worker/Wrapper Transformation-         -- | Note that many of these operations require 'Data.Function.fix' to be in scope.-         HERMIT.Dictionary.WorkerWrapper.Fix.externals-       , wwFacBR-       , wwSplitR-       , wwSplitStaticArg-       , wwGenerateFusionR-       , wwFusionBR-       , wwAssA-       , wwAssB-       , wwAssC-       )-where+    ( -- * The Worker/Wrapper Transformation+      -- | Note that many of these operations require 'Data.Function.fix' to be in scope.+      HERMIT.Dictionary.WorkerWrapper.Fix.externals+    , wwFacBR+    , wwSplitR+    , wwSplitStaticArg+    , wwGenerateFusionR+    , wwFusionBR+    , wwAssA+    , wwAssB+    , wwAssC+    ) where  import Control.Applicative import Control.Arrow +import Data.String (fromString)+ import HERMIT.Core-import HERMIT.Monad-import HERMIT.Kure import HERMIT.External import HERMIT.GHC-import HERMIT.Utilities+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name import HERMIT.ParserCore+import HERMIT.Utilities  import HERMIT.Dictionary.AlphaConversion import HERMIT.Dictionary.Common@@ -171,7 +173,7 @@                      guardMsg (eqType tyA tA) ("wrapper/unwrapper types do not match fix body type.")                      whenJust (verifyWWAss wrap unwrap f) mAss                      b <- constT (newIdH "x" tyB)-                     App wrap <$> mkFixT (Lam b (App unwrap (App f (App wrap (Var b)))))+                     App wrap <$> buildFixT (Lam b (App unwrap (App f (App wrap (Var b)))))      wwR :: RewriteH CoreExpr     wwR  =    prefixFailMsg "(reverse) worker/wrapper factorisation failed: " $@@ -183,7 +185,7 @@                       guardMsg (equivalentBy exprAlphaEq [wrap, wrap1, wrap2]) "wrappers do not match."                       guardMsg (exprAlphaEq unwrap unwrap1) "unwrappers do not match."                       whenJust (verifyWWAss wrap unwrap f) mAss-                      mkFixT f+                      buildFixT f      wrongFixBody :: String     wrongFixBody = "body of fix does not have the form Lam b (App unwrap (App f (App wrap (Var b))))"@@ -251,11 +253,11 @@ -- | \\ wrap unwrap ->  (@prog = expr@  ==>  @prog = let f = \\ prog -> expr in let work = unwrap (f (wrap work)) in wrap work)@ wwSplitR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> RewriteH CoreDef wwSplitR mAss wrap unwrap =-      fixIntroR+      fixIntroRecR       >>> defAllR idR ( appAllR idR (letIntroR "f")                         >>> letFloatArgR                         >>> letAllR idR ( forwardT (wwFacBR mAss wrap unwrap)-                                          >>> appAllR idR ( unfoldNameR "fix"+                                          >>> appAllR idR ( unfoldNameR (fromString "Data.Function.fix")                                                             >>> alphaLetWithR ["work"]                                                             >>> letRecAllR (\ _ -> defAllR idR (betaReduceR >>> letNonRecSubstR)                                                                                    >>> extractR (wwGenerateFusionR mAss)@@ -440,8 +442,8 @@   prefixFailMsg ("verification of worker/wrapper assumption C failed: ") $   do (tyA,_) <- wrapUnwrapTypes wrap unwrap      a       <- constT (newIdH "a" tyA)-     rhs     <- mkFixT f-     lhs     <- mkFixT (Lam a (App wrap (App unwrap (App f (Var a)))))+     rhs     <- buildFixT f+     lhs     <- buildFixT (Lam a (App wrap (App unwrap (App f (Var a)))))      verifyEqualityLeftToRightT lhs rhs assC  --------------------------------------------------------------------------------------------------
src/HERMIT/Dictionary/WorkerWrapper/FixResult.hs view
@@ -1,31 +1,33 @@ {-# LANGUAGE TupleSections #-}  module HERMIT.Dictionary.WorkerWrapper.FixResult-       ( -- * The Worker/Wrapper Transformation (Result Variant)-         -- | Note that many of these operations require 'Data.Function.fix' to be in scope.-         HERMIT.Dictionary.WorkerWrapper.FixResult.externals-       , wwResultFacBR-       , wwResultSplitR-       , wwResultSplitStaticArg-       , wwResultGenerateFusionR-       , wwResultFusionBR-       , wwResultAssA-       , wwResultAssB-       , wwResultAssC-       )-where+    ( -- * The Worker/Wrapper Transformation (Result Variant)+      -- | Note that many of these operations require 'Data.Function.fix' to be in scope.+      HERMIT.Dictionary.WorkerWrapper.FixResult.externals+    , wwResultFacBR+    , wwResultSplitR+    , wwResultSplitStaticArg+    , wwResultGenerateFusionR+    , wwResultFusionBR+    , wwResultAssA+    , wwResultAssB+    , wwResultAssC+    ) where  import Prelude hiding (abs)  import Control.Arrow +import Data.String (fromString)+ import HERMIT.Core-import HERMIT.Monad-import HERMIT.Kure import HERMIT.External import HERMIT.GHC-import HERMIT.Utilities+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name import HERMIT.ParserCore+import HERMIT.Utilities  import HERMIT.Dictionary.AlphaConversion import HERMIT.Dictionary.Common@@ -172,7 +174,7 @@     wwL :: Type -> Type -> RewriteH CoreExpr     wwL tyA tyB = prefixFailMsg "worker/wrapper factorisation failed: " $                   do (tyXA,f)  <- isFixExprT-                     (tyX,tA)  <- constT (splitFunTypeM tyXA)+                     (_,tyX,tA)  <- constT (splitFunTypeM tyXA)                      let tyXB  =  FunTy tyX tyB                      h         <- constT (newIdH "h" tyXB)                      guardMsg (eqType tyA tA) ("abs/rep types do not match fix body type.")@@ -182,7 +184,7 @@                       whenJust (verifyWWAss abs rep f) mAss -                     work <- mkFixT (Lam h (Lam x1 (App rep+                     work <- buildFixT (Lam h (Lam x1 (App rep                                                         (App (App f (Lam x2 (App abs (App (Var h) (Var x2)))))                                                              (Var x1)                                                         )@@ -203,7 +205,7 @@                  guardMsg (equivalentBy exprAlphaEq [abs, abs1, abs2]) "abs's do not match."                  guardMsg (exprAlphaEq rep rep1) "rep's do not match."                  whenJust (verifyWWAss abs rep f) mAss-                 mkFixT f+                 buildFixT f      wrongForm :: String     wrongForm = wrongExprForm "\\ x1 -> abs (fix (\\ h x2 -> rep (f (\\ x3 -> abs (h x3)) x2)) x1)"@@ -282,11 +284,11 @@ -- | \\ abs rep -> (@prog = expr@  ==>  @prog = let f = \\ prog -> expr in let work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1) in \\ x0 -> abs (work x0)@) wwResultSplitR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> RewriteH CoreDef wwResultSplitR mAss abs rep =-      fixIntroR+      fixIntroRecR       >>> defAllR idR ( appAllR idR (letIntroR "f")                         >>> letFloatArgR                         >>> letAllR idR ( forwardT (wwResultFacBR mAss abs rep)-                                          >>> lamAllR idR (appAllR idR (appAllR ( unfoldNameR "fix"+                                          >>> lamAllR idR (appAllR idR (appAllR ( unfoldNameR (fromString "Data.Function.fix")                                                                                   >>> alphaLetWithR ["work"]                                                                                   >>> letRecAllR (\ _ -> defAllR idR (betaReduceR >>> letNonRecSubstR)                                                                                                          >>> extractR (wwResultGenerateFusionR mAss)@@ -461,9 +463,9 @@            -> TransformH x () verifyAssB abs rep f assB =   prefixFailMsg ("verification of worker/wrapper assumption B failed: ") $-  do (tyA,_) <- absRepTypes abs rep-     tyXA     <- constT (endoFunExprType f)-     (tyX,tA) <- constT (splitFunTypeM tyXA)+  do (tyA,_)    <- absRepTypes abs rep+     (_,tyXA)   <- constT (endoFunExprTypeM f)+     (_,tyX,tA) <- constT (splitFunTypeM tyXA)      guardMsg (eqType tyA tA) "type of program body does not match types of abs/rep."      h        <- constT (newIdH "h" tyXA)      x        <- constT (newIdH "x" tyX)@@ -478,14 +480,14 @@            -> TransformH a () verifyAssC abs rep f assC =   prefixFailMsg ("verification of worker/wrapper assumption C failed: ") $-  do (tyA,_)  <- absRepTypes abs rep-     tyXA     <- constT (endoFunExprType f)-     (tyX,tA) <- constT (splitFunTypeM tyXA)+  do (tyA,_)    <- absRepTypes abs rep+     (_,tyXA)   <- constT (endoFunExprTypeM f)+     (_,tyX,tA) <- constT (splitFunTypeM tyXA)      guardMsg (eqType tyA tA) "type of program body does not match types of abs/rep."      h        <- constT (newIdH "h" tyXA)      x        <- constT (newIdH "x" tyX)-     rhs      <- mkFixT f-     lhs      <- mkFixT (Lam h (Lam x (App abs (App rep (App (App f (Var h)) (Var x))))))+     rhs      <- buildFixT f+     lhs      <- buildFixT (Lam h (Lam x (App abs (App rep (App (App f (Var h)) (Var x))))))      verifyEqualityLeftToRightT lhs rhs assC  --------------------------------------------------------------------------------------------------
src/HERMIT/Driver.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE ViewPatterns #-}-module HERMIT.Driver +module HERMIT.Driver     ( hermitVersion     , ghcFlags     , hermitDriver     , usage+    , usageOutput     ) where  import Data.List (isPrefixOf, partition)@@ -14,7 +15,7 @@ import System.Process import System.Exit -hermitVersion :: String   +hermitVersion :: String hermitVersion = "HERMIT v" ++ showVersion P.version  ghcFlags :: [String]@@ -26,11 +27,9 @@ --           , "-v0"            ] -usage :: IO ()-usage = putStrLn $ unlines-        [hermitVersion-        ,""-        ,"usage: hermit File.hs SCRIPTNAME"+usageOutput :: String+usageOutput = unlines+        ["usage: hermit File.hs SCRIPTNAME"         ,"       - OR -"         ,"       hermit File.hs [HERMIT_ARGS] [+module_name [MOD_ARGS]]* [-- [ghc-args]]"         ,""@@ -45,6 +44,7 @@         ,""         ,"HERMIT_ARGS"         ,"  -opt=MODULE : where MODULE is the module containing a HERMIT optimization plugin"+        ,"  -pN         : where 0<=N<=17 is the stage in the optimization pipeline HERMIT targets"         ,"  -vN         : controls verbosity, where N is one of the following values:"         ,"                  0 : suppress HERMIT messages, pass -v0 to GHC"         ,"                  1 : suppress HERMIT messages"@@ -56,7 +56,10 @@         ,"  resume     : skip interactive mode and resume compilation after any scripts"         ] --- | Entry point for HERMIT driver executable. +usage :: IO ()+usage = mapM_ putStrLn [hermitVersion, "", usageOutput]++-- | Entry point for HERMIT driver executable. -- First String in list is expected to be target file name. hermitDriver :: [String] -> IO () hermitDriver [] = usage
src/HERMIT/External.hs view
@@ -1,54 +1,52 @@ {-# LANGUAGE GADTs, TypeFamilies, FlexibleContexts, FlexibleInstances, DeriveDataTypeable #-}  module HERMIT.External-       (-       -- * Externals-         External-       , ExternalName-       , ExternalHelp-       , externName-       , externDyn-       , externHelp-       , externTypeString-       , externTypeArgResString-       , Dictionary-       , toDictionary-       , addToDictionary-       , toHelp-       , external-       , Extern(..)-       , matchingExternals-       -- * Tags-       , CmdTag(..)-       , TagE-       , Tag((.+),remTag,tagMatch)-       , (.&)-       , (.||)-       , notT-       , externTags-       , dictionaryOfTags-       -- * Boxes-       -- | Boxes are used by the 'Extern' class.-       , TagBox(..)-       , IntBox(..)-       , RewriteCoreBox(..)-       , RewriteCoreTCBox(..)-       , BiRewriteCoreBox(..)-       , TransformCoreStringBox(..)-       , TransformCoreTCStringBox(..)-       , TransformCoreCheckBox(..)-       , TransformCoreTCCheckBox(..)-       , TransformCorePathBox(..)-       , TransformCoreTCPathBox(..)-       , CoreString(..)-       , CoreBox(..)-       , CrumbBox(..)-       , PathBox(..)-       , StringBox(..)-       , StringListBox(..)-       , IntListBox(..)-       , RewriteCoreListBox(..)-) where+    ( -- * Externals+      External+    , ExternalName+    , ExternalHelp+    , externName+    , externDyn+    , externHelp+    , externTypeString+    , externTypeArgResString+    , splitFunTyArgs+    , toHelp+    , external+    , Extern(..)+    , matchingExternals+      -- * Tags+    , CmdTag(..)+    , TagE+    , Tag((.+),remTag,tagMatch)+    , (.&)+    , (.||)+    , notT+    , externTags+    , dictionaryOfTags+      -- * Boxes+      -- | Boxes are used by the 'Extern' class.+    , BiRewriteCoreBox(..)+    , CoreString(..)+    , CrumbBox(..)+    , IntBox(..)+    , IntListBox(..)+    , PathBox(..)+    , RewriteCoreBox(..)+    , RewriteCoreListBox(..)+    , RewriteCoreTCBox(..)+    , RewriteEqualityBox(..)+    , StringBox(..)+    , StringListBox(..)+    , TagBox(..)+    , TransformCoreCheckBox(..)+    , TransformCorePathBox(..)+    , TransformCoreStringBox(..)+    , TransformCoreTCCheckBox(..)+    , TransformCoreTCPathBox(..)+    , TransformCoreTCStringBox(..)+    , TransformEqualityStringBox(..)+    ) where  import Data.Map hiding (map) import Data.Dynamic@@ -58,6 +56,7 @@ import HERMIT.Core import HERMIT.Context (LocalPathH) import HERMIT.Kure+import HERMIT.Monad  ----------------------------------------------------------------- @@ -80,11 +79,12 @@             | Deep           -- ^ Command may make a deep change, can be O(n).             | Shallow        -- ^ Command operates on local nodes only, O(1).             | Navigation     -- ^ Uses 'Path' or 'Lens' to focus onto something.-            | Query          -- ^ A question we ask.+            | Query          -- ^ Extract information from an expression.             | Predicate      -- ^ Something that passes or fails.             | Introduce      -- ^ Introduce something, like a new name.             | Commute        -- ^ Commute is when you swap nested terms.             | PreCondition   -- ^ Operation has a (perhaps undocumented) precondition.+            | Strictness     -- ^ Alters the strictness of the expression.             | Debug          -- ^ Commands specifically to help debugging.             | VersionControl -- ^ Version control for Core syntax.             | Context        -- ^ A command that uses its context, such as inlining.@@ -96,22 +96,6 @@             | Experiment     -- ^ Things we are trying out.             | Deprecated     -- ^ A command that will be removed in a future release;                              --   it has probably been renamed or subsumed by another command.----- Unsure about these-{--            | Local         -- local thing, O(1)-            | CaseCmd       -- works on case statements-            | Context       -- something that uses the context-            | GHC           -- a tunnel into GHC-            | Lens          -- focuses into a specific node-            | LetCmd        -- works on let statements-            | Meta          -- combines other commands-            | Restful       -- RESTful API commands-            | Slow          -- this command is slow--}-            -- Other String-            -- etc     deriving (Eq, Show, Read, Bounded, Enum)  -- | Lists all the tags paired with a short description of what they're about.@@ -121,31 +105,30 @@                             , tag `notElem` map fst notes                             ]   where notes =-          -- These should give the user a clue about what the sub-commands-          -- might do-          [ (Shell,        "Shell-specific command.")-          , (Eval,         "The arrow of evaluation (reduces a term).")-          , (KURE,         "Direct reflection of a combinator from the KURE DSL.")-          , (Loop,         "Command may operate multiple times.")-          , (Deep,         "Command may make a deep change, can be O(n).")-          , (Shallow,      "Command operates on local nodes only, O(1).")-          , (Navigation,   "Navigate via focus, or directional command.")-          , (Query,        "A question we ask.")-          , (Predicate,    "Something that passes or fails.")-          , (Introduce,    "Introduce something, like a new name.")-          , (Commute,      "Commute is when you swap nested terms.")-          , (PreCondition, "Operation has a (perhaps undocumented) precondition.")-          , (Debug,        "A command specifically to help debugging.")-          , (VersionControl,"Version control for Core syntax.")-          , (Context,      "A command that uses its context, such as inlining.")-          , (Unsafe,       "Commands that are not type safe (may cause Core Lint to fail), or may otherwise change the semantics of the program.")-          , (Proof,        "Commands related to proving lemmas.")-          , (TODO,         "An incomplete or potentially buggy command.")-          , (Experiment,   "Things we are trying out, use at your own risk.")-          , (Deprecated,   "A command that will be removed in a future release; it has probably been renamed or subsumed by another command.")+          -- These should give the user a clue about what the sub-commands might do+          [ (Shell,          "Shell-specific command.")+          , (Eval,           "The arrow of evaluation (reduces a term).")+          , (KURE,           "Direct reflection of a combinator from the KURE DSL.")+          , (Loop,           "Command may operate multiple times.")+          , (Deep,           "Command may make a deep change, can be O(n).")+          , (Shallow,        "Command operates on local nodes only, O(1).")+          , (Navigation,     "Navigate via focus, or directional command.")+          , (Query,          "Extract information from an expression.")+          , (Predicate,      "Something that passes or fails.")+          , (Introduce,      "Introduce something, like a new name.")+          , (Commute,        "Commute is when you swap nested terms.")+          , (PreCondition,   "Operation has a (perhaps undocumented) precondition.")+          , (Strictness,     "Alters the strictness of an expression.")+          , (Debug,          "A command specifically to help debugging.")+          , (VersionControl, "Version control for Core syntax.")+          , (Context,        "A command that uses its context, such as inlining.")+          , (Unsafe,         "Commands that are not type safe (may cause Core Lint to fail), or may otherwise change the semantics of the program.")+          , (Proof,          "Commands related to proving lemmas.")+          , (TODO,           "An incomplete or potentially buggy command.")+          , (Experiment,     "Things we are trying out, use at your own risk.")+          , (Deprecated,     "A command that will be removed in a future release; it has probably been renamed or subsumed by another command.")           ] - -- Unfortunately, record update syntax seems to associate to the right. -- These operators save us some parentheses. infixl 3 .+@@ -234,20 +217,6 @@ matchingExternals tag exts = [ (e,tr) | e <- exts, tagMatch tag e                                       , Just tr <- [fmap unbox $ fromDynamic $ externDyn e] ] --- | A 'Dictionary' is a collection of 'Dynamic's.---   Looking up a 'Dynamic' (via an 'ExternalName' key) returns a list, as there can be multiple 'Dynamic's with the same name.-type Dictionary = Map ExternalName [Dynamic]---- | Build a 'Data.Map' from names to 'Dynamic' values.-toDictionary :: [External] -> Dictionary-toDictionary = fromListWith (++) . map toEntry--toEntry :: External -> (ExternalName, [Dynamic])-toEntry e = (externName e, [externDyn e])--addToDictionary :: External -> Dictionary -> Dictionary-addToDictionary ex d = fromListWith (++) $ toEntry ex : toList d- -- | Build a 'Data.Map' from names to help information. toHelp :: [External] -> Map ExternalName ExternalHelp toHelp = fromListWith (++) . map toH@@ -266,9 +235,9 @@  -- | Remove the word 'Box' from a string. deBoxify :: String -> String-deBoxify xs +deBoxify xs     | "CLSBox -> " `isPrefixOf` xs = deBoxify (drop 10 xs)-deBoxify xs +deBoxify xs     | "Box" `isPrefixOf` xs        = deBoxify (drop 3 xs) deBoxify (x:xs)                    = x : deBoxify xs deBoxify []                        = []@@ -435,14 +404,12 @@  ----------------------------------------------------------------- --- TODO: Is this deliberately called "CoreBox" rather than "CoreStringBox"?-newtype CoreString = CoreString { unCoreString :: String }-data CoreBox = CoreBox CoreString deriving Typeable+newtype CoreString = CoreString { unCoreString :: String } deriving Typeable  instance Extern CoreString where-    type Box CoreString = CoreBox-    box = CoreBox-    unbox (CoreBox s) = s+    type Box CoreString = CoreString+    box = id+    unbox = id  ----------------------------------------------------------------- @@ -479,5 +446,37 @@     type Box [RewriteH Core] = RewriteCoreListBox     box = RewriteCoreListBox     unbox (RewriteCoreListBox l) = l++-----------------------------------------------------------------++instance Extern RememberedName where+    type Box RememberedName = RememberedName+    box = id+    unbox = id++-----------------------------------------------------------------++instance Extern LemmaName where+    type Box LemmaName = LemmaName+    box = id+    unbox = id++-----------------------------------------------------------------++data RewriteEqualityBox = RewriteEqualityBox (RewriteH Equality) deriving Typeable++instance Extern (RewriteH Equality) where+    type Box (RewriteH Equality) = RewriteEqualityBox+    box = RewriteEqualityBox+    unbox (RewriteEqualityBox r) = r++-----------------------------------------------------------------++data TransformEqualityStringBox = TransformEqualityStringBox (TransformH Equality String) deriving Typeable++instance Extern (TransformH Equality String) where+    type Box (TransformH Equality String) = TransformEqualityStringBox+    box = TransformEqualityStringBox+    unbox (TransformEqualityStringBox t) = t  -----------------------------------------------------------------
src/HERMIT/GHC.hs view
@@ -1,7 +1,5 @@ {-# LANGUAGE CPP, InstanceSigs, TypeSynonymInstances, FlexibleInstances #-}-#if __GLASGOW_HASKELL__ > 706 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}-#endif -- Above shadowing disabled because the eqExprX function has lots of shadowing module HERMIT.GHC     ( -- * GHC Imports@@ -9,101 +7,95 @@       module GhcPlugins     , ppIdInfo     , zapVarOccInfo-    , var2String     , thRdrNameGuesses     , varNameNS     , isQualified     , cmpString2Name     , cmpString2Var-    , fqName-    , uqName-    , findNamesFromString+    , qualifiedName+    , unqualifiedName     , alphaTyVars     , Type(..)     , TyLit(..)     , GhcException(..)     , throwGhcException     , exprArity-    , occurAnalyseExpr+    , occurAnalyseExpr_NoBinderSwap     , isKind     , isLiftedTypeKindCon-#if __GLASGOW_HASKELL__ > 706-    , coAxiomName-    , CoAxiom.BranchIndex-    , CoAxiom.CoAxiom-    , CoAxiom.Branched-#endif     , notElemVarSet     , varSetToStrings     , showVarSet     , Pair(..)     , bndrRuleAndUnfoldingVars-#if __GLASGOW_HASKELL__ <= 706-    , exprType-    , Control.Monad.IO.Class.liftIO-#else-    , runDsMtoCoreM-    , runTcMtoCoreM-    , buildTypeable-    , buildDictionary+    , coAxiomName+    , CoAxiom.BranchIndex+    , CoAxiom.CoAxiom+    , CoAxiom.Branched+    , Bag.foldBag     , eqExprX-    , lookupRdrNameInModuleForPlugins+    , loadSysInterface+    , lookupRdrNameInModule+    , reportAllUnsolved+    , zEncodeString+#ifdef mingw32_HOST_OS+    , initStaticOpts #endif-    , mkPhiTy-    , mkSigmaTy+    , module Class+    , module DsBinds+    , module DsMonad+    , module ErrUtils+    , module PrelNames+    , module TcEnv+    , module TcMType+    , module TcRnMonad+    , module TcRnTypes+    , module TcSimplify+    , module TcType+    , module Unify     , getHscEnvCoreM     ) where -#if __GLASGOW_HASKELL__ <= 706--- GHC 7.6-import qualified Control.Monad.IO.Class-import qualified MonadUtils (MonadIO,liftIO)-import GhcPlugins hiding (exprFreeVars, exprFreeIds, bindFreeVars, exprType, liftIO, PluginPass, getHscEnv)-import TysPrim (alphaTy, alphaTyVars)-import Panic (throwGhcException, GhcException(..))-import PprCore (pprCoreExpr)-import Data.Monoid hiding ((<>))-#else--- GHC 7.8-import Finder (findImportedModule, cannotFindModule)--- we hide these so that they don't get inadvertently used.  See Core.hs-import GhcPlugins hiding (exprFreeVars, exprFreeIds, bindFreeVars, PluginPass, getHscEnv)-import LoadIface (loadPluginInterface)-import Panic (throwGhcException, throwGhcExceptionIO, GhcException(..))-import TcRnMonad (initIfaceTcRn)-import TysPrim (alphaTyVars)-#endif---- hacky direct GHC imports-import Convert (thRdrNameGuesses)-import CoreArity-import qualified CoreMonad -- for getHscEnv-import Kind (isKind,isLiftedTypeKindCon)-import qualified OccName -- for varName-import OccurAnal (occurAnalyseExpr)-import Pair (Pair(..))-import TcType (mkPhiTy, mkSigmaTy)-import TypeRep (Type(..),TyLit(..))--#if __GLASGOW_HASKELL__ <= 706-import Data.Maybe (isJust)-#else+-- Imports from GHC. import qualified Bag+import           Class (classTyCon) import qualified CoAxiom -- for coAxiomName-import DsBinds (dsEvBinds)-import DsMonad (DsM, initDsTc)-import PrelNames (typeableClassName)-import TcEnv (tcLookupClass)-import TcMType (newWantedEvVar)-import TcRnMonad (getCtLoc)-import TcRnTypes (TcM, mkNonCanonical, mkFlatWC, CtEvidence(..), SkolemInfo(..), CtOrigin(..))-import TcSimplify (solveWantedsTcM)--import HERMIT.GHC.Typechecker+import           Convert (thRdrNameGuesses)+import           CoreArity+import qualified CoreMonad -- for getHscEnv+import           DsBinds (dsEvBinds)+import           DsMonad (DsM, initDsTc)+import           Encoding (zEncodeString)+import           ErrUtils (pprErrMsgBag)+import           Finder (findImportedModule, cannotFindModule)+-- we hide these so that they don't get inadvertently used.+-- several are redefined in Core.hs and elsewhere+import           GhcPlugins hiding (exprFreeVars, exprFreeIds, bindFreeVars, PluginPass, getHscEnv, RuleName)+import           Kind (isKind,isLiftedTypeKindCon)+import           LoadIface (loadSysInterface)+import qualified OccName -- for varName+import           OccurAnal (occurAnalyseExpr_NoBinderSwap)+import           Pair (Pair(..))+import           Panic (throwGhcException, throwGhcExceptionIO, GhcException(..))+import           PrelNames (typeableClassName)+#if mingw32_HOST_OS+import           StaticFlags #endif+import           TcEnv (tcLookupClass)+import           TcErrors (reportAllUnsolved)+import           TcMType (newWantedEvVar)+import           TcRnMonad (getCtLoc, initIfaceTcRn)+import           TcRnTypes (TcM, mkNonCanonical, mkFlatWC, CtEvidence(..), SkolemInfo(..), CtOrigin(..))+import           TcSimplify (solveWantedsTcM)+import           TcType (mkPhiTy, mkSigmaTy)+import           TypeRep (Type(..),TyLit(..))+import           TysPrim (alphaTyVars)+import           Unify (tcUnifyTys, BindFlag(..))  import Data.List (intercalate) +import HERMIT.GHC.Typechecker+ --------------------------------------------------------------------------  -- | Rename this namespace, as 'varName' is already a function in Var.@@ -113,36 +105,11 @@ getHscEnvCoreM :: CoreM HscEnv getHscEnvCoreM = CoreMonad.getHscEnv -#if __GLASGOW_HASKELL__ <= 706--- Note: prior to 7.8, the Let case was buggy for type--- bindings, so we provide a fixed definition here.-exprType :: CoreExpr -> Type--- ^ Recover the type of a well-typed Core expression. Fails when--- applied to the actual 'CoreSyn.Type' expression as it cannot--- really be said to have a type-exprType (Var var)           = idType var-exprType (Lit lit)           = literalType lit-exprType (Coercion co)       = coercionType co-exprType (Let bind body)-  | NonRec tv rhs <- bind-  , Type ty <- rhs           = substTyWith [tv] [ty] (exprType body)-  | otherwise                = exprType body-exprType (Case _ _ ty _)     = ty-exprType (Cast _ co)         = pSnd (coercionKind co)-exprType (Tick _ e)          = exprType e-exprType (Lam binder expr)   = mkPiType binder (exprType expr)-exprType e@(App _ _)-  = case collectArgs e of-        (fun, args) -> applyTypeToArgs e (exprType fun) args--exprType other = pprTrace "exprType" (pprCoreExpr other) alphaTy-#endif- --------------------------------------------------------------------------  -- | Convert a 'VarSet' to a list of user-readable strings. varSetToStrings :: VarSet -> [String]-varSetToStrings = map var2String . varSetElems+varSetToStrings = map unqualifiedName . varSetElems  -- | Show a human-readable version of a 'VarSet'. showVarSet :: VarSet -> String@@ -150,13 +117,8 @@  -------------------------------------------------------------------------- -#if __GLASGOW_HASKELL__ <= 706--- coAxiomName :: CoAxiom -> Name--- coAxiomName = coAxiomName-#else coAxiomName :: CoAxiom.CoAxiom br -> Name coAxiomName = CoAxiom.coAxiomName-#endif  -- varName :: Var -> Name -- nameOccName :: Name -> OccName@@ -166,24 +128,20 @@ -- getOccString :: NamedThing a => a -> String  -- | Get the unqualified name from a 'NamedThing'.-uqName :: NamedThing nm => nm -> String-uqName = getOccString+unqualifiedName :: NamedThing nm => nm -> String+unqualifiedName = getOccString  -- | Get the fully qualified name from a 'Name'.-fqName :: Name -> String-fqName nm = modStr ++ uqName nm+qualifiedName :: Name -> String+qualifiedName nm = modStr ++ unqualifiedName nm     where modStr = maybe "" (\m -> moduleNameString (moduleName m) ++ ".") (nameModule_maybe nm) --- | Convert a variable to a neat string for printing (unqualfied name).-var2String :: Var -> String-var2String = uqName . varName- -- | Compare a 'String' to a 'Name' for equality. -- Strings containing a period are assumed to be fully qualified names. -- (Except for ".", which is an unqualified reference to composition.) cmpString2Name :: String -> Name -> Bool-cmpString2Name str nm | isQualified str = str == fqName nm-                      | otherwise       = str == uqName nm+cmpString2Name str nm | isQualified str = str == qualifiedName nm+                      | otherwise       = str == unqualifiedName nm  isQualified :: String -> Bool isQualified [] = False@@ -193,12 +151,6 @@ cmpString2Var :: String -> Var -> Bool cmpString2Var str = cmpString2Name str . varName --- | Find 'Name's matching a given fully qualified or unqualified name.-findNamesFromString :: GlobalRdrEnv -> String -> [Name]-findNamesFromString rdrEnv str | isQualified str = res-                               | otherwise       = res-    where res = [ nm | elt <- globalRdrEnvElts rdrEnv, let nm = gre_name elt, cmpString2Name str nm ]- -- | Pretty-print an identifier. ppIdInfo :: Id -> IdInfo -> SDoc ppIdInfo v info@@ -224,12 +176,7 @@     has_caf_info = not (mayHaveCafRefs caf_info)      str_info = strictnessInfo info-    has_strictness =-#if __GLASGOW_HASKELL__ > 706-        True-#else-        isJust str_info-#endif+    has_strictness = True      unf_info = unfoldingInfo info     has_unf = hasSomeUnfolding unf_info@@ -255,23 +202,8 @@ notElemVarSet :: Var -> VarSet -> Bool notElemVarSet v vs = not (v `elemVarSet` vs) -#if __GLASGOW_HASKELL__ <= 706-instance Monoid VarSet where-  mempty :: VarSet-  mempty = emptyVarSet--  mappend :: VarSet -> VarSet -> VarSet-  mappend = unionVarSet- -------------------------------------------------------------------------- -instance Control.Monad.IO.Class.MonadIO CoreM where-  liftIO :: IO a -> CoreM a-  liftIO = MonadUtils.liftIO-#endif----------------------------------------------------------------------------- -- This function is copied from GHC, which defines but doesn't expose it. -- A 'let' can bind a type variable, and idRuleVars assumes -- it's seeing an Id. This function tests first.@@ -281,44 +213,6 @@  -------------------------------------------------------------------------- -#if __GLASGOW_HASKELL__ > 706-runTcMtoCoreM :: ModGuts -> TcM a -> CoreM a-runTcMtoCoreM guts m = do-    env <- CoreMonad.getHscEnv-    -- What is the effect of HsSrcFile (should we be using something else?)-    -- What should the boolean flag be set to?-    (msgs, mr) <- liftIO $ initTcFromModGuts env guts HsSrcFile False m-    -- There is probably something better for reporting the errors.-    let dumpSDocs endMsg = Bag.foldBag (\ d r -> d ++ ('\n':r)) show endMsg-        showMsgs (warns, errs) = "Errors:\n" ++ dumpSDocs ("Warnings:\n" ++ dumpSDocs "" warns) errs-    maybe (fail $ showMsgs msgs) return mr--runDsMtoCoreM :: ModGuts -> DsM a -> CoreM a-runDsMtoCoreM guts = runTcMtoCoreM guts . initDsTc---- TODO: this is mostly an example, move somewhere?-buildTypeable :: ModGuts -> Type -> CoreM (Id, [CoreBind])-buildTypeable guts ty = do-    evar <- runTcMtoCoreM guts $ do-        cls <- tcLookupClass typeableClassName-        let predTy = mkClassPred cls [typeKind ty, ty] -- recall that Typeable is now poly-kinded-        newWantedEvVar predTy-    buildDictionary guts evar---- | Build a dictionary for the given-buildDictionary :: ModGuts -> Id -> CoreM (Id, [CoreBind])-buildDictionary guts evar = do-    (i, bs) <- runTcMtoCoreM guts $ do-        loc <- getCtLoc $ GivenOrigin UnkSkol-        let predTy = varType evar-            nonC = mkNonCanonical $ CtWanted { ctev_pred = predTy, ctev_evar = evar, ctev_loc = loc }-            wCs = mkFlatWC [nonC]-        (_wCs', bnds) <- solveWantedsTcM wCs-        -- TODO: check for unsolved constraints?-        return (evar, bnds)-    bnds <- runDsMtoCoreM guts $ dsEvBinds bs-    return (i,bnds)- -- This function used to be in GHC itself, but was removed. -- It compares core for equality modulo alpha. eqExprX :: IdUnfoldingFun -> RnEnv2 -> CoreExpr -> CoreExpr -> Bool@@ -391,10 +285,16 @@ -- * If the module could not be found -- * If we could not determine the imports of the module ----- This is adapted from GHC's function of the same name, but using--- initTcFromModGuts instead of initTcInteractive.-lookupRdrNameInModuleForPlugins :: HscEnv -> ModGuts -> ModuleName -> RdrName -> IO (Maybe Name)-lookupRdrNameInModuleForPlugins hsc_env guts mod_name rdr_name = do+-- This is adapted from GHC's function called lookupRdrNameInModuleForPlugins,+-- but using initTcFromModGuts instead of initTcInteractive. Also, we ImportBySystem+-- instead of ImportByPlugin, so the EPS gets populated with RULES and instances from+-- the loaded module.+--+-- TODO: consider importing by plugin first, then only importing by system when a name+-- is successfully found... as written we will load RULES/instances if the module loads+-- successfully, even if the name is not found.+lookupRdrNameInModule :: HscEnv -> ModGuts -> ModuleName -> RdrName -> IO (Maybe Name)+lookupRdrNameInModule hsc_env guts mod_name rdr_name = do     -- First find the package the module resides in by searching exposed packages and home modules     found_module <- findImportedModule hsc_env mod_name Nothing     case found_module of@@ -402,7 +302,8 @@             -- Find the exports of the module             (_, mb_iface) <- initTcFromModGuts hsc_env guts HsSrcFile False $                              initIfaceTcRn $-                             loadPluginInterface doc mod+                             loadSysInterface doc mod+             case mb_iface of                 Just iface -> do                     -- Try and find the required name in the exports@@ -427,4 +328,3 @@  throwCmdLineError :: String -> IO a throwCmdLineError = throwGhcExceptionIO . CmdLineError-#endif
src/HERMIT/GHC/Typechecker.hs view
@@ -1,15 +1,11 @@ {-# LANGUAGE CPP, RankNTypes #-}-module HERMIT.GHC.Typechecker -    ( -#if __GLASGOW_HASKELL__ > 706+module HERMIT.GHC.Typechecker+    (       initTcFromModGuts     , mk_type_env     , tcLookupGlobal-#endif     ) where -#if __GLASGOW_HASKELL__ > 706- import Annotations (emptyAnnEnv) import HsSyn import RdrName@@ -34,7 +30,7 @@ import qualified Data.Set as Set import qualified Data.Map as Map -import Prelude +import Prelude import VarSet (emptyVarSet)  -- Note: the contents of this module should eventually be folded into GHC proper.@@ -178,5 +174,3 @@ mk_dfun_n :: ModGuts -> OccSet -- TODO mk_dfun_n _ = emptyOccSet--#endif
src/HERMIT/Kernel.hs view
@@ -1,17 +1,18 @@ {-# LANGUAGE RankNTypes, ScopedTypeVariables, TupleSections, GADTs #-}  module HERMIT.Kernel-        ( -- * The HERMIT Kernel-          AST-        , Kernel-        , hermitKernel-        , resumeK-        , abortK-        , applyK-        , queryK-        , deleteK-        , listK-) where+    ( -- * The HERMIT Kernel+      AST+    , Kernel+    , KernelEnv(..)+    , hermitKernel+    , resumeK+    , abortK+    , applyK+    , queryK+    , deleteK+    , listK+    ) where  import Prelude hiding (lookup) @@ -27,12 +28,12 @@ --   For now, operations on a 'Kernel' are sequential, but later --   it will be possible to have two 'applyK's running in parallel. data Kernel = Kernel-  { resumeK ::            AST                                        -> IO ()           -- ^ Halt the 'Kernel' and return control to GHC, which compiles the specified 'AST'.-  , abortK  ::                                                          IO ()           -- ^ Halt the 'Kernel' and abort GHC without compiling.-  , applyK  ::            AST -> RewriteH ModGuts     -> HermitMEnv  -> IO (KureM AST)  -- ^ Apply a 'Rewrite' to the specified 'AST' and return a handle to the resulting 'AST'.-  , queryK  :: forall a . AST -> TransformH ModGuts a -> HermitMEnv  -> IO (KureM a)    -- ^ Apply a 'TransformH' to the 'AST' and return the resulting value.-  , deleteK ::            AST                                        -> IO ()           -- ^ Delete the internal record of the specified 'AST'.-  , listK   ::                                                          IO [AST]        -- ^ List all the 'AST's tracked by the 'Kernel'.+  { resumeK ::            AST                                      -> IO ()          -- ^ Halt the 'Kernel' and return control to GHC, which compiles the specified 'AST'.+  , abortK  ::                                                        IO ()          -- ^ Halt the 'Kernel' and abort GHC without compiling.+  , applyK  ::            AST -> RewriteH ModGuts     -> KernelEnv -> IO (KureM AST) -- ^ Apply a 'Rewrite' to the specified 'AST' and return a handle to the resulting 'AST'.+  , queryK  :: forall a . AST -> TransformH ModGuts a -> KernelEnv -> IO (KureM a)   -- ^ Apply a 'TransformH' to the 'AST' and return the resulting value.+  , deleteK ::            AST                                      -> IO ()          -- ^ Delete the internal record of the specified 'AST'.+  , listK   ::                                                        IO [AST]       -- ^ List all the 'AST's tracked by the 'Kernel'.   }  -- | A /handle/ for a specific version of the 'ModGuts'.@@ -42,15 +43,28 @@ data Msg s r = forall a . Req (s -> CoreM (KureM (a,s))) (MVar (KureM a))              | Done (s -> CoreM r) -type KernelState = Map AST (DefStash, ModGuts)+type ASTMap = Map AST KernelState +data KernelState = KernelState { _ksStash  :: DefStash+                               , _ksLemmas :: Lemmas+                               , ksGuts   :: ModGuts+                               }++fromHermitMResult :: HermitMResult ModGuts -> KernelState+fromHermitMResult hRes = sideEffectsOnly hRes (hResult hRes)++sideEffectsOnly :: HermitMResult a -> ModGuts -> KernelState+sideEffectsOnly hRes = KernelState (hResStash hRes) (hResLemmas hRes)++data KernelEnv = KernelEnv { kEnvChan :: DebugMessage -> HermitM () }+ -- | Start a HERMIT client by providing an IO function that takes the initial 'Kernel' and inital 'AST' handle. --   The 'Modguts' to 'CoreM' Modguts' function required by GHC Plugins is returned. --   The callback is only ever called once. hermitKernel :: (Kernel -> AST -> IO ()) -> ModGuts -> CoreM ModGuts hermitKernel callback modGuts = do -        msgMV :: MVar (Msg KernelState ModGuts) <- liftIO newEmptyMVar+        msgMV :: MVar (Msg ASTMap ModGuts) <- liftIO newEmptyMVar          nextASTname :: MVar AST <- liftIO newEmptyMVar @@ -58,38 +72,53 @@                                                loop (succ n)                                 in loop 0 -        let sendDone :: (KernelState -> CoreM ModGuts) -> IO ()+        let sendDone :: (ASTMap -> CoreM ModGuts) -> IO ()             sendDone = putMVar msgMV . Done -        let sendReq :: (KernelState -> CoreM (KureM (a, KernelState))) -> IO (KureM a)+        let sendReq :: (ASTMap -> CoreM (KureM (a, ASTMap))) -> IO (KureM a)             sendReq fn = do rep  <- newEmptyMVar                             putMVar msgMV (Req fn rep)                             takeMVar rep -        let sendReqRead :: (KernelState -> CoreM (KureM a)) -> IO (KureM a)-            sendReqRead fn = sendReq (\ st -> (fmap.fmap) (,st) $ fn st)+        let sendReqRead :: (ASTMap -> CoreM (KureM a)) -> IO (KureM a)+            sendReqRead fn = sendReq (\ st -> (fmap.fmap) (,st) $ fn st) -- >>= return . fmap fst -        let sendReqWrite :: (KernelState -> CoreM KernelState) -> IO ()-            sendReqWrite fn = sendReq (fmap ( return . ((),) ) . fn) >>= liftKureM+        let sendReqWrite :: (ASTMap -> CoreM ASTMap) -> IO ()+            sendReqWrite fn = sendReq (fmap ( return . ((),) ) . fn) >>= {- fmap fst . -} liftKureM          let kernel :: Kernel             kernel = Kernel-                { resumeK = \ name -> sendDone $ \ st -> findWithErrMsg name st (\ msg -> throwGhcException $ ProgramError $ msg ++ ", exiting HERMIT and aborting GHC compilation.") (return.snd)+                { resumeK = \ name ->+                                sendDone $ \ st ->+                                    findWithErrMsg name+                                                   st+                                                   (\ msg -> throwGhcException+                                                             $ ProgramError+                                                             $ msg ++ ", exiting HERMIT and aborting GHC compilation.")+                                                   (return.ksGuts) -                , abortK  = sendDone $ \ _ -> throwGhcException (ProgramError "Exiting HERMIT and aborting GHC compilation.")+                , abortK  = sendDone $ \ _ -> throwGhcException+                                              $ ProgramError "Exiting HERMIT and aborting GHC compilation." -                , applyK = \ name r hm_env -> sendReq $ \ st -> findWithErrMsg name st fail $ \ (defs, guts) -> runHM (guts,hm_env)-                                                                                                               defs-                                                                                                               (\ defs' guts' -> do ast <- liftIO $ takeMVar nextASTname-                                                                                                                                    return $ return (ast, insert ast (defs',guts') st))-                                                                                                               (return . fail)-                                                                                                               (apply r (topLevelHermitC guts) guts)+                , applyK = \ name r kEnv ->+                                sendReq $ \ st ->+                                    findWithErrMsg name st fail $ \ (KernelState defs lemmas guts) ->+                                        runHM (kEnvChan kEnv)+                                              (mkEnv guts defs lemmas)+                                              (\ hRes -> do+                                                    ast <- liftIO $ takeMVar nextASTname+                                                    return $ return (ast, insert ast (fromHermitMResult hRes) st))+                                              (return . fail)+                                              (applyT r (topLevelHermitC guts) guts) -                , queryK = \ name t hm_env -> sendReqRead $ \ st -> findWithErrMsg name st fail $ \ (defs, guts) -> runHM (guts,hm_env)-                                                                                                                      defs-                                                                                                                      (\ _ -> return.return)-                                                                                                                      (return . fail)-                                                                                                                      (apply t (topLevelHermitC guts) guts)+                , queryK = \ name t kEnv ->+                                sendReqRead $ \ st ->+                                    findWithErrMsg name st fail $ \ (KernelState defs lemmas guts) ->+                                        runHM (kEnvChan kEnv)+                                              (mkEnv guts defs lemmas)+                                              (return . return . hResult)+                                              (return . fail)+                                              (applyT t (topLevelHermitC guts) guts)                  , deleteK = \ name -> sendReqWrite (return . delete name) @@ -99,7 +128,7 @@         -- We always start with AST 0         ast0 <- liftIO $ takeMVar nextASTname -        let loop :: KernelState -> CoreM ModGuts+        let loop :: ASTMap -> CoreM ModGuts             loop st = do                 m <- liftIO $ takeMVar msgMV                 case m of@@ -109,7 +138,7 @@          _pid <- liftIO $ forkIO $ callback kernel ast0 -        loop (singleton ast0 (empty, modGuts))+        loop (singleton ast0 $ KernelState empty empty modGuts)          -- (Kill the pid'd thread? do we need to?) 
src/HERMIT/Kernel/Scoped.hs view
@@ -22,7 +22,6 @@ import HERMIT.Context import HERMIT.Kure import HERMIT.GHC hiding (Direction,L)-import HERMIT.Monad import HERMIT.Kernel  ----------------------------------------------------------------------------@@ -59,22 +58,22 @@  -- | An alternative HERMIT kernel, that provides scoping. data ScopedKernel = ScopedKernel-    { resumeS      :: (MonadIO m, MonadCatch m) =>                SAST -> m ()-    , abortS       ::  MonadIO m                =>                        m ()+    { resumeS      :: (MonadIO m, MonadCatch m) =>               SAST -> m ()+    , abortS       ::  MonadIO m                =>                       m ()     , applyS       :: (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g)-                   => RewriteH g -> HermitMEnv ->                 SAST -> m SAST+                   => RewriteH g     -> KernelEnv ->             SAST -> m SAST     , queryS       :: (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g)-                   => TransformH g a -> HermitMEnv ->             SAST -> m a-    , deleteS      :: (MonadIO m, MonadCatch m) =>                SAST -> m ()-    , listS        ::  MonadIO m                =>                        m [SAST]-    , pathS        :: (MonadIO m, MonadCatch m) =>                SAST -> m [PathH]+                   => TransformH g a -> KernelEnv ->             SAST -> m a+    , deleteS      :: (MonadIO m, MonadCatch m) =>               SAST -> m ()+    , listS        ::  MonadIO m                =>                       m [SAST]+    , pathS        :: (MonadIO m, MonadCatch m) =>               SAST -> m [PathH]     , modPathS     :: (MonadIO m, MonadCatch m)-                   => (LocalPathH -> LocalPathH) -> HermitMEnv -> SAST -> m SAST-    , beginScopeS  :: (MonadIO m, MonadCatch m) =>                SAST -> m SAST-    , endScopeS    :: (MonadIO m, MonadCatch m) =>                SAST -> m SAST+                   => (LocalPathH -> LocalPathH) -> KernelEnv -> SAST -> m SAST+    , beginScopeS  :: (MonadIO m, MonadCatch m) =>               SAST -> m SAST+    , endScopeS    :: (MonadIO m, MonadCatch m) =>               SAST -> m SAST     -- means of accessing the underlying kernel, obviously for unsafe purposes-    , kernelS      ::                                                     Kernel-    , toASTS       :: (MonadIO m, MonadCatch m) =>                SAST -> m AST+    , kernelS      ::                                                    Kernel+    , toASTS       :: (MonadIO m, MonadCatch m) =>               SAST -> m AST     }  -- | A /handle/ for an 'AST' combined with scoping information.@@ -111,9 +110,10 @@             , applyS      = \ rr env (SAST sAst) -> safeTakeTMVar store $ \ m -> do                                 (ast, base, rel) <- get sAst m                                 applyK kernel ast (focusR (pathStackToLens base rel) rr) env-                                  >>= runKureM (\ ast' -> atomically $ do k <- newKey-                                                                          putTMVar store $ I.insert k (ast', base, rel) m-                                                                          return $ SAST k)+                                  >>= runKureM (\ ast' -> atomically $ do+                                                    k <- newKey+                                                    putTMVar store $ I.insert k (ast', base, rel) m+                                                    return (SAST k))                                                fail             , queryS      = \ t env (SAST sAst) -> liftAndCatchIO $ do                                 m <- atomically $ readTMVar store
src/HERMIT/Kure.hs view
@@ -69,18 +69,11 @@        , forAllCoT, forAllCoAllR, forAllCoAnyR, forAllCoOneR        , coVarCoT, coVarCoR        , axiomInstCoT, axiomInstCoAllR, axiomInstCoAnyR, axiomInstCoOneR-#if __GLASGOW_HASKELL__ > 706-#else-       , unsafeCoT, unsafeCoAllR, unsafeCoAnyR, unsafeCoOneR-#endif        , symCoT, symCoR        , transCoT, transCoAllR, transCoAnyR, transCoOneR        , nthCoT, nthCoAllR, nthCoAnyR, nthCoOneR        , instCoT, instCoAllR, instCoAnyR, instCoOneR-#if __GLASGOW_HASKELL__ > 706        , lrCoT, lrCoAllR, lrCoAnyR, lrCoOneR-#else-#endif        -- * Conversion to deprecated Int representation        , deprecatedIntToCrumbT        , deprecatedIntToPathT@@ -129,12 +122,12 @@   allR :: forall m. MonadCatch m => Rewrite c m Core -> Rewrite c m Core   allR r = prefixFailMsg "allR failed: " $            rewrite $ \ c -> \case-             GutsCore guts  -> inject <$> apply allRmodguts c guts-             ProgCore p     -> inject <$> apply allRprog c p-             BindCore bn    -> inject <$> apply allRbind c bn-             DefCore def    -> inject <$> apply allRdef c def-             AltCore alt    -> inject <$> apply allRalt c alt-             ExprCore e     -> inject <$> apply allRexpr c e+             GutsCore guts  -> inject <$> applyT allRmodguts c guts+             ProgCore p     -> inject <$> applyT allRprog c p+             BindCore bn    -> inject <$> applyT allRbind c bn+             DefCore def    -> inject <$> applyT allRdef c def+             AltCore alt    -> inject <$> applyT allRalt c alt+             ExprCore e     -> inject <$> applyT allRexpr c e     where       allRmodguts :: MonadCatch m => Rewrite c m ModGuts       allRmodguts = modGutsR (extractR r)@@ -203,12 +196,8 @@                         TransCo{}     -> transCoAllR r r                         NthCo{}       -> nthCoAllR idR r                         InstCo{}      -> instCoAllR r idR-#if __GLASGOW_HASKELL__ > 706                         LRCo{}        -> lrCoAllR idR r                         AxiomInstCo{} -> axiomInstCoAllR idR idR (const r)-#else-                        AxiomInstCo{} -> axiomInstCoAllR idR (const r)-#endif                         _             -> idR  ---------------------------------------------------------------------@@ -219,8 +208,8 @@   allR :: forall m. MonadCatch m => Rewrite c m TyCo -> Rewrite c m TyCo   allR r = prefixFailMsg "allR failed: " $            rewrite $ \ c -> \case-             TypeCore ty     -> inject <$> apply (allR $ extractR r) c ty -- exploiting the fact that types do not contain coercions-             CoercionCore co -> inject <$> apply allRcoercion c co+             TypeCore ty     -> inject <$> applyT (allR $ extractR r) c ty -- exploiting the fact that types do not contain coercions+             CoercionCore co -> inject <$> applyT allRcoercion c co     where       allRcoercion :: MonadCatch m => Rewrite c m Coercion       allRcoercion = readerT $ \case@@ -228,20 +217,12 @@                               TyConAppCo{}  -> tyConAppCoAllR idR (const $ extractR r) -- we don't descend into the TyCon                               AppCo{}       -> appCoAllR (extractR r) (extractR r)                               ForAllCo{}    -> forAllCoAllR idR (extractR r) -- we don't descend into the TyVar-#if __GLASGOW_HASKELL__ > 706-#else-                              UnsafeCo{}    -> unsafeCoAllR (extractR r) (extractR r)-#endif                               SymCo{}       -> symCoR (extractR r)                               TransCo{}     -> transCoAllR (extractR r) (extractR r)                               InstCo{}      -> instCoAllR (extractR r) (extractR r)                               NthCo{}       -> nthCoAllR idR (extractR r) -- we don't descend into the Int-#if __GLASGOW_HASKELL__ > 706                               LRCo{}        -> lrCoAllR idR (extractR r)                               AxiomInstCo{} -> axiomInstCoAllR idR idR (const $ extractR r) -- we don't descend into the axiom or index-#else-                              AxiomInstCo{} -> axiomInstCoAllR idR (const $ extractR r) -- we don't descend into the axiom-#endif                               _             -> idR       {-# INLINE allRcoercion #-} @@ -253,13 +234,13 @@   allR :: forall m. MonadCatch m => Rewrite c m CoreTC -> Rewrite c m CoreTC   allR r = prefixFailMsg "allR failed: " $            rewrite $ \ c -> \case-             Core (GutsCore guts)  -> inject <$> apply allRmodguts c guts-             Core (ProgCore p)     -> inject <$> apply allRprog c p-             Core (BindCore bn)    -> inject <$> apply allRbind c bn-             Core (DefCore def)    -> inject <$> apply allRdef c def-             Core (AltCore alt)    -> inject <$> apply allRalt c alt-             Core (ExprCore e)     -> inject <$> apply allRexpr c e-             TyCo tyCo             -> inject <$> apply (allR $ extractR r) c tyCo -- exploiting the fact that only types and coercions appear within types and coercions+             Core (GutsCore guts)  -> inject <$> applyT allRmodguts c guts+             Core (ProgCore p)     -> inject <$> applyT allRprog c p+             Core (BindCore bn)    -> inject <$> applyT allRbind c bn+             Core (DefCore def)    -> inject <$> applyT allRdef c def+             Core (AltCore alt)    -> inject <$> applyT allRalt c alt+             Core (ExprCore e)     -> inject <$> applyT allRexpr c e+             TyCo tyCo             -> inject <$> applyT (allR $ extractR r) c tyCo -- exploiting the fact that only types and coercions appear within types and coercions     where       allRmodguts :: MonadCatch m => Rewrite c m ModGuts       allRmodguts = modGutsR (extractR r)@@ -307,7 +288,7 @@ -- | Transform a module. --   Slightly different to the other congruence combinators: it passes in /all/ of the original to the reconstruction function. modGutsT :: (ExtendPath c Crumb, HasEmptyContext c, Monad m) => Transform c m CoreProg a -> (ModGuts -> a -> b) -> Transform c m ModGuts b-modGutsT t f = transform $ \ c guts -> f guts <$> apply t (setEmptyContext c @@ ModGuts_Prog) (bindsToProg $ mg_binds guts)+modGutsT t f = transform $ \ c guts -> f guts <$> applyT t (setEmptyContext c @@ ModGuts_Prog) (bindsToProg $ mg_binds guts) {-# INLINE modGutsT #-}  -- | Rewrite the 'CoreProg' child of a module.@@ -327,7 +308,7 @@ -- | Transform a program of the form: ('CoreBind' @:@ 'CoreProg') progConsT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => Transform c m CoreBind a1 -> Transform c m CoreProg a2 -> (a1 -> a2 -> b) -> Transform c m CoreProg b progConsT t1 t2 f = transform $ \ c -> \case-                                          ProgCons bd p -> f <$> apply t1 (c @@ ProgCons_Head) bd <*> apply t2 (addBindingGroup bd c @@ ProgCons_Tail) p+                                          ProgCons bd p -> f <$> applyT t1 (c @@ ProgCons_Head) bd <*> applyT t2 (addBindingGroup bd c @@ ProgCons_Tail) p                                           _             -> fail "not a non-empty program." {-# INLINE progConsT #-} @@ -351,7 +332,7 @@ -- | Transform a binding group of the form: @NonRec@ 'Var' 'CoreExpr' nonRecT :: (ExtendPath c Crumb, Monad m) => Transform c m Var a1 -> Transform c m CoreExpr a2 -> (a1 -> a2 -> b) -> Transform c m CoreBind b nonRecT t1 t2 f = transform $ \ c -> \case-                                        NonRec v e -> f <$> apply t1 (c @@ NonRec_Var) v <*> apply t2 (c @@ NonRec_RHS) e+                                        NonRec v e -> f <$> applyT t1 (c @@ NonRec_Var) v <*> applyT t2 (c @@ NonRec_RHS) e                                         _          -> fail "not a non-recursive binding group." {-# INLINE nonRecT #-} @@ -375,7 +356,7 @@ recT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => (Int -> Transform c m CoreDef a) -> ([a] -> b) -> Transform c m CoreBind b recT t f = transform $ \ c -> \case          Rec bds -> -- The group is recursive, so we add all other bindings in the group to the context (excluding the one under consideration).-                    f <$> sequence [ apply (t n) (addDefBindingsExcept n bds c @@ Rec_Def n) (Def i e) -- here we convert from (Id,CoreExpr) to CoreDef+                    f <$> sequence [ applyT (t n) (addDefBindingsExcept n bds c @@ Rec_Def n) (Def i e) -- here we convert from (Id,CoreExpr) to CoreDef                                    | ((i,e),n) <- zip bds [0..]                                    ]          _       -> fail "not a recursive binding group."@@ -400,7 +381,7 @@  -- | Transform a recursive definition of the form: @Def@ 'Id' 'CoreExpr' defT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => Transform c m Id a1 -> Transform c m CoreExpr a2 -> (a1 -> a2 -> b) -> Transform c m CoreDef b-defT t1 t2 f = transform $ \ c (Def i e) -> f <$> apply t1 (c @@ Def_Id) i <*> apply t2 (addDefBinding i c @@ Def_RHS) e+defT t1 t2 f = transform $ \ c (Def i e) -> f <$> applyT t1 (c @@ Def_Id) i <*> applyT t2 (addDefBinding i c @@ Def_RHS) e {-# INLINE defT #-}  -- | Rewrite all children of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'@@ -422,9 +403,9 @@  -- | Transform a case alternative of the form: ('AltCon', ['Var'], 'CoreExpr') altT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => Transform c m AltCon a1 -> (Int -> Transform c m Var a2) -> Transform c m CoreExpr a3 -> (a1 -> [a2] -> a3 -> b) -> Transform c m CoreAlt b-altT t1 ts t2 f = transform $ \ c (con,vs,e) -> f <$> apply t1 (c @@ Alt_Con) con-                                                  <*> sequence [ apply (ts n) (c @@ Alt_Var n) v | (v,n) <- zip vs [1..] ]-                                                  <*> apply t2 (addAltBindings vs c @@ Alt_RHS) e+altT t1 ts t2 f = transform $ \ c (con,vs,e) -> f <$> applyT t1 (c @@ Alt_Con) con+                                                  <*> sequence [ applyT (ts n) (c @@ Alt_Var n) v | (v,n) <- zip vs [1..] ]+                                                  <*> applyT t2 (addAltBindings vs c @@ Alt_RHS) e {-# INLINE altT #-}  -- | Rewrite all children of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')@@ -447,7 +428,7 @@ -- | Transform an expression of the form: @Var@ 'Id' varT :: (ExtendPath c Crumb, Monad m) => Transform c m Id b -> Transform c m CoreExpr b varT t = transform $ \ c -> \case-                               Var v -> apply t (c @@ Var_Id) v+                               Var v -> applyT t (c @@ Var_Id) v                                _     -> fail "not a variable." {-# INLINE varT #-} @@ -460,7 +441,7 @@ -- | Transform an expression of the form: @Lit@ 'Literal' litT :: (ExtendPath c Crumb, Monad m) => Transform c m Literal b -> Transform c m CoreExpr b litT t = transform $ \ c -> \case-                               Lit x -> apply t (c @@ Lit_Lit) x+                               Lit x -> applyT t (c @@ Lit_Lit) x                                _     -> fail "not a literal." {-# INLINE litT #-} @@ -473,7 +454,7 @@ -- | Transform an expression of the form: @App@ 'CoreExpr' 'CoreExpr' appT :: (ExtendPath c Crumb, Monad m) => Transform c m CoreExpr a1 -> Transform c m CoreExpr a2 -> (a1 -> a2 -> b) -> Transform c m CoreExpr b appT t1 t2 f = transform $ \ c -> \case-                                     App e1 e2 -> f <$> apply t1 (c @@ App_Fun) e1 <*> apply t2 (c @@ App_Arg) e2+                                     App e1 e2 -> f <$> applyT t1 (c @@ App_Fun) e1 <*> applyT t2 (c @@ App_Arg) e2                                      _         -> fail "not an application." {-# INLINE appT #-} @@ -496,7 +477,7 @@ -- | Transform an expression of the form: @Lam@ 'Var' 'CoreExpr' lamT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => Transform c m Var a1 -> Transform c m CoreExpr a2 -> (a1 -> a2 -> b) -> Transform c m CoreExpr b lamT t1 t2 f = transform $ \ c -> \case-                                     Lam v e -> f <$> apply t1 (c @@ Lam_Var) v <*> apply t2 (addLambdaBinding v c @@ Lam_Body) e+                                     Lam v e -> f <$> applyT t1 (c @@ Lam_Var) v <*> applyT t2 (addLambdaBinding v c @@ Lam_Body) e                                      _       -> fail "not a lambda." {-# INLINE lamT #-} @@ -521,7 +502,7 @@ letT t1 t2 f = transform $ \ c -> \case         Let bds e -> -- Note we use the *original* context for the binding group.                      -- If the bindings are recursive, they will be added to the context by recT.-                     f <$> apply t1 (c @@ Let_Bind) bds <*> apply t2 (addBindingGroup bds c @@ Let_Body) e+                     f <$> applyT t1 (c @@ Let_Bind) bds <*> applyT t2 (addBindingGroup bds c @@ Let_Body) e         _         -> fail "not a let node." {-# INLINE letT #-} @@ -550,10 +531,10 @@       -> (e -> w -> ty -> [alt] -> b)       -> Transform c m CoreExpr b caseT te tw tty talts f = transform $ \ c -> \case-         Case e w ty alts -> f <$> apply te (c @@ Case_Scrutinee) e-                               <*> apply tw (c @@ Case_Binder) w-                               <*> apply tty (c @@ Case_Type) ty-                               <*> sequence [ apply (talts n) (addCaseBinderBinding (w,e,alt) c @@ Case_Alt n) alt+         Case e w ty alts -> f <$> applyT te (c @@ Case_Scrutinee) e+                               <*> applyT tw (c @@ Case_Binder) w+                               <*> applyT tty (c @@ Case_Type) ty+                               <*> sequence [ applyT (talts n) (addCaseBinderBinding (w,e,alt) c @@ Case_Alt n) alt                                             | (alt,n) <- zip alts [0..]                                             ]          _                -> fail "not a case."@@ -593,7 +574,7 @@ -- | Transform an expression of the form: @Cast@ 'CoreExpr' 'Coercion' castT :: (ExtendPath c Crumb, Monad m) => Transform c m CoreExpr a1 -> Transform c m Coercion a2 -> (a1 -> a2 -> b) -> Transform c m CoreExpr b castT t1 t2 f = transform $ \ c -> \case-                                      Cast e co -> f <$> apply t1 (c @@ Cast_Expr) e <*> apply t2 (c @@ Cast_Co) co+                                      Cast e co -> f <$> applyT t1 (c @@ Cast_Expr) e <*> applyT t2 (c @@ Cast_Co) co                                       _         -> fail "not a cast." {-# INLINE castT #-} @@ -616,7 +597,7 @@ -- | Transform an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr' tickT :: (ExtendPath c Crumb, Monad m) => Transform c m CoreTickish a1 -> Transform c m CoreExpr a2 -> (a1 -> a2 -> b) -> Transform c m CoreExpr b tickT t1 t2 f = transform $ \ c -> \case-                                      Tick tk e -> f <$> apply t1 (c @@ Tick_Tick) tk <*> apply t2 (c @@ Tick_Expr) e+                                      Tick tk e -> f <$> applyT t1 (c @@ Tick_Tick) tk <*> applyT t2 (c @@ Tick_Expr) e                                       _         -> fail "not a tick." {-# INLINE tickT #-} @@ -639,7 +620,7 @@ -- | Transform an expression of the form: @Type@ 'Type' typeT :: (ExtendPath c Crumb, Monad m) => Transform c m Type b -> Transform c m CoreExpr b typeT t = transform $ \ c -> \case-                                Type ty -> apply t (c @@ Type_Type) ty+                                Type ty -> applyT t (c @@ Type_Type) ty                                 _       -> fail "not a type." {-# INLINE typeT #-} @@ -652,7 +633,7 @@ -- | Transform an expression of the form: @Coercion@ 'Coercion' coercionT :: (ExtendPath c Crumb, Monad m) => Transform c m Coercion b -> Transform c m CoreExpr b coercionT t = transform $ \ c -> \case-                                    Coercion co -> apply t (c @@ Co_Co) co+                                    Coercion co -> applyT t (c @@ Co_Co) co                                     _           -> fail "not a coercion." {-# INLINE coercionT #-} @@ -910,7 +891,7 @@ -- | Transform a type of the form: @TyVarTy@ 'TyVar' tyVarT :: (ExtendPath c Crumb, Monad m) => Transform c m TyVar b -> Transform c m Type b tyVarT t = transform $ \ c -> \case-                                 TyVarTy v -> apply t (c @@ TyVarTy_TyVar) v+                                 TyVarTy v -> applyT t (c @@ TyVarTy_TyVar) v                                  _         -> fail "not a type variable." {-# INLINE tyVarT #-} @@ -923,7 +904,7 @@ -- | Transform a type of the form: @LitTy@ 'TyLit' litTyT :: (ExtendPath c Crumb, Monad m) => Transform c m TyLit b -> Transform c m Type b litTyT t = transform $ \ c -> \case-                                 LitTy x -> apply t (c @@ LitTy_TyLit) x+                                 LitTy x -> applyT t (c @@ LitTy_TyLit) x                                  _       -> fail "not a type literal." {-# INLINE litTyT #-} @@ -936,7 +917,7 @@ -- | Transform a type of the form: @AppTy@ 'Type' 'Type' appTyT :: (ExtendPath c Crumb, Monad m) => Transform c m Type a1 -> Transform c m Type a2 -> (a1 -> a2 -> b) -> Transform c m Type b appTyT t1 t2 f = transform $ \ c -> \case-                                     AppTy ty1 ty2 -> f <$> apply t1 (c @@ AppTy_Fun) ty1 <*> apply t2 (c @@ AppTy_Arg) ty2+                                     AppTy ty1 ty2 -> f <$> applyT t1 (c @@ AppTy_Fun) ty1 <*> applyT t2 (c @@ AppTy_Arg) ty2                                      _             -> fail "not a type application." {-# INLINE appTyT #-} @@ -959,7 +940,7 @@ -- | Transform a type of the form: @FunTy@ 'Type' 'Type' funTyT :: (ExtendPath c Crumb, Monad m) => Transform c m Type a1 -> Transform c m Type a2 -> (a1 -> a2 -> b) -> Transform c m Type b funTyT t1 t2 f = transform $ \ c -> \case-                                     FunTy ty1 ty2 -> f <$> apply t1 (c @@ FunTy_Dom) ty1 <*> apply t2 (c @@ FunTy_CoDom) ty2+                                     FunTy ty1 ty2 -> f <$> applyT t1 (c @@ FunTy_Dom) ty1 <*> applyT t2 (c @@ FunTy_CoDom) ty2                                      _             -> fail "not a function type." {-# INLINE funTyT #-} @@ -982,7 +963,7 @@ -- | Transform a type of the form: @ForAllTy@ 'Var' 'Type' forAllTyT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => Transform c m Var a1 -> Transform c m Type a2 -> (a1 -> a2 -> b) -> Transform c m Type b forAllTyT t1 t2 f = transform $ \ c -> \case-                                          ForAllTy v ty -> f <$> apply t1 (c @@ ForAllTy_Var) v <*> apply t2 (addForallBinding v c @@ ForAllTy_Body) ty+                                          ForAllTy v ty -> f <$> applyT t1 (c @@ ForAllTy_Var) v <*> applyT t2 (addForallBinding v c @@ ForAllTy_Body) ty                                           _             -> fail "not a forall type." {-# INLINE forAllTyT #-} @@ -1005,7 +986,7 @@ -- | Transform a type of the form: @TyConApp@ 'TyCon' ['KindOrType'] tyConAppT :: (ExtendPath c Crumb, Monad m) => Transform c m TyCon a1 -> (Int -> Transform c m KindOrType a2) -> (a1 -> [a2] -> b) -> Transform c m Type b tyConAppT t ts f = transform $ \ c -> \case-                                         TyConApp con tys -> f <$> apply t (c @@ TyConApp_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConApp_Arg n) ty | (ty,n) <- zip tys [0..] ]+                                         TyConApp con tys -> f <$> applyT t (c @@ TyConApp_TyCon) con <*> sequence [ applyT (ts n) (c @@ TyConApp_Arg n) ty | (ty,n) <- zip tys [0..] ]                                          _                -> fail "not a type-constructor application." {-# INLINE tyConAppT #-} @@ -1030,43 +1011,23 @@ -- Coercions -- TODO: review and bring all these up-to-date for Coercions w/ Roles in 7.8 -#if __GLASGOW_HASKELL__ > 706 -- | Transform a coercion of the form: @Refl@ 'Role' 'Type' reflT :: (ExtendPath c Crumb, Monad m) => Transform c m Type a1 -> (Role -> a1 -> b) -> Transform c m Coercion b reflT t f = transform $ \ c -> \case-                                 Refl r ty -> f r <$> apply t (c @@ Refl_Type) ty+                                 Refl r ty -> f r <$> applyT t (c @@ Refl_Type) ty                                  _         -> fail "not a reflexive coercion."  -- | Rewrite the 'Type' child of a coercion of the form: @Refl@ 'Role' 'Type' reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion reflR r = reflT r Refl-#else--- | Transform a coercion of the form: @Refl@ 'Type'-reflT :: (ExtendPath c Crumb, Monad m) => Transform c m Type b -> Transform c m Coercion b-reflT t = transform $ \ c -> \case-                                 Refl ty -> apply t (c @@ Refl_Type) ty-                                 _       -> fail "not a reflexive coercion."---- | Rewrite the 'Type' child of a coercion of the form: @Refl@ 'Type'-reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion-reflR r = reflT (Refl <$> r)-#endif {-# INLINE reflT #-} {-# INLINE reflR #-} -#if __GLASGOW_HASKELL__ > 706 -- | Transform a coercion of the form: @TyConAppCo@ 'Role' 'TyCon' ['Coercion'] tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Transform c m TyCon a1 -> (Int -> Transform c m Coercion a2) -> (Role -> a1 -> [a2] -> b) -> Transform c m Coercion b tyConAppCoT t ts f = transform $ \ c -> \case-                                           TyConAppCo r con coes -> f r <$> apply t (c @@ TyConAppCo_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConAppCo_Arg n) co | (co,n) <- zip coes [0..] ]+                                           TyConAppCo r con coes -> f r <$> applyT t (c @@ TyConAppCo_TyCon) con <*> sequence [ applyT (ts n) (c @@ TyConAppCo_Arg n) co | (co,n) <- zip coes [0..] ]                                            _                     -> fail "not a type-constructor coercion."-#else--- | Transform a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']-tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Transform c m TyCon a1 -> (Int -> Transform c m Coercion a2) -> (a1 -> [a2] -> b) -> Transform c m Coercion b-tyConAppCoT t ts f = transform $ \ c -> \case-                                           TyConAppCo con coes -> f <$> apply t (c @@ TyConAppCo_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConAppCo_Arg n) co | (co,n) <- zip coes [0..] ]-                                           _                   -> fail "not a type-constructor coercion."-#endif {-# INLINE tyConAppCoT #-}  -- | Rewrite all children of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']@@ -1088,7 +1049,7 @@ -- | Transform a coercion of the form: @AppCo@ 'Coercion' 'Coercion' appCoT :: (ExtendPath c Crumb, Monad m) => Transform c m Coercion a1 -> Transform c m Coercion a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b appCoT t1 t2 f = transform $ \ c -> \case-                                     AppCo co1 co2 -> f <$> apply t1 (c @@ AppCo_Fun) co1 <*> apply t2 (c @@ AppCo_Arg) co2+                                     AppCo co1 co2 -> f <$> applyT t1 (c @@ AppCo_Fun) co1 <*> applyT t2 (c @@ AppCo_Arg) co2                                      _             -> fail "not a coercion application." {-# INLINE appCoT #-} @@ -1111,7 +1072,7 @@ -- | Transform a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion' forAllCoT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, Monad m) => Transform c m TyVar a1 -> Transform c m Coercion a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b forAllCoT t1 t2 f = transform $ \ c -> \case-                                          ForAllCo v co -> f <$> apply t1 (c @@ ForAllCo_TyVar) v <*> apply t2 (addForallBinding v c @@ ForAllCo_Body) co+                                          ForAllCo v co -> f <$> applyT t1 (c @@ ForAllCo_TyVar) v <*> applyT t2 (addForallBinding v c @@ ForAllCo_Body) co                                           _             -> fail "not a forall coercion." {-# INLINE forAllCoT #-} @@ -1134,7 +1095,7 @@ -- | Transform a coercion of the form: @CoVarCo@ 'CoVar' coVarCoT :: (ExtendPath c Crumb, Monad m) => Transform c m CoVar b -> Transform c m Coercion b coVarCoT t = transform $ \ c -> \case-                                   CoVarCo v -> apply t (c @@ CoVarCo_CoVar) v+                                   CoVarCo v -> applyT t (c @@ CoVarCo_CoVar) v                                    _         -> fail "not a coercion variable." {-# INLINE coVarCoT #-} @@ -1143,83 +1104,33 @@ coVarCoR r = coVarCoT (CoVarCo <$> r) {-# INLINE coVarCoR #-} -#if __GLASGOW_HASKELL__ > 706 -- | Transform a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion'] axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Transform c m (CoAxiom Branched) a1 -> Transform c m BranchIndex a2 -> (Int -> Transform c m Coercion a3) -> (a1 -> a2 -> [a3] -> b) -> Transform c m Coercion b axiomInstCoT t1 t2 ts f = transform $ \ c -> \case-                                                AxiomInstCo ax idx coes -> f <$> apply t1 (c @@ AxiomInstCo_Axiom) ax <*> apply t2 (c @@ AxiomInstCo_Index) idx <*> sequence [ apply (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]+                                                AxiomInstCo ax idx coes -> f <$> applyT t1 (c @@ AxiomInstCo_Axiom) ax <*> applyT t2 (c @@ AxiomInstCo_Index) idx <*> sequence [ applyT (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]                                                 _                       -> fail "not a coercion axiom instantiation."-#else--- | Transform a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Transform c m CoAxiom a1 -> (Int -> Transform c m Coercion a2) -> (a1 -> [a2] -> b) -> Transform c m Coercion b-axiomInstCoT t ts f = transform $ \ c -> \case-                                            AxiomInstCo ax coes -> f <$> apply t (c @@ AxiomInstCo_Axiom) ax <*> sequence [ apply (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]-                                            _                   -> fail "not a coercion axiom instantiation."-#endif {-# INLINE axiomInstCoT #-} -#if __GLASGOW_HASKELL__ > 706 -- | Rewrite all children of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion'] axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion axiomInstCoAllR r1 r2 rs = axiomInstCoT r1 r2 rs AxiomInstCo-#else--- | Rewrite all children of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoAllR r rs = axiomInstCoT r rs AxiomInstCo-#endif {-# INLINE axiomInstCoAllR #-} -#if __GLASGOW_HASKELL__ > 706 -- | Rewrite any children of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion'] axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion axiomInstCoAnyR r1 r2 rs = unwrapAnyR $ axiomInstCoAllR (wrapAnyR r1) (wrapAnyR r2) (wrapAnyR . rs)-#else--- | Rewrite any children of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoAnyR r rs = unwrapAnyR $ axiomInstCoAllR (wrapAnyR r) (wrapAnyR . rs)-#endif {-# INLINE axiomInstCoAnyR #-} -#if __GLASGOW_HASKELL__ > 706 -- | Rewrite one child of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion'] axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion axiomInstCoOneR r1 r2 rs = unwrapOneR $ axiomInstCoAllR (wrapOneR r1) (wrapOneR r2) (wrapOneR . rs)-#else--- | Rewrite one child of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoOneR r rs = unwrapOneR $ axiomInstCoAllR (wrapOneR r) (wrapOneR . rs)-#endif {-# INLINE axiomInstCoOneR #-} -#if __GLASGOW_HASKELL__ > 706-#else--- | Transform a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoT :: (ExtendPath c Crumb, Monad m) => Transform c m Type a1 -> Transform c m Type a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b-unsafeCoT t1 t2 f = transform $ \ c -> \case-                                          UnsafeCo ty1 ty2 -> f <$> apply t1 (c @@ UnsafeCo_Left) ty1 <*> apply t2 (c @@ UnsafeCo_Right) ty2-                                          _                -> fail "not an unsafe coercion."-{-# INLINE unsafeCoT #-} --- | Rewrite all children of a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion-unsafeCoAllR r1 r2 = unsafeCoT r1 r2 UnsafeCo-{-# INLINE unsafeCoAllR #-}---- | Rewrite any children of a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion-unsafeCoAnyR r1 r2 = unwrapAnyR $ unsafeCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE unsafeCoAnyR #-}---- | Rewrite one child of a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion-unsafeCoOneR r1 r2 = unwrapOneR $ unsafeCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE unsafeCoOneR #-}-#endif- -- | Transform a coercion of the form: @SymCo@ 'Coercion' symCoT :: (ExtendPath c Crumb, Monad m) => Transform c m Coercion b -> Transform c m Coercion b symCoT t = transform $ \ c -> \case-                                   SymCo co -> apply t (c @@ SymCo_Co) co+                                   SymCo co -> applyT t (c @@ SymCo_Co) co                                    _        -> fail "not a symmetric coercion." {-# INLINE symCoT #-} @@ -1232,7 +1143,7 @@ -- | Transform a coercion of the form: @TransCo@ 'Coercion' 'Coercion' transCoT :: (ExtendPath c Crumb, Monad m) => Transform c m Coercion a1 -> Transform c m Coercion a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b transCoT t1 t2 f = transform $ \ c -> \case-                                          TransCo co1 co2 -> f <$> apply t1 (c @@ TransCo_Left) co1 <*> apply t2 (c @@ TransCo_Right) co2+                                          TransCo co1 co2 -> f <$> applyT t1 (c @@ TransCo_Left) co1 <*> applyT t2 (c @@ TransCo_Right) co2                                           _               -> fail "not a transitive coercion." {-# INLINE transCoT #-} @@ -1255,7 +1166,7 @@ -- | Transform a coercion of the form: @NthCo@ 'Int' 'Coercion' nthCoT :: (ExtendPath c Crumb, Monad m) => Transform c m Int a1 -> Transform c m Coercion a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b nthCoT t1 t2 f = transform $ \ c -> \case-                                          NthCo n co -> f <$> apply t1 (c @@ NthCo_Int) n <*> apply t2 (c @@ NthCo_Co) co+                                          NthCo n co -> f <$> applyT t1 (c @@ NthCo_Int) n <*> applyT t2 (c @@ NthCo_Co) co                                           _          -> fail "not an Nth coercion." {-# INLINE nthCoT #-} @@ -1275,11 +1186,10 @@ {-# INLINE nthCoOneR #-}  -#if __GLASGOW_HASKELL__ > 706 -- | Transform a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion' lrCoT :: (ExtendPath c Crumb, Monad m) => Transform c m LeftOrRight a1 -> Transform c m Coercion a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b lrCoT t1 t2 f = transform $ \ c -> \case-                                      LRCo lr co -> f <$> apply t1 (c @@ LRCo_LR) lr <*> apply t2 (c @@ LRCo_Co) co+                                      LRCo lr co -> f <$> applyT t1 (c @@ LRCo_LR) lr <*> applyT t2 (c @@ LRCo_Co) co                                       _          -> fail "not a left/right coercion." {-# INLINE lrCoT #-} @@ -1297,14 +1207,12 @@ lrCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion lrCoOneR r1 r2 = unwrapOneR $ lrCoAllR (wrapOneR r1) (wrapOneR r2) {-# INLINE lrCoOneR #-}-#else-#endif   -- | Transform a coercion of the form: @InstCo@ 'Coercion' 'Type' instCoT :: (ExtendPath c Crumb, Monad m) => Transform c m Coercion a1 -> Transform c m Type a2 -> (a1 -> a2 -> b) -> Transform c m Coercion b instCoT t1 t2 f = transform $ \ c -> \case-                                          InstCo co ty -> f <$> apply t1 (c @@ InstCo_Co) co <*> apply t2 (c @@ InstCo_Type) ty+                                          InstCo co ty -> f <$> applyT t1 (c @@ InstCo_Co) co <*> applyT t2 (c @@ InstCo_Type) ty                                           _            -> fail "not a coercion instantiation." {-# INLINE instCoT #-} @@ -1356,3 +1264,6 @@  --------------------------------------------------------------------- ---------------------------------------------------------------------++instance HasDynFlags m => HasDynFlags (Transform c m a) where+    getDynFlags = constT getDynFlags
src/HERMIT/Monad.hs view
@@ -1,42 +1,51 @@-{-# LANGUAGE CPP, InstanceSigs #-}+{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, GADTs, InstanceSigs, KindSignatures #-}  module HERMIT.Monad-          (-            -- * The HERMIT Monad-            HermitM-          , runHM-          , liftCoreM-          , newGlobalIdH-          , newIdH-          , newTyVarH-          , newCoVarH-          , newVarH-          , cloneVarH-            -- * Saving Definitions-          , Label-          , DefStash-          , saveDef-          , lookupDef-          , getStash-            -- * Reader Information-          , HasHermitMEnv(..)-          , HasModGuts(..)-          , HasHscEnv(..)-            -- * Messages-          , HermitMEnv(..)-          , DebugMessage(..)-          , mkHermitMEnv-          , sendDebugMessage-) where+    ( -- * The HERMIT Monad+      HermitM+    , runHM+    , embedHermitM+    , HermitMEnv(..)+    , HermitMResult(..)+    , LiftCoreM(..)+    , runTcM+    , runDsM+      -- * Saving Definitions+    , RememberedName(..)+    , DefStash+    , saveDef+    , lookupDef+    , HasStash(..)+      -- * Lemmas+    , Equality(..)+    , LemmaName(..)+    , Lemma(..)+    , Lemmas+    , addLemma+      -- * Reader Information+    , HasHermitMEnv(..)+    , mkEnv+    , getModGuts+    , HasHscEnv(..)+      -- * Writer Information+    , HasLemmas(..)+      -- * Messages+    , HasDebugChan(..)+    , DebugMessage(..)+    , sendDebugMessage+    ) where  import Prelude hiding (lookup) +import Data.Dynamic (Typeable) import Data.Map+import Data.String (IsString(..)) -import Control.Monad-import Control.Monad.IO.Class import Control.Applicative import Control.Arrow+import Control.Concurrent.STM+import Control.Monad+import Control.Monad.IO.Class  import Language.KURE @@ -44,78 +53,93 @@ import HERMIT.Context import HERMIT.Kure.SumTypes import HERMIT.GHC--#if __GLASGOW_HASKELL__ > 706 import HERMIT.GHC.Typechecker-#endif  ---------------------------------------------------------------------------- --- | A label for individual definitions.-type Label = String---- | A store of saved definitions.-type DefStash = Map Label CoreDef---- | A way of sending messages to top level-newtype HermitMEnv = HermitMEnv { hs_debugChan :: DebugMessage -> HermitM () }+-- | A label for individual definitions. Use a newtype so we can tab-complete in shell.+newtype RememberedName = RememberedName String deriving (Eq, Ord, Typeable) --- | The HERMIT monad is kept abstract.-newtype HermitM a = HermitM ((ModGuts,HermitMEnv) -> DefStash -> CoreM (KureM (DefStash, a)))+instance IsString RememberedName where fromString = RememberedName+instance Show RememberedName where show (RememberedName s) = s -runHermitM :: HermitM a -> (ModGuts,HermitMEnv) -> DefStash -> CoreM (KureM (DefStash, a))-runHermitM (HermitM f) = f+-- | A store of saved definitions.+type DefStash = Map RememberedName CoreDef --- | Eliminator for 'HermitM'.-runHM :: (ModGuts,HermitMEnv) -> DefStash -> (DefStash -> a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b-runHM env s success failure ma = runHermitM ma env s >>= runKureM (\ (a,b) -> success a b) failure+-- | An equality is represented as a set of universally quantified binders, and the LHS and RHS of the equality.+data Equality = Equality [CoreBndr] CoreExpr CoreExpr -----------------------------------------------------------------------------+-- | A name for lemmas. Use a newtype so we can tab-complete in shell.+newtype LemmaName = LemmaName String deriving (Eq, Ord, Typeable) --- | Get the stash of saved definitions.-getStash :: HermitM DefStash-getStash = HermitM (\ _ s -> return $ return (s, s))+instance IsString LemmaName where fromString = LemmaName+instance Show LemmaName where show (LemmaName s) = s --- | Replace the stash of saved definitions.-putStash :: DefStash -> HermitM ()-putStash s = HermitM (\ _ _ -> return $ return (s, ()))+-- | An equality with a proven status.+data Lemma = Lemma { lemmaEq :: Equality+                   , lemmaP  :: Bool     -- whether lemma has been proven+                   , lemmaU  :: Bool     -- whether lemma has been used+                   } -class HasHermitMEnv m where-    -- | Get the HermitMEnv-    getHermitMEnv :: m HermitMEnv+-- | A collectin of named lemmas.+type Lemmas = Map LemmaName Lemma -instance HasHermitMEnv HermitM where-    getHermitMEnv = HermitM (\ rdr s -> return $ return (s, snd rdr))+-- | The HermitM reader environment.+data HermitMEnv = HermitMEnv { hEnvModGuts   :: ModGuts -- ^ Note: this is a snapshot of the ModGuts from+                                                        --         before the current transformation.+                             , hEnvStash     :: DefStash+                             , hEnvLemmas    :: Lemmas+                             } -class HasModGuts m where-    -- | Get the ModGuts (Note: this is a snapshot of the ModGuts from before the current transformation.)-    getModGuts :: m ModGuts+mkEnv :: ModGuts -> DefStash -> Lemmas -> HermitMEnv+mkEnv = HermitMEnv -instance HasModGuts HermitM where-    getModGuts = HermitM (\ rdr s -> return $ return (s, fst rdr))+-- | The HermitM result record.+data HermitMResult a = HermitMResult { hResStash  :: DefStash+                                     , hResLemmas :: Lemmas+                                     , hResult    :: a+                                     } -class HasHscEnv m where-    getHscEnv :: m HscEnv+mkResult :: DefStash -> Lemmas -> a -> HermitMResult a+mkResult = HermitMResult -instance HasHscEnv CoreM where-    getHscEnv = getHscEnvCoreM+mkResultEnv :: HermitMEnv -> a -> HermitMResult a+mkResultEnv env = mkResult (hEnvStash env) (hEnvLemmas env) -instance HasHscEnv HermitM where-    getHscEnv = liftCoreM getHscEnv+-- | The HERMIT monad is kept abstract.+--+-- It provides a reader for ModGuts, state for DefStash and Lemmas,+-- and access to a debugging channel.+newtype HermitM a = HermitM { runHermitM :: DebugChan -> HermitMEnv -> CoreM (KureM (HermitMResult a)) } -sendDebugMessage :: DebugMessage -> HermitM ()-sendDebugMessage msg = do env <- getHermitMEnv-                          hs_debugChan env msg+type DebugChan = DebugMessage -> HermitM () --- | Save a definition for future use.-saveDef :: Label -> CoreDef -> HermitM ()-saveDef l d = getStash >>= (insert l d >>> putStash)+-- | Eliminator for 'HermitM'.+runHM :: DebugChan                     -- debug chan+      -> HermitMEnv                    -- env+      -> (HermitMResult a -> CoreM b)  -- success+      -> (String -> CoreM b)           -- failure+      -> HermitM a                     -- ma+      -> CoreM b+runHM chan env success failure ma = runHermitM ma chan env >>= runKureM success failure --- | Lookup a previously saved definition.-lookupDef :: Label -> HermitM CoreDef-lookupDef l = getStash >>= (lookup l >>> maybe (fail "Definition not found.") return)+-- | Allow HermitM to be embedded in another monad with proper capabilities.+embedHermitM :: (HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m) => HermitM a -> m a+embedHermitM hm = do+    env <- getHermitMEnv+    c <- liftCoreM $ liftIO newTChanIO -- we are careful to do IO within liftCoreM to avoid the MonadIO constraint+    r <- liftCoreM (runHermitM hm (liftIO . atomically . writeTChan c) env) >>= runKureM return fail+    chan <- getDebugChan+    let relayDebugMessages = do+            mm <- liftCoreM $ liftIO $ atomically $ tryReadTChan c+            case mm of+                Nothing -> return ()+                Just dm -> chan dm >> relayDebugMessages -----------------------------------------------------------------------------+    relayDebugMessages+    putStash $ hResStash r+    forM_ (toList (hResLemmas r)) $ uncurry insertLemma+    return $ hResult r  instance Functor HermitM where   fmap :: (a -> b) -> HermitM a -> HermitM b@@ -130,24 +154,22 @@  instance Monad HermitM where   return :: a -> HermitM a-  return a = HermitM $ \ _ s -> return (return (s,a))+  return a = HermitM $ \ _ env -> return (return (mkResultEnv env a))    (>>=) :: HermitM a -> (a -> HermitM b) -> HermitM b-  (HermitM gcm) >>= f = HermitM $ \ env -> gcm env >=> runKureM (\ (s', a) -> runHermitM (f a) env s') (return . fail)+  (HermitM gcm) >>= f =+        HermitM $ \ chan env -> gcm chan env >>= runKureM (\ (HermitMResult s ls a) ->+                                                            let env' = env { hEnvStash = s, hEnvLemmas = ls }+                                                            in  runHermitM (f a) chan env')+                                                          (return . fail)    fail :: String -> HermitM a   fail msg = HermitM $ \ _ _ -> return (fail msg)  instance MonadCatch HermitM where   catchM :: HermitM a -> (String -> HermitM a) -> HermitM a-  (HermitM gcm) `catchM` f = HermitM $ \ env s -> gcm env s >>= runKureM (return.return) (\ msg -> runHermitM (f msg) env s)---------------------------------------------------------------------------------- | 'CoreM' can be lifted to 'HermitM'.-liftCoreM :: CoreM a -> HermitM a-liftCoreM ma = HermitM $ \ _ s -> do a <- ma-                                     return (return (s,a))+  (HermitM gcm) `catchM` f = HermitM $ \ chan env -> gcm chan env >>= runKureM (return.return)+                                                                               (\ msg -> runHermitM (f msg) chan env)  instance MonadIO HermitM where   liftIO :: IO a -> HermitM a@@ -170,65 +192,120 @@     -- *most* things from the current module. However,     -- some Ids, such as class method selectors, are not     -- explicitly bound in the core, so will not be in-    -- the context. These are instead kept in the +    -- the context. These are instead kept in the     -- ModGuts' list of instances. Which this will find.-    lookupThing nm = do-#if __GLASGOW_HASKELL__ < 708-        liftCoreM (lookupThing nm)-#else-        guts <- getModGuts-        liftCoreM $ runTcMtoCoreM guts $ tcLookupGlobal nm-#endif+    lookupThing nm = runTcM $ tcLookupGlobal nm  instance HasDynFlags HermitM where-  getDynFlags :: HermitM DynFlags-  getDynFlags = liftCoreM getDynFlags+    getDynFlags :: HermitM DynFlags+    getDynFlags = liftCoreM getDynFlags  ---------------------------------------------------------------------------- -newName :: String -> HermitM Name-newName nm = mkSystemVarName <$> getUniqueM <*> pure (mkFastString nm)+class HasStash m where+    -- | Get the stash of saved definitions.+    getStash :: m DefStash --- | Make a unique global identifier for a specified type, using a provided name.-newGlobalIdH :: String -> Type -> HermitM Id-newGlobalIdH nm ty = mkVanillaGlobal <$> newName nm <*> pure ty+    -- | Replace the stash of saved definitions.+    putStash :: DefStash -> m () --- | Make a unique identifier for a specified type, using a provided name.-newIdH :: String -> Type -> HermitM Id-newIdH nm ty = mkLocalId <$> newName nm <*> pure ty+instance HasStash HermitM where+    getStash = HermitM $ \ _ env -> return $ return $ mkResultEnv env $ hEnvStash env --- | Make a unique type variable for a specified kind, using a provided name.-newTyVarH :: String -> Kind -> HermitM TyVar-newTyVarH nm k = mkTyVar <$> newName nm <*> pure k+    putStash s = HermitM $ \ _ env -> return $ return $ mkResult s (hEnvLemmas env) () --- | Make a unique coercion variable for a specified type, using a provided name.-newCoVarH :: String -> Type -> HermitM TyVar-newCoVarH nm ty = mkCoVar <$> newName nm <*> pure ty+-- | Save a definition for future use.+saveDef :: (HasStash m, Monad m) => RememberedName -> CoreDef -> m ()+saveDef l d = getStash >>= (insert l d >>> putStash) --- TODO: not sure if the predicates are correct.--- | Experimental, use at your own risk.-newVarH :: String -> KindOrType -> HermitM Var-newVarH name tk | isCoVarType tk = newCoVarH name tk-                | isKind tk      = newTyVarH name tk-                | otherwise      = newIdH name tk+-- | Lookup a previously saved definition.+lookupDef :: (HasStash m, Monad m) => RememberedName -> m CoreDef+lookupDef l = getStash >>= (lookup l >>> maybe (fail "Definition not found.") return) --- | Make a new variable of the same type, with a modified textual name.-cloneVarH :: (String -> String) -> Var -> HermitM Var-cloneVarH nameMod v | isTyVar v = newTyVarH name ty-                    | isCoVar v = newCoVarH name ty-                    | isId v    = newIdH name ty-                    | otherwise = fail "If this variable isn't a type, coercion or identifier, then what is it?"-  where-    name = nameMod (uqName v)-    ty   = varType v+---------------------------------------------------------------------------- +class HasHermitMEnv m where+    -- | Get the HermitMEnv+    getHermitMEnv :: m HermitMEnv++instance HasHermitMEnv HermitM where+    getHermitMEnv = HermitM $ \ _ env -> return $ return $ mkResultEnv env env++getModGuts :: (HasHermitMEnv m, Monad m) => m ModGuts+getModGuts = liftM hEnvModGuts getHermitMEnv+ ---------------------------------------------------------------------------- --- | A message packet.-data DebugMessage = DebugTick String-                  | DebugCore String HermitC CoreTC+class HasDebugChan m where+    -- | Get the debugging channel+    getDebugChan :: m (DebugMessage -> m ()) -mkHermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv-mkHermitMEnv debugger = HermitMEnv { hs_debugChan = debugger }+instance HasDebugChan HermitM where+    getDebugChan = HermitM $ \ chan env -> return $ return $ mkResultEnv env chan +sendDebugMessage :: (HasDebugChan m, Monad m) => DebugMessage -> m ()+sendDebugMessage msg = getDebugChan >>= ($ msg)+ ----------------------------------------------------------------------------++class HasHscEnv m where+    getHscEnv :: m HscEnv++instance HasHscEnv CoreM where+    getHscEnv = getHscEnvCoreM++instance HasHscEnv HermitM where+    getHscEnv = liftCoreM getHscEnv++----------------------------------------------------------------------------++class HasLemmas m where+    -- | Add (or replace) a named lemma.+    insertLemma :: LemmaName -> Lemma -> m ()++    getLemmas :: m Lemmas++instance HasLemmas HermitM where+    insertLemma nm l = HermitM $ \ _ env -> return $ return $ mkResult (hEnvStash env) (insert nm l $ hEnvLemmas env) ()++    getLemmas = HermitM $ \ _ env -> return $ return $ mkResultEnv env (hEnvLemmas env)++-- | Only adds a lemma if doesn't already exist.+addLemma :: (HasLemmas m, Monad m) => LemmaName -> Lemma -> m ()+addLemma nm l = do+    ls <- getLemmas+    maybe (insertLemma nm l) (\ _ -> return ()) (lookup nm ls)++----------------------------------------------------------------------------++class Monad m => LiftCoreM m where+    -- | 'CoreM' can be lifted to this monad.+    liftCoreM :: CoreM a -> m a++instance LiftCoreM HermitM where+    liftCoreM coreM = HermitM $ \ _ env -> coreM >>= return . return . mkResultEnv env++----------------------------------------------------------------------------++-- | A message packet.+data DebugMessage :: * where+    DebugTick ::                                       String                -> DebugMessage+    DebugCore :: (ReadBindings c, ReadPath c Crumb) => String -> c -> CoreTC -> DebugMessage++----------------------------------------------------------------------------++runTcM :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => TcM a -> m a+runTcM m = do+    env <- getHscEnv+    dflags <- getDynFlags+    guts <- getModGuts+    -- What is the effect of HsSrcFile (should we be using something else?)+    -- What should the boolean flag be set to?+    (msgs, mr) <- liftIO $ initTcFromModGuts env guts HsSrcFile False m+    let showMsgs (warns, errs) = showSDoc dflags $ vcat+                                                 $    text "Errors:" : pprErrMsgBag errs+                                                   ++ text "Warnings:" : pprErrMsgBag warns+    maybe (fail $ showMsgs msgs) return mr++runDsM :: (HasDynFlags m, HasHermitMEnv m, HasHscEnv m, MonadIO m) => DsM a -> m a+runDsM = runTcM . initDsTc
src/HERMIT/Name.hs view
@@ -1,15 +1,23 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ <= 706-{-# LANGUAGE ScopedTypeVariables #-}-#endif-module HERMIT.Name +{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleInstances, TypeFamilies #-}+module HERMIT.Name     ( HermitName+    , cmpHN2Name+    , cmpHN2Var     , fromRdrName     , toRdrName     , toRdrNames     , hnModuleName     , hnUnqualified     , parseName+    , showName+      -- * Wrappers+    , OccurrenceName(..)+    , OccurrenceNameListBox(..)+    , mkOccPred+    , BindingName(..)+    , mkBindingPred+    , RhsOfName(..)+    , mkRhsOfPred       -- * Namespaces     , Named(..)     , varToNamed@@ -18,37 +26,36 @@     , tyConClassNS     , tyVarNS     , varNS+      -- * Variable Creation+    , newGlobalIdH+    , newIdH+    , newTyVarH+    , newCoVarH+    , newVarH+    , cloneVarH       -- * Name Lookup     , findId-#if __GLASGOW_HASKELL__ > 706     , findVar     , findTyCon     , findType     , findInNameSpace     , findInNameSpaces-#endif     ) where  import Control.Monad import Control.Monad.IO.Class -#if __GLASGOW_HASKELL__ <= 706 import Data.List (intercalate)-#endif+import Data.Dynamic (Typeable)+import Data.String (IsString(..))  import HERMIT.Context+import HERMIT.External import HERMIT.GHC import HERMIT.Kure import HERMIT.Monad --- | A 'HermitName' is an optionally fully-qualified name,--- like GHC's 'RdrName', but without specifying which 'NameSpace'--- the name is found in.-data HermitName = HermitName { hnModuleName  :: Maybe ModuleName-                             , hnUnqualified :: String -                             }---- | Possible results from name lookup. +-- | Possible results from name lookup. -- Invariant: One constructor for each NameSpace. data Named = NamedId Id            | NamedDataCon DataCon@@ -88,15 +95,63 @@  ---------------------------------------------------------- +-- | A 'HermitName' is an optionally fully-qualified name,+-- like GHC's 'RdrName', but without specifying which 'NameSpace'+-- the name is found in.+data HermitName = HermitName { hnModuleName  :: Maybe ModuleName+                             , hnUnqualified :: String+                             }+    deriving (Eq, Typeable)++instance Extern HermitName where+    type Box HermitName = HermitName+    box = id+    unbox = id++instance IsString HermitName where fromString = parseName+instance Show HermitName where show = showName++-- | Compare a HermitName to a Var.+--+-- Only compare module names if the HermitName is fully qualified.+-- Otherwise match variables from any module with appropriate occurrence name.+cmpHN2Var :: HermitName -> Var -> Bool+cmpHN2Var hn = cmpHN2Name hn . varName++cmpHN2Name :: HermitName -> Name -> Bool+cmpHN2Name (HermitName hm nm) n+    | Just mn <- hm+    , Just m  <- nameModule_maybe n = (mn == moduleName m) && sameOccName+    | otherwise     = sameOccName+    where sameOccName = nm == unqualifiedName n++-- | Make a qualified HermitName from a String representing the module name+-- and a String representing the occurrence name. mkQualified :: String -> String -> HermitName mkQualified mnm nm = HermitName (Just $ mkModuleName mnm) nm--- mkOccName--- mkRdrQual +-- | Make an unqualified HermitName from a String. mkUnqualified :: String -> HermitName mkUnqualified = HermitName Nothing--- mkRdrUnqual +-- | Parse a HermitName from a String.+parseName :: String -> HermitName+parseName s | isQualified s = parseQualified s+            | otherwise     = mkUnqualified s++-- | Parse a qualified HermitName from a String.+parseQualified :: String -> HermitName+parseQualified [] = error "parseQualified: empty string"+parseQualified s = mkQualified mnm nm+    where (c:cs) = reverse s -- we are careful to parse 'Prelude..' correctly+          (rNm, _dot:rMod) = break (=='.') cs+          (nm, mnm) = (reverse (c:rNm), reverse rMod)++-- | Turn a HermitName into a (possibly fully-qualified) String.+showName :: HermitName -> String+showName (HermitName mnm nm) = maybe id (\ m n -> moduleNameString m ++ ('.' : n)) mnm nm++-- | Make a HermitName from a RdrName fromRdrName :: RdrName -> HermitName fromRdrName nm = case isQual_maybe nm of                     Nothing         -> HermitName Nothing    (occNameString $ rdrNameOcc nm)@@ -111,26 +166,55 @@ toRdrNames :: [NameSpace] -> HermitName -> [RdrName] toRdrNames nss hnm = [ toRdrName ns hnm | ns <- nss ] -parseQualified :: String -> HermitName-parseQualified [] = error "parseQualified: empty string"-parseQualified s = mkQualified mnm nm-    where (c:cs) = reverse s -- we are careful to parse 'Prelude..' correctly-          (rNm, _dot:rMod) = break (=='.') cs-          (nm, mnm) = (reverse (c:rNm), reverse rMod)+-------------------------------------------------------------------------------------------------- --- | Parse a HermitName from a String.-parseName :: String -> HermitName-parseName s | isQualified s = parseQualified s-            | otherwise     = mkUnqualified s+-- Newtype wrappers used for type-based command completion +newtype BindingName = BindingName { unBindingName :: HermitName } deriving Typeable++instance Extern BindingName where+    type Box BindingName = BindingName+    box = id+    unbox = id++mkBindingPred :: BindingName -> Var -> Bool+mkBindingPred (BindingName hnm) = cmpHN2Var hnm++newtype OccurrenceName = OccurrenceName { unOccurrenceName :: HermitName } deriving Typeable++instance Extern OccurrenceName where+    type Box OccurrenceName = OccurrenceName+    box = id+    unbox = id++mkOccPred :: OccurrenceName -> Var -> Bool+mkOccPred (OccurrenceName hnm) = cmpHN2Var hnm++newtype OccurrenceNameListBox = OccurrenceNameListBox [OccurrenceName] deriving Typeable++instance Extern [OccurrenceName] where+    type Box [OccurrenceName] = OccurrenceNameListBox+    box = OccurrenceNameListBox+    unbox (OccurrenceNameListBox l) = l++newtype RhsOfName = RhsOfName { unRhsOfName :: HermitName } deriving Typeable++instance Extern RhsOfName where+    type Box RhsOfName = RhsOfName+    box = id+    unbox = id++mkRhsOfPred :: RhsOfName -> Var -> Bool+mkRhsOfPred (RhsOfName hnm) = cmpHN2Var hnm+ --------------------------------------------------------------------------------------------------  -- | An instance of 'MonadThings' for 'Transform', which looks in the context first. -- -- NB: we store TyVars in the context, but the 'TyThing' return type is not rich enough--- to return them. So 'lookupThing' cannot be used to look up TyVars. +-- to return them. So 'lookupThing' cannot be used to look up TyVars. -- TODO: add function for this, or modify GHC's 'TyThing'?-instance (MonadThings m, BoundVars c) => MonadThings (Transform c m a) where +instance (MonadThings m, BoundVars c) => MonadThings (Transform c m a) where     lookupThing nm = contextonlyT $ \ c ->                         case varSetElems $ filterVarSet ((== nm) . varName) (boundVars c) of                             (i:_) | isVarName nm -> return $ AnId i@@ -140,9 +224,8 @@  -------------------------------------------------------------------------------------------------- -#if __GLASGOW_HASKELL__ > 706-findId :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) -       => String -> c -> m Id+findId :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+       => HermitName -> c -> m Id findId nm c = do     nmd <- findInNameSpaces [varNS, dataConNS] nm c     case nmd of@@ -150,8 +233,8 @@         NamedDataCon dc -> return $ dataConWrapId dc         other -> fail $ "findId: impossible Named returned: " ++ show other -findVar :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) -       => String -> c -> m Var+findVar :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+       => HermitName -> c -> m Var findVar nm c = do     nmd <- findInNameSpaces [varNS, tyVarNS, dataConNS] nm c     case nmd of@@ -160,16 +243,16 @@         NamedDataCon dc -> return $ dataConWrapId dc         other -> fail $ "findVar: impossible Named returned: " ++ show other -findTyCon :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) -          => String -> c -> m TyCon+findTyCon :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+          => HermitName -> c -> m TyCon findTyCon nm c = do     nmd <- findInNameSpace tyConClassNS nm c     case nmd of         NamedTyCon tc -> return tc         other -> fail $ "findTyCon: impossible Named returned: " ++ show other -findType :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) -         => String -> c -> m Type+findType :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+         => HermitName -> c -> m Type findType nm c = do     nmd <- findInNameSpaces [tyVarNS, tyConClassNS] nm c     case nmd of@@ -179,21 +262,21 @@  -------------------------------------------------------------------------------------------------- -findInNameSpaces :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadCatch m, MonadIO m, MonadThings m) -                 => [NameSpace] -> String -> c -> m Named+findInNameSpaces :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadCatch m, MonadIO m, MonadThings m)+                 => [NameSpace] -> HermitName -> c -> m Named findInNameSpaces nss nm c = setFailMsg "Variable not in scope." -- because catchesM clobbers failure messages.                           $ catchesM [ findInNameSpace ns nm c | ns <- nss ] -findInNameSpace :: (BoundVars c, HasHscEnv m, HasModGuts m, MonadIO m, MonadThings m) -                => NameSpace -> String -> c -> m Named-findInNameSpace ns nm c = -    case filter ((== ns) . occNameSpace . getOccName) $ varSetElems (findBoundVars nm c) of+findInNameSpace :: (BoundVars c, HasHscEnv m, HasHermitMEnv m, MonadIO m, MonadThings m)+                => NameSpace -> HermitName -> c -> m Named+findInNameSpace ns nm c =+    case varSetElems $ filterVarSet ((== ns) . occNameSpace . getOccName) $ findBoundVars (cmpHN2Var nm) c of         _ : _ : _ -> fail "multiple matching variables in scope."         [v]       -> return $ varToNamed v-        []        -> findInNSModGuts ns (parseName nm)+        []        -> findInNSModGuts ns nm  -- | Looks for Named in current GlobalRdrEnv. If not present, calls 'findInNSPackageDB'.-findInNSModGuts :: (HasHscEnv m, HasModGuts m, MonadIO m, MonadThings m) +findInNSModGuts :: (HasHscEnv m, HasHermitMEnv m, MonadIO m, MonadThings m)                 => NameSpace -> HermitName -> m Named findInNSModGuts ns nm = do     rdrEnv <- liftM mg_rdr_env getModGuts@@ -203,37 +286,37 @@         _     -> fail "findInNSModGuts: multiple names returned"  -- | Looks for Named in package database, or built-in packages.-findInNSPackageDB :: (HasHscEnv m, HasModGuts m, MonadIO m, MonadThings m) +findInNSPackageDB :: (HasHscEnv m, HasHermitMEnv m, MonadIO m, MonadThings m)                   => NameSpace -> HermitName -> m Named findInNSPackageDB ns nm = do     mnm <- lookupName ns nm     case mnm of-        Nothing -> findNamedBuiltIn ns (hnUnqualified nm)+        Nothing -> findNamedBuiltIn ns nm         Just n  -> nameToNamed n --- | Helper to call GHC's lookupRdrNameInModuleForPlugins-lookupName :: (HasModGuts m, HasHscEnv m, MonadIO m) => NameSpace -> HermitName -> m (Maybe Name)+-- | Helper to call lookupRdrNameInModule+lookupName :: (HasHermitMEnv m, HasHscEnv m, MonadIO m) => NameSpace -> HermitName -> m (Maybe Name) lookupName ns nm = case isQual_maybe rdrName of                     Nothing    -> return Nothing -- we can't use lookupName on the current module                     Just (m,_) -> do                         hscEnv <- getHscEnv                         guts <- getModGuts-                        liftIO $ lookupRdrNameInModuleForPlugins hscEnv guts m rdrName+                        liftIO $ lookupRdrNameInModule hscEnv guts m rdrName     where rdrName = toRdrName ns nm  -- | Looks for Named amongst GHC's built-in DataCons/TyCons.-findNamedBuiltIn :: Monad m => NameSpace -> String -> m Named-findNamedBuiltIn ns str-    | isValNameSpace ns = -        case [ dc | tc <- wiredInTyCons, dc <- tyConDataCons tc, str == getOccString dc ] of+findNamedBuiltIn :: Monad m => NameSpace -> HermitName -> m Named+findNamedBuiltIn ns hnm+    | isValNameSpace ns =+        case [ dc | tc <- wiredInTyCons, dc <- tyConDataCons tc, cmpHN2Name hnm (getName dc) ] of             [] -> fail "name not in scope."             [dc] -> return $ NamedDataCon dc-            dcs -> fail $ "multiple DataCons match: " ++ show (map getOccString dcs)-    | isTcClsNameSpace ns = -        case [ tc | tc <- wiredInTyCons, str == getOccString tc ] of+            dcs -> fail $ "multiple DataCons match: " ++ intercalate ", " (map unqualifiedName dcs)+    | isTcClsNameSpace ns =+        case [ tc | tc <- wiredInTyCons, cmpHN2Name hnm (getName tc) ] of             [] -> fail "type name not in scope."             [tc] -> return $ NamedTyCon tc-            tcs -> fail $ "multiple TyCons match: " ++ show (map getOccString tcs)+            tcs -> fail $ "multiple TyCons match: " ++ intercalate ", " (map unqualifiedName tcs)     | otherwise = fail "findNameBuiltIn: unusable NameSpace"  -- | We have a name, find the corresponding Named.@@ -244,49 +327,47 @@               | isTyVarName n   = fail "nameToNamed: impossible, TyVars are not exported and cannot be looked up."               | otherwise       = fail "nameToNamed: unknown name type" -#else---- | Looks for Id with given name in the context. If it is not present, calls 'findIdMG'.-findId :: (BoundVars c, HasModGuts m, HasHscEnv m, MonadCatch m, MonadIO m, MonadThings m) => String -> c -> m Id-findId nm c = case varSetElems (findBoundVars nm c) of-                []         -> findIdMG (parseName nm) -                [v]        -> return v-                _ : _ : _  -> fail "multiple matching variables in scope."--findIdMG :: (HasModGuts m, MonadThings m) => HermitName -> m Id-findIdMG hnm = do-    let nm = hnUnqualified hnm-    rdrEnv <- liftM mg_rdr_env getModGuts-    case filter isValName $ findNamesFromString rdrEnv nm of-        []  -> findIdBuiltIn nm-        [n] -> nameToId n-        ns  -> fail $ "multiple matches found:\n" ++ intercalate ", " (map getOccString ns)+-- Someday, when Applicative is a superclass of monad, we can uncomment the+-- nicer applicative definitions. For now, we don't want the extra constraint. --- | We have a name, find the corresponding Id.-nameToId :: MonadThings m => Name -> m Id-nameToId n | isVarName n     = lookupId n-           | isDataConName n = liftM dataConWrapId $ lookupDataCon n-           | otherwise       = fail "nameToId: unknown name type"+-- | Make a 'Name' from a string.+newName :: MonadUnique m => String -> m Name+newName nm = getUniqueM >>= return . flip mkSystemVarName (mkFastString nm)+-- newName nm = mkSystemVarName <$> getUniqueM <*> pure (mkFastString nm) -findIdBuiltIn :: forall m. Monad m => String -> m Id-findIdBuiltIn = go-    where go ":"     = dataConId consDataCon-          go "[]"    = dataConId nilDataCon+-- | Make a unique global identifier for a specified type, using a provided name.+newGlobalIdH :: MonadUnique m => String -> Type -> m Id+newGlobalIdH nm ty = newName nm >>= return . flip mkVanillaGlobal ty+-- newGlobalIdH nm ty = mkVanillaGlobal <$> newName nm <*> pure ty -          go "True"  = return trueDataConId-          go "False" = return falseDataConId+-- | Make a unique identifier for a specified type, using a provided name.+newIdH :: MonadUnique m => String -> Type -> m Id+newIdH nm ty = newName nm >>= return . flip mkLocalId ty+-- newIdH nm ty = mkLocalId <$> newName nm <*> pure ty -          go "<"     = return ltDataConId-          go "=="    = return eqDataConId-          go ">"     = return gtDataConId+-- | Make a unique type variable for a specified kind, using a provided name.+newTyVarH :: MonadUnique m => String -> Kind -> m TyVar+newTyVarH nm k = newName nm >>= return . flip mkTyVar k+-- newTyVarH nm k = mkTyVar <$> newName nm <*> pure k -          go "I#"    = dataConId intDataCon+-- | Make a unique coercion variable for a specified type, using a provided name.+newCoVarH :: MonadUnique m => String -> Type -> m TyVar+newCoVarH nm ty = newName nm >>= return . flip mkCoVar ty+-- newCoVarH nm ty = mkCoVar <$> newName nm <*> pure ty -          go "()"    = return unitDataConId-          -- TODO: add more as needed-          --       http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/TysWiredIn.html-          go _   = fail "variable not in scope."+-- TODO: not sure if the predicates are correct.+-- | Experimental, use at your own risk.+newVarH :: MonadUnique m => String -> KindOrType -> m Var+newVarH name tk | isCoVarType tk = newCoVarH name tk+                | isKind tk      = newTyVarH name tk+                | otherwise      = newIdH name tk -          dataConId :: DataCon -> m Id-          dataConId = return . dataConWorkId-#endif+-- | Make a new variable of the same type, with a modified textual name.+cloneVarH :: MonadUnique m => (String -> String) -> Var -> m Var+cloneVarH nameMod v | isTyVar v = newTyVarH name ty+                    | isCoVar v = newCoVarH name ty+                    | isId v    = newIdH name ty+                    | otherwise = fail "If this variable isn't a type, coercion or identifier, then what is it?"+  where+    name = nameMod (unqualifiedName v)+    ty   = varType v
src/HERMIT/Parser.y view
@@ -5,6 +5,7 @@     , unparseScript     , unparseExprH     , ExprH(..)+    , parseExprH     ) where  import Data.Char (isSpace)@@ -16,7 +17,8 @@  } -%name parser+%name parser scoped+%name exprParser ExprH %tokentype { Token } %error { parseError } %monad { Either String } { >>= } { return }@@ -162,6 +164,9 @@  parseScript :: String -> Either String Script parseScript = lexer >=> parser++parseExprH :: String -> Either String ExprH+parseExprH = lexer >=> exprParser  --------------------------------------------- 
src/HERMIT/ParserCore.y view
@@ -3,6 +3,8 @@ module HERMIT.ParserCore     ( parseCore     , parseCoreExprT+    , parse2BeforeT+    , parse3BeforeT     , parse2beforeBiR     , parse3beforeBiR     , parse4beforeBiR@@ -89,21 +91,17 @@ {  mkIntExpr' :: Integer -> CoreParseM CoreExpr-#if __GLASGOW_HASKELL__ > 706 mkIntExpr' i = do     dflags <- lift getDynFlags     return $ mkIntExpr dflags i-#else-mkIntExpr' i = return $ mkIntExpr i-#endif  lookupName :: String -> CoreParseM CoreExpr lookupName nm = do-    c <- ask-    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId nm c+    vset <- ask+    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId (parseName nm) vset     return $ varToCoreExpr v -type CoreParseM a = ReaderT HermitC HermitM a+type CoreParseM a = ReaderT VarSet HermitM a  parseError :: Monad m => [Token] -> m a parseError ts = fail $ "core parse error: " ++ show ts@@ -170,19 +168,30 @@  --------------------------------------------- -parseCore :: CoreString -> HermitC -> HermitM CoreExpr+parseCore :: BoundVars c => CoreString -> c -> HermitM CoreExpr parseCore (CoreString s) c =     case lexer s of         Left msg -> fail msg-        Right tokens -> runReaderT (parser tokens) c+        Right tokens -> runReaderT (parser tokens) (boundVars c)  ---------------------------------------------  -- These should probably go somewhere else.  -- | Parse a 'CoreString' to a 'CoreExpr', using the current context.-parseCoreExprT :: CoreString -> TransformH a CoreExpr-parseCoreExprT = contextonlyT . parseCore+parseCoreExprT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m)+               => CoreString -> Transform c m a CoreExpr+parseCoreExprT cs = contextonlyT $ embedHermitM . parseCore cs++parse2BeforeT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m)+              => (CoreExpr -> CoreExpr -> Translate c m a b)+              -> CoreString -> CoreString -> Translate c m a b+parse2BeforeT f s1 s2 = parseCoreExprT s1 &&& parseCoreExprT s2 >>= uncurry f++parse3BeforeT :: (BoundVars c, HasDebugChan m, HasHermitMEnv m, HasLemmas m, HasStash m, LiftCoreM m)+              => (CoreExpr -> CoreExpr -> CoreExpr -> Translate c m a b)+              -> CoreString -> CoreString -> CoreString -> Translate c m a b+parse3BeforeT f s1 s2 s3 = (parseCoreExprT s1 &&& parseCoreExprT s2) &&& parseCoreExprT s3 >>= (uncurry . uncurry $ f)  parse2beforeBiR :: (CoreExpr -> CoreExpr -> BiRewriteH a)                 -> CoreString -> CoreString -> BiRewriteH a
src/HERMIT/ParserType.y view
@@ -1,15 +1,11 @@ { {-# LANGUAGE CPP #-} module HERMIT.ParserType-#if __GLASGOW_HASKELL__ <= 706-    () where-#else     ( parseType     , parseTypeT     , parseTypeWithHoles     , parseTypeWithHolesT     ) where-#endif  import Control.Arrow import Control.Monad.State@@ -87,14 +83,10 @@ tyvar : NAME               {% lookupName $1 } { -#if __GLASGOW_HASKELL__ <= 706-findType = error "findType cannot be called in < GHC 7.8"-#endif- lookupName :: String -> TypeParseM Type lookupName nm = do     c <- getContext-    et <- lift $ attemptM $ findType nm c+    et <- lift $ attemptM $ findType (parseName nm) c     either (const (addTyVar nm)) return et  catchFrees :: Type -> TypeParseM ([TyVar], Type)@@ -117,7 +109,7 @@ addTyVar :: String -> TypeParseM Type addTyVar tvStr = do     used <- gets tpUsed-    case [ tv | tv <- used, getOccString tv == tvStr ] of+    case [ tv | tv <- used, unqualifiedName tv == tvStr ] of         [] -> do tv <- lift $ newTyVarH tvStr liftedTypeKind                  modify $ \ st -> st { tpUsed = tv : tpUsed st }                  return $ mkTyVarTy tv
src/HERMIT/Plugin.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE KindSignatures, GADTs, FlexibleContexts, GeneralizedNewtypeDeriving, LambdaCase #-}+{-# LANGUAGE KindSignatures, GADTs, FlexibleContexts, GeneralizedNewtypeDeriving, LambdaCase, CPP #-} module HERMIT.Plugin     ( -- * The HERMIT Plugin       hermitPlugin@@ -12,15 +12,15 @@     , setPrettyOptions       -- ** Active modifiers     , at-    , phase+    , pass     , after     , before     , until-    , allPhases-    , firstPhase-    , lastPhase+    , allPasses+    , firstPass+    , lastPass       -- ** Knobs and Dials-    , getPhaseInfo+    , getPassInfo     , modifyCLS       -- ** Types     , defPS@@ -31,7 +31,11 @@ import Control.Applicative import Control.Arrow import Control.Concurrent.STM+#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except hiding (guard)+#else import Control.Monad.Error hiding (guard)+#endif import Control.Monad.Operational import Control.Monad.State hiding (guard) @@ -40,12 +44,12 @@  import HERMIT.Dictionary import HERMIT.External hiding (Query, Shell)+import HERMIT.Kernel (KernelEnv) import HERMIT.Kernel.Scoped import HERMIT.Context import HERMIT.Kure import HERMIT.GHC hiding (singleton, liftIO, display, (<>)) import qualified HERMIT.GHC as GHC-import HERMIT.Monad  import HERMIT.Plugin.Builder import qualified HERMIT.Plugin.Display as Display@@ -59,13 +63,11 @@  import Prelude hiding (until) -import System.Console.Haskeline (defaultBehavior)- hermitPlugin :: ([CommandLineOption] -> HPM ()) -> Plugin-hermitPlugin f = buildPlugin $ \ phaseInfo -> runHPM phaseInfo . f+hermitPlugin f = buildPlugin $ \ passInfo -> runHPM passInfo . f -defPS :: SAST -> ScopedKernel -> PhaseInfo -> IO PluginState-defPS initSAST kernel phaseInfo = do+defPS :: SAST -> ScopedKernel -> PassInfo -> IO PluginState+defPS initSAST kernel passInfo = do     emptyTick <- liftIO $ atomically $ newTVar M.empty     return $ PluginState                 { ps_cursor         = initSAST@@ -76,12 +78,12 @@                 , ps_diffonly       = False                 , ps_failhard       = False                 , ps_kernel         = kernel-                , ps_phase          = phaseInfo+                , ps_pass           = passInfo                 }  data HPMInst :: * -> * where     Shell    :: [External] -> [CommandLineOption] -> HPMInst ()-    Guard    :: (PhaseInfo -> Bool) -> HPM ()     -> HPMInst ()+    Guard    :: (PassInfo -> Bool) -> HPM ()     -> HPMInst ()     Focus    :: (Injection ModGuts g, Walker HermitC g) => TransformH g LocalPathH -> HPM a -> HPMInst a     RR       :: (Injection ModGuts g, Walker HermitC g) => RewriteH g                       -> HPMInst ()     Query    :: (Injection ModGuts g, Walker HermitC g) => TransformH g a                   -> HPMInst a@@ -89,14 +91,18 @@ newtype HPM a = HPM { unHPM :: ProgramT HPMInst PluginM a }     deriving (Functor, Applicative, Monad, MonadIO) -runHPM :: PhaseInfo -> HPM () -> ModGuts -> CoreM ModGuts-runHPM phaseInfo pass = scopedKernel $ \ kernel initSAST -> do-    ps <- defPS initSAST kernel phaseInfo-    (r,st) <- hpmToIO ps pass+runHPM :: PassInfo -> HPM () -> ModGuts -> CoreM ModGuts+runHPM passInfo hpass = scopedKernel $ \ kernel initSAST -> do+    ps <- defPS initSAST kernel passInfo+    (r,st) <- hpmToIO ps hpass+    let cleanup sast = do+            if sast /= initSAST -- only do this if we actually changed the AST+            then applyS kernel occurAnalyseAndDezombifyR (mkKernelEnv st) sast >>= resumeS kernel+            else resumeS kernel sast     either (\case PAbort       -> abortS kernel-                  PResume sast -> resumeS kernel sast+                  PResume sast -> cleanup sast                   PError  err  -> putStrLn err >> abortS kernel)-           (\ _ -> resumeS kernel $ ps_cursor st) r+           (\ _ -> cleanup $ ps_cursor st) r  hpmToIO :: PluginState -> HPM a -> IO (Either PException a, PluginState) hpmToIO initState = runPluginT initState . eval . unHPM@@ -113,11 +119,11 @@             -- We want to discard the current focus, open the shell at             -- the top level, then restore the current focus.             paths <- resetScoping env-            clm (commandLine os defaultBehavior es)+            clm (commandLine interpShellCommand os es)             _ <- resetScoping env             restoreScoping env paths             eval $ k ()-        Guard p (HPM m)  :>>= k  -> gets (p . ps_phase) >>= \ b -> when b (eval m) >>= eval . k+        Guard p (HPM m)  :>>= k  -> gets (p . ps_pass) >>= \ b -> when b (eval m) >>= eval . k         Focus tp (HPM m) :>>= k  -> do             p <- runK (queryS kernel tp env)  -- run the pathfinding translation             runS $ beginScopeS kernel         -- remember the current path@@ -128,7 +134,7 @@  ------------------------- Shell-related helpers -------------------------------------- -resetScoping :: HermitMEnv -> PluginM [PathH]+resetScoping :: KernelEnv -> PluginM [PathH] resetScoping env = do     kernel <- gets ps_kernel     paths <- runK $ pathS kernel@@ -137,7 +143,7 @@     catchM (runS $ modPathS kernel (const mempty) env) (const (return ()))     return paths -restoreScoping :: HermitMEnv -> [PathH] -> PluginM ()+restoreScoping :: KernelEnv -> [PathH] -> PluginM () restoreScoping _   []    = return () restoreScoping env (h:t) = do     kernel <- gets ps_kernel@@ -172,41 +178,41 @@  ----------------------------- guards ------------------------------ -guard :: (PhaseInfo -> Bool) -> HPM () -> HPM ()+guard :: (PassInfo -> Bool) -> HPM () -> HPM () guard p = HPM . singleton . Guard p  at :: TransformH CoreTC LocalPathH -> HPM a -> HPM a at tp = HPM . singleton . Focus tp -phase :: Int -> HPM () -> HPM ()-phase n = guard ((n ==) . phaseNum)+pass :: Int -> HPM () -> HPM ()+pass n = guard ((n ==) . passNum)  after :: CorePass -> HPM () -> HPM ()-after cp = guard (\phaseInfo -> case phasesDone phaseInfo of+after cp = guard (\passInfo -> case passesDone passInfo of                             [] -> False                             xs -> last xs == cp)  before :: CorePass -> HPM () -> HPM ()-before cp = guard (\phaseInfo -> case phasesLeft phaseInfo of+before cp = guard (\passInfo -> case passesLeft passInfo of                             (x:_) | cp == x -> True                             _               -> False)  until :: CorePass -> HPM () -> HPM ()-until cp = guard ((cp `elem`) . phasesLeft)+until cp = guard ((cp `elem`) . passesLeft) -allPhases :: HPM () -> HPM ()-allPhases = guard (const True)+allPasses :: HPM () -> HPM ()+allPasses = guard (const True) -firstPhase :: HPM () -> HPM ()-firstPhase = guard (null . phasesDone)+firstPass :: HPM () -> HPM ()+firstPass = guard (null . passesDone) -lastPhase :: HPM () -> HPM ()-lastPhase = guard (null . phasesLeft)+lastPass :: HPM () -> HPM ()+lastPass = guard (null . passesLeft)  ----------------------------- other ------------------------------ -getPhaseInfo :: HPM PhaseInfo-getPhaseInfo = HPM $ lift $ gets ps_phase+getPassInfo :: HPM PassInfo+getPassInfo = HPM $ lift $ gets ps_pass  display :: HPM () display = HPM $ lift $ Display.display Nothing
src/HERMIT/Plugin/Builder.hs view
@@ -7,8 +7,8 @@     , CorePass(..)     , getCorePass     , ghcPasses-    , PhaseInfo(..)-    , getPhaseFlag+    , PassInfo(..)+    , getPassFlag     )  where  import Data.List@@ -17,7 +17,7 @@ import HERMIT.GHC  -- | Given a list of 'CommandLineOption's, produce the 'ModGuts' to 'ModGuts' function required to build a plugin.-type PluginPass = PhaseInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts+type PluginPass = PassInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts  -- | Build a plugin. This mainly handles the per-module options. buildPlugin :: PluginPass -> Plugin@@ -31,6 +31,9 @@             liftIO $ hSetBuffering stdout NoBuffering #ifdef mingw32_HOST_OS             liftIO $ hSetEncoding stdout utf8+            -- This is a hacky workaround of a bug in Windows GHC.+            -- See https://ghc.haskell.org/trac/ghc/ticket/8276+            liftIO initStaticOpts #endif              let todos' = flattenTodos todos@@ -38,12 +41,12 @@                 allPasses = foldr (\ (n,p,seen,notyet) r -> mkPass n seen notyet : p : r)                                   [mkPass (length todos') passes []]                                   (zip4 [0..] todos' (inits passes) (tails passes))-                mkPass n ps ps' = CoreDoPluginPass ("HERMIT" ++ show n) $ modFilter hp (PhaseInfo n ps ps') opts+                mkPass n ps ps' = CoreDoPluginPass ("HERMIT" ++ show n) $ modFilter hp (PassInfo n ps ps') opts              return allPasses  -- | Determine whether to act on this module, choose plugin pass.--- NB: we have the ability to stick module info in the phase info here+-- NB: we have the ability to stick module info in the pass info here modFilter :: PluginPass -> PluginPass modFilter hp pInfo opts guts     | null modOpts && notNull opts = return guts -- don't process this module@@ -64,7 +67,7 @@     where modName = moduleNameString $ moduleName $ mg_module guts           len = length modName + 1 -- for the colon --- | An enumeration type for GHC's phases.+-- | An enumeration type for GHC's passes. data CorePass = FloatInwards               | LiberateCase               | PrintCore@@ -112,26 +115,26 @@             ]  getCorePass :: CoreToDo -> CorePass-getCorePass CoreDoFloatInwards  = FloatInwards-getCorePass CoreLiberateCase    = LiberateCase-getCorePass CoreDoPrintCore     = PrintCore-getCorePass CoreDoStaticArgs    = StaticArgs-getCorePass CoreDoStrictness    = Strictness-getCorePass CoreDoWorkerWrapper = WorkerWrapper-getCorePass CoreDoSpecialising  = Specialising-getCorePass CoreDoSpecConstr    = SpecConstr-getCorePass CoreCSE             = CSE-getCorePass CoreDoVectorisation = Vectorisation-getCorePass CoreDesugar         = Desugar-getCorePass CoreDesugarOpt      = DesugarOpt-getCorePass CoreTidy            = Tidy-getCorePass CorePrep            = Prep-getCorePass (CoreDoSimplify {}) = Simplify+getCorePass CoreDoFloatInwards       = FloatInwards+getCorePass CoreLiberateCase         = LiberateCase+getCorePass CoreDoPrintCore          = PrintCore+getCorePass CoreDoStaticArgs         = StaticArgs+getCorePass CoreDoStrictness         = Strictness+getCorePass CoreDoWorkerWrapper      = WorkerWrapper+getCorePass CoreDoSpecialising       = Specialising+getCorePass CoreDoSpecConstr         = SpecConstr+getCorePass CoreCSE                  = CSE+getCorePass CoreDoVectorisation      = Vectorisation+getCorePass CoreDesugar              = Desugar+getCorePass CoreDesugarOpt           = DesugarOpt+getCorePass CoreTidy                 = Tidy+getCorePass CorePrep                 = Prep+getCorePass (CoreDoSimplify {})      = Simplify getCorePass (CoreDoFloatOutwards {}) = FloatOutwards-getCorePass (CoreDoRuleCheck {}) = RuleCheck-getCorePass (CoreDoPasses {})   = Passes -- these should be flattened out in practice-getCorePass (CoreDoPluginPass nm _) = PluginPass nm-getCorePass CoreDoNothing       = NoOp+getCorePass (CoreDoRuleCheck {})     = RuleCheck+getCorePass (CoreDoPasses {})        = Passes -- these should be flattened out in practice+getCorePass (CoreDoPluginPass nm _)  = PluginPass nm+getCorePass CoreDoNothing            = NoOp -- getCorePass _                   = Unknown  flattenTodos :: [CoreToDo] -> [CoreToDo]@@ -140,16 +143,16 @@           f CoreDoNothing     = []           f other             = [other] -data PhaseInfo =-    PhaseInfo { phaseNum :: Int-              , phasesDone :: [CorePass]-              , phasesLeft :: [CorePass]-              }+data PassInfo =+    PassInfo { passNum :: Int+             , passesDone :: [CorePass]+             , passesLeft :: [CorePass]+             }     deriving (Read, Show, Eq)  -- | If HERMIT user specifies the -pN flag, get the N -- TODO: as written will discard other flags that start with -p-getPhaseFlag :: [CommandLineOption] -> Maybe (Int, [CommandLineOption])-getPhaseFlag opts = case partition ("-p" `isPrefixOf`) opts of+getPassFlag :: [CommandLineOption] -> Maybe (Int, [CommandLineOption])+getPassFlag opts = case partition ("-p" `isPrefixOf`) opts of                         ([],_) -> Nothing                         (ps,r) -> Just (read (drop 2 (last ps)), r)
src/HERMIT/Plugin/Renderer.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP, FlexibleContexts #-} module HERMIT.Plugin.Renderer where  import Control.Arrow@@ -11,9 +11,16 @@ import HERMIT.Kure import HERMIT.Plugin.Types import HERMIT.PrettyPrinter.Common+#ifdef mingw32_HOST_OS+import HERMIT.Win32.IO (hPutStr, hPutStrLn)+#endif  import System.Console.ANSI+#ifdef mingw32_HOST_OS+import System.IO hiding (hPutStr, hPutStrLn)+#else import System.IO+#endif import System.IO.Temp import System.Process 
src/HERMIT/Plugin/Types.hs view
@@ -1,11 +1,15 @@-{-# LANGUAGE TypeFamilies, DeriveDataTypeable, FlexibleContexts, +{-# LANGUAGE TypeFamilies, DeriveDataTypeable, FlexibleContexts,              LambdaCase, GADTs, GeneralizedNewtypeDeriving,-             ScopedTypeVariables, FlexibleInstances #-}+             ScopedTypeVariables, FlexibleInstances, CPP #-} module HERMIT.Plugin.Types where  import Control.Applicative import Control.Concurrent.STM+#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else import Control.Monad.Error+#endif import Control.Monad.State  import Data.Dynamic@@ -13,6 +17,7 @@  import HERMIT.Kure import HERMIT.External+import HERMIT.Kernel (KernelEnv(..)) import HERMIT.Kernel.Scoped import HERMIT.Monad import HERMIT.Plugin.Builder@@ -21,11 +26,19 @@ import System.IO  type PluginM = PluginT IO+#if MIN_VERSION_mtl(2,2,1)+newtype PluginT m a = PluginT { unPluginT :: ExceptT PException (StateT PluginState m) a }+#else newtype PluginT m a = PluginT { unPluginT :: ErrorT PException (StateT PluginState m) a }+#endif     deriving (Functor, Applicative, Monad, MonadIO, MonadError PException, MonadState PluginState)  runPluginT :: PluginState -> PluginT m a -> m (Either PException a, PluginState)+#if MIN_VERSION_mtl(2,2,1)+runPluginT ps = flip runStateT ps . runExceptT . unPluginT+#else runPluginT ps = flip runStateT ps . runErrorT . unPluginT+#endif  instance MonadTrans PluginT where     lift = PluginT . lift . lift@@ -53,12 +66,14 @@     , ps_failhard       :: Bool                                     -- ^ if true, abort on *any* failure     -- this should be in a reader     , ps_kernel         :: ScopedKernel-    , ps_phase          :: PhaseInfo+    , ps_pass           :: PassInfo     } deriving (Typeable)  data PException = PAbort | PResume SAST | PError String +#if !(MIN_VERSION_mtl(2,2,1)) instance Error PException where strMsg = PError+#endif  newtype PSBox = PSBox PluginState deriving Typeable instance Extern PluginState where@@ -76,25 +91,25 @@         writeTVar var (M.insert msg c m)         return c -mkKernelEnv :: PluginState -> HermitMEnv+mkKernelEnv :: PluginState -> KernelEnv mkKernelEnv st =     let pp = ps_pretty st         out str = liftIO $ ps_render st stdout (pOptions pp) (Left $ str ++ "\n") -    in  mkHermitMEnv $ \ msg -> case msg of+    in  KernelEnv $ \ msg -> case msg of                 DebugTick    msg'      -> do                         c <- liftIO $ tick (ps_tick st) msg'                         out $ "<" ++ show c ++ "> " ++ msg'                 DebugCore  msg' cxt core -> do                         out $ "[" ++ msg' ++ "]"-                        doc :: DocH <- apply (pCoreTC pp) (liftPrettyC (pOptions pp) cxt) (inject core)+                        doc :: DocH <- applyT (pCoreTC pp) (liftPrettyC (pOptions pp) cxt) (inject core)                         liftIO $ ps_render st stdout (pOptions pp) (Right doc)  iokm' :: (MonadIO m, MonadCatch m) => String -> (a -> m b) -> IO (KureM a) -> m b iokm' msg ret m = liftIO m >>= runKureM ret (fail . (msg ++)) -iokm :: (MonadIO m, MonadCatch m) => String -> IO (KureM a) -> m a +iokm :: (MonadIO m, MonadCatch m) => String -> IO (KureM a) -> m a iokm msg = iokm' msg return -iokm'' :: (MonadIO m, MonadCatch m) => IO (KureM a) -> m a +iokm'' :: (MonadIO m, MonadCatch m) => IO (KureM a) -> m a iokm'' = iokm ""
src/HERMIT/PrettyPrinter/AST.hs view
@@ -115,19 +115,12 @@            <+ transCoT ppCoercion ppCoercion (\ co1 co2 -> coText "TransCo" $$ nest 2 (cat [parens co1, parens co2]))            <+ nthCoT (arr $ coText . show) ppCoercion (\ n co -> coText "NthCo" <+> n $$ parens co)            <+ instCoT ppCoercion ppKindOrType (\ co ty -> coText "InstCo" $$ nest 2 (cat [parens co, parens ty]))-#if __GLASGOW_HASKELL__ > 706 -- TODO: Figure out how to properly pp new branched Axioms and Left/Right Coercions            <+ reflT ppKindOrType (\ r ty -> coText "Refl" <+> coText (showRole r) $$ nest 2 (parens ty))            <+ axiomInstCoT ppSDoc ppSDoc (const ppCoercion) (\ ax idx coes -> coText "AxiomInstCo" <+> ax <+> idx $$ nest 2 (vlist $ map parens coes))            <+ lrCoT ppSDoc ppCoercion (\ lr co -> coText "LRCo" <+> lr $$ nest 2 (parens co))            <+ tyConAppCoT ppSDoc (const ppCoercion) (\ r con coes -> coText "TyConAppCo" <+> coText (showRole r) <+> con $$ nest 2 (vlist $ map parens coes))            -- TODO: add UnivCo and SubCo-#else-           <+ reflT (ppKindOrType >>^ \ ty -> coText "Refl" $$ nest 2 (parens ty))-           <+ tyConAppCoT ppSDoc (const ppCoercion) (\ con coes -> coText "TyConAppCo" <+> con $$ nest 2 (vlist $ map parens coes))-           <+ unsafeCoT ppKindOrType ppKindOrType (\ ty1 ty2 -> coText "UnsafeCo" $$ nest 2 (cat [parens ty1, parens ty2]))-           <+ axiomInstCoT ppSDoc (const ppCoercion) (\ ax coes -> coText "AxiomInstCo" <+> ax $$ nest 2 (vlist $ map parens coes))-#endif  ppVar :: PrettyH Var ppVar = readerT $ \ v -> ppSDoc >>^ modCol v
src/HERMIT/PrettyPrinter/Clean.hs view
@@ -1,19 +1,18 @@ {-# LANGUAGE CPP, LambdaCase, MultiWayIf #-}  module HERMIT.PrettyPrinter.Clean-  ( -- * HERMIT's Clean Pretty-Printer for GHC Core-    pretty-  , ppCoreTC-  , ppModGuts-  , ppCoreProg-  , ppCoreBind-  , ppCoreExpr-  , ppCoreAlt-  , ppKindOrType-  , ppCoercion-  , ppForallQuantification-  )-where+    ( -- * HERMIT's Clean Pretty-Printer for GHC Core+      pretty+    , ppCoreTC+    , ppModGuts+    , ppCoreProg+    , ppCoreBind+    , ppCoreExpr+    , ppCoreAlt+    , ppKindOrType+    , ppCoercion+    , ppForallQuantification+    ) where  import Control.Arrow hiding ((<+>)) import Control.Applicative ((<$>))@@ -24,16 +23,12 @@  import HERMIT.Context import HERMIT.Core-import HERMIT.GHC hiding ((<+>), (<>), ($$), ($+$), sep, hsep, empty, nest, vcat, char, text, keyword, hang)+import HERMIT.Dictionary (dynFlagsT)+import HERMIT.GHC hiding ((<+>), (<>), ($$), ($+$), cat, sep, fsep, hsep, empty, nest, vcat, char, text, keyword, hang) import HERMIT.Kure import HERMIT.Monad-import HERMIT.Syntax--import HERMIT.Dictionary (dynFlagsT)- import HERMIT.PrettyPrinter.Common--import Pair+import HERMIT.Syntax  import Text.PrettyPrint.MarkedHughesPJ as PP @@ -50,11 +45,13 @@         | RetLet AbsolutePathH [DocH] AbsolutePathH DocH         | RetApp DocH [(AbsolutePathH,RetExpr)]         | RetForAll AbsolutePathH [DocH] AbsolutePathH DocH-        | RetArrowType DocH [(AbsolutePathH,DocH)] -- f -> (a -> (b -> c))  The path is for each arrow, starting from the left.+        | RetArrowType ArrowType DocH [(AbsolutePathH,DocH)] -- f -> (a -> (b -> c))  The path is for each arrow, starting from the left.         | RetExpr DocH         | RetAtom DocH         -- parens not needed         | RetEmpty +data ArrowType = ATType | ATCoercion deriving (Eq, Show)+ retApp :: AbsolutePathH -> Crumb -> Crumb -> RetExpr -> RetExpr -> RetExpr retApp _ _   _   f              RetEmpty = f retApp _ _   _   RetEmpty       e        = e@@ -87,16 +84,11 @@                             ty                    -> RetForAll p [v] (p @@ cr) (normalExpr ty)  -- This is very hacky.  There must be a better way of handling arrow types.-retArrowType :: AbsolutePathH -> Crumb -> Crumb -> RetExpr -> RetExpr -> RetExpr-retArrowType p cr1 cr2 ty1 = \case-                                RetArrowType ty2 ptys  -> RetArrowType (normalParensExceptApp (p @@ cr1) ty1) ((p,ty2) : ptys)-                                ty2                    -> RetArrowType (normalParensExceptApp (p @@ cr1) ty1) [(p , normalParensExceptApp (p @@ cr2) ty2)]----------------------------------------------------------------------------------------------------isAtom :: RetExpr -> Bool-isAtom (RetAtom _) = True-isAtom _           = False+retArrowType :: ArrowType -> AbsolutePathH -> Crumb -> Crumb -> RetExpr -> RetExpr -> RetExpr+retArrowType at@ATType p cr1 _cr2 ty1 (RetArrowType _ ty2 ptys)+    = RetArrowType at (normalParensExceptApp (p @@ cr1) ty1) ((p,ty2) : ptys)+retArrowType at        p cr1 cr2  ty1 ty2+    = RetArrowType at (normalParensExceptApp (p @@ cr1) ty1) [(p , normalParensExceptApp (p @@ cr2) ty2)]  ------------------------------------------------------------------------------------------------ @@ -106,11 +98,12 @@ normalExpr (RetExpr e)         = e normalExpr (RetLam p vs pb e)  = hang (specialSymbol p LambdaSymbol <+> hsep vs <+> specialSymbol pb RightArrowSymbol) 2 e normalExpr (RetLet p vs pb e)  = sep [ keyword p "let" <+> vcat vs, keyword pb "in" <+> e ]-normalExpr (RetApp f pes)      = let (pAtoms,pExprs) = span (isAtom.snd) pes-                                  in sep [ hsep (f : map (normalExpr.snd) pAtoms)-                                         , nest 2 (sep $ map (uncurry normalParens) pExprs) ]+normalExpr (RetApp f pes)      = f <+> fsep (map (uncurry normalParens) pes) normalExpr (RetForAll p vs pb ty) = specialSymbol p ForallSymbol <+> hsep vs <+> symbol pb '.' <+> ty-normalExpr (RetArrowType ty ptys) = foldl (\ ty1 (p,ty2) -> ty1 <+> typeArrow p <+> ty2) ty ptys+normalExpr (RetArrowType at ty ptys) = let a = case at of+                                                ATType -> typeArrow+                                                ATCoercion -> coArrow+                                       in foldl (\ ty1 (p,ty2) -> ty1 <+> a p <+> ty2) ty ptys  ------------------------------------------------------------------------------------------------ @@ -175,7 +168,14 @@ coKeyword :: AbsolutePathH -> String -> DocH coKeyword = coText -- An alternative would be keyword. +coArrow :: AbsolutePathH -> DocH+coArrow p = coSymbol p RightArrowSymbol +coTypeSymbol :: AbsolutePathH -> DocH+coTypeSymbol p = coSymbol p TypeOfSymbol++------------------------------------------------------------------------------------------------+ tyChar :: AbsolutePathH -> Char -> DocH tyChar p = attrP p . typeColor . char @@ -222,6 +222,7 @@              then return (cleanParens p (idText p doc))              else return (idText p doc) +-- For var bindings ppVar :: PrettyH Var ppVar = readerT $ \ v -> varName ^>> ppName (varColor v) @@ -241,7 +242,9 @@  ppName :: SyntaxForColor -> PrettyH Name ppName color = do p    <- absPathT-                  name <- arr uqName+                  c    <- contextT+                  name <- arr (\ n -> unqualifiedName n ++ (if po_showUniques (prettyC_options c)+                                                            then '_' : show (getUnique n) else ""))                   let doc = attrP p $ markColor color $ text name                                -- TODO: is "isScriptInfixId" the right predicate to use here?                   if all isScriptInfixIdChar name@@ -312,7 +315,7 @@                     )                     (\ _ -> ppBinderMode)                     ppCoreExpr-                    (\ con vs e -> hang (con <+> hsep vs <+> specialSymbol p RightArrowSymbol) 2 e)+                    (\ con vs e -> hang (con <+> fsep vs <+> specialSymbol p RightArrowSymbol) 2 e)  ppCoreDef :: PrettyH CoreDef ppCoreDef = defT idR (ppCoreExprR &&& ppTypeSig) (,) >>> ppDef Def_RHS@@ -349,14 +352,15 @@               lamT ppBinderMode ppCoreExprR (retLam p)            <+ letT ppCoreBind ppCoreExprR (retLet p)            <+ appT ppCoreExprR ppCoreExprR (retApp p App_Fun App_Arg)-           <+ caseT ppCoreExpr ppVar (ppTypeModeR >>> parenExpr) (const ppCoreAlt) (\ s w ty alts -> RetExpr ((keyword p "case" <+> s <+> keyword p "of" <+> w <+> ty) $$ nest 2 (vcat alts)))+           <+ caseT ppCoreExpr ppVar (ppTypeModeR >>> parenExpr) (const ppCoreAlt)+                (\ s w ty alts -> RetExpr (hang (keyword p "case" <+> s) 1 (keyword p "of" <+> w <+> ty) $+$ nest 2 (vcat alts)))            <+ varT (RetAtom <$> ppVarOcc)            <+ litT (RetAtom <$> ppSDoc)            <+ typeT ppTypeModeR            <+ coercionT ppCoercionModeR            <+ (castT ppCoreExprR (ppCoercionModeR >>> parenExpr) (,) >>> readerT (\ (_,co) -> if isEmpty co                                                                                                  then arr fst-                                                                                                 else toFst parenExprExceptApp >>^ \ e -> RetExpr (e <+> castSymbol p <+> co)+                                                                                                 else toFst parenExprExceptApp >>^ \ e -> RetExpr (hang e 2 (castSymbol p <+> co))                                                                                  ))            <+ tickT ppSDoc (ppCoreExprR >>> parenExpr) (\ tk e -> RetExpr $ attrP p (text "Tick") $$ nest 2 (tk <+> e)) @@ -381,10 +385,10 @@            tyVarT (RetAtom <$> ppVarOcc)         <+ litTyT (RetAtom <$> ppLitTy)         <+ appTyT ppKindOrTypeR ppKindOrTypeR (retApp p AppTy_Fun AppTy_Arg)-        <+ funTyT ppKindOrTypeR ppKindOrTypeR (retArrowType p FunTy_Dom FunTy_CoDom)+        <+ funTyT ppKindOrTypeR ppKindOrTypeR (retArrowType ATType p FunTy_Dom FunTy_CoDom)         <+ forAllTyT ppVar ppKindOrTypeR (retForAll p ForAllTy_Body)         <+ tyConAppT (forkFirst ppTyCon) (\ _ -> ppKindOrTypeR)-             (\ (pCon,tyCon) tys -> if | isFunTyCon tyCon && length tys == 2 -> let [ty1,ty2] = tys in retArrowType p (TyConApp_Arg 0) (TyConApp_Arg 1) ty1 ty2+             (\ (pCon,tyCon) tys -> if | isFunTyCon tyCon && length tys == 2 -> let [ty1,ty2] = tys in retArrowType ATType p (TyConApp_Arg 0) (TyConApp_Arg 1) ty1 ty2                                        | tyCon == listTyCon -> RetAtom $ tyChar p '[' <> (case tys of                                                                                                 []  -> empty                                                                                                 t:_ -> normalExpr t)@@ -419,7 +423,7 @@                        Omit     -> return RetEmpty                        Abstract -> return (RetAtom $ coercionSymbol p)                        Show     -> ppCoercionR-                       Kind     -> ppCoKind >>^ (\ k -> RetExpr (coercionSymbol p <+> typeOfSymbol p <+> k))+                       Kind     -> ppCoKind >>^ (\ k -> RetExpr (coercionSymbol p <+> coTypeSymbol p <+> k))  ppCoercionR :: Transform PrettyC HermitM Coercion RetExpr ppCoercionR = absPathT >>= ppCoercionPR@@ -436,26 +440,25 @@                                                                                                                                          else RetExpr (cop2 <+> coChar p '@' <+> ty)                                                                                                                    )                 <+ appCoT ppCoercionR ppCoercionR (retApp p AppCo_Fun AppCo_Arg)-#if __GLASGOW_HASKELL__ > 706 -- TODO: Figure out how to properly pp new branched Axioms and Left/Right Coercions                 <+ reflT (ppTypeModeR >>^ normalExpr) (\ r ty -> RetAtom $ if isEmpty ty then coText p "refl" else coChar p '<' <> coText p (showRole r ++ ":") <> ty <> coChar p '>')-                <+ tyConAppCoT ppTyConCo (const ppCoercionR) (\ r tc -> retApps p TyConApp_Arg $ coText p (showRole r ++ ":") <> tc)+                <+ tyConAppCoT (forkFirst ppTyConCo) (const ppCoercionR)+                               (\ r (ptc, tc) cs -> if isFunTyCon tc && (length cs == 2)+                                                    then let [c1,c2] = cs+                                                         in retArrowType ATCoercion p (TyConApp_Arg 0) (TyConApp_Arg 1) c1 c2+                                                    else retApps p TyConApp_Arg (coText p (showRole r ++ ":") <> ptc) cs)                 <+ axiomInstCoT (coAxiomName ^>> ppName CoercionColor) ppSDoc (\ _ -> ppCoercionR >>> parenExpr) (\ ax idx coes -> RetExpr (coText p "axiomInst" <+> ax <+> idx <+> sep coes))                 <+ lrCoT ppSDoc (ppCoercionR >>> parenExpr) (\ lr co -> RetExpr (coercionColor lr <+> co))                 -- TODO: UnivCo and SubCo                 <+ constT (return . RetAtom $ text "Unsupported Coercion Constructor")-#else-                <+ reflT (ppTypeModeR >>^ normalExpr >>^ \ ty -> RetAtom $ if isEmpty ty then coText p "refl" else coChar p '<' <> ty <> coChar p '>')-                <+ tyConAppCoT ppTyConCo (const ppCoercionR) (retApps p TyConApp_Arg)-                <+ unsafeCoT (ppTypeModeR >>> parenExpr) (ppTypeModeR >>> parenExpr) (\ ty1 ty2 -> (if isEmpty ty1 && isEmpty ty2 then RetAtom else RetExpr)-                                                                                                   (coKeyword p "unsafe" <+> ty1 <+> ty2)-                                                     )-                <+ axiomInstCoT (coAxiomName ^>> ppName CoercionColor) (\ _ -> ppCoercionR >>> parenExpr) (\ ax coes -> RetExpr (coText p "axiomInst" <+> ax <+> sep coes))-#endif  ppCoKind :: PrettyH Coercion-ppCoKind = do p <- absPathT-              (coercionKind >>> unPair) ^>> ((ppTypeModeR >>> parenExprExceptApp) *** (ppTypeModeR >>> parenExprExceptApp)) >>^ ( \(ty1,ty2) -> ty1 <+> coText p "~#" <+> ty2)+ppCoKind = do+    p <- absPathT+    (r, Pair co1 co2) <- arr (coercionRole &&& coercionKind)+    ty1 <- return co1 >>> ppTypeModeR >>> parenExprExceptApp+    ty2 <- return co2 >>> ppTypeModeR >>> parenExprExceptApp+    return $ cat [ty1, pad (coText p ("~" ++ showRole r)), ty2]  -------------------------------------------------------------------- 
src/HERMIT/PrettyPrinter/Common.hs view
@@ -40,11 +40,10 @@     , updateTypeShowOption     , updateWidthOption       -- * Utilities+    , pad     , hlist     , vlist-#if __GLASGOW_HASKELL__ > 706     , showRole-#endif     ) where  import Data.Char@@ -56,18 +55,16 @@ import HERMIT.Context import HERMIT.Core import HERMIT.External-import HERMIT.GHC hiding (($$), (<>), (<+>))+import HERMIT.GHC hiding (($$), (<>), (<+>), char) import HERMIT.Kure import HERMIT.Monad  import Text.PrettyPrint.MarkedHughesPJ as PP -#if __GLASGOW_HASKELL__ > 706 showRole :: Role -> String-showRole Nominal          = "Nominal"-showRole Representational = "Representational"-showRole Phantom          = "Phantom"-#endif+showRole Nominal          = "N"+showRole Representational = "R"+showRole Phantom          = "P"  -- A HERMIT document type DocH = MDoc HermitMark@@ -201,6 +198,7 @@         , po_exprTypes       :: ShowOption      -- ^ Do you hide types, and type arguments, as <>?         , po_coercions       :: ShowOption      -- ^ Do you hide coercions?         , po_typesForBinders :: ShowOption      -- ^ Do you give the types for all bindings?+        , po_showUniques     :: Bool            -- ^ Append uniques to OccNames? (Like GHC does)         , po_focus           :: Maybe PathH     -- ^ This region should be highlighted (is the current focus)         , po_depth           :: Maybe Int       -- ^ below this depth are ..., Nothing => infinite         , po_notes           :: Bool            -- ^ notes might be added to output@@ -225,8 +223,9 @@   def = PrettyOptions         { po_fullyQualified  = False         , po_exprTypes       = Abstract-        , po_coercions       = Abstract+        , po_coercions       = Kind         , po_typesForBinders = Omit+        , po_showUniques     = False         , po_focus           = Nothing         , po_depth           = Nothing         , po_notes           = False@@ -487,5 +486,9 @@ vlist, hlist :: [MDoc a] -> MDoc a vlist = listify ($$) hlist = listify (<+>)++-- | wrap a document in spaces+pad :: MDoc a -> MDoc a+pad d = char ' ' <> d <> char ' '  -------------------------------------------------------------------------------
src/HERMIT/Shell/Command.hs view
@@ -1,8 +1,9 @@-{-# LANGUAGE LambdaCase, ScopedTypeVariables, GADTs, FlexibleContexts, TypeFamilies #-}+{-# LANGUAGE ConstraintKinds, CPP, FlexibleContexts, GADTs, LambdaCase, ScopedTypeVariables, TypeFamilies #-}  module HERMIT.Shell.Command     ( -- * The HERMIT Command-line Shell       commandLine+    , interpShellCommand     , unicodeConsole     , diffDocH     , diffR@@ -14,14 +15,14 @@     , evalScript     ) where -import Control.Concurrent import Control.Monad.State-import Control.Monad.Error  import Data.Char import Data.List (isPrefixOf, partition) import Data.Maybe+import Data.Monoid +import HERMIT.Context import HERMIT.External import qualified HERMIT.GHC as GHC import HERMIT.Kernel.Scoped hiding (abortS, resumeS)@@ -31,6 +32,9 @@ import HERMIT.Plugin.Display import HERMIT.Plugin.Renderer +import HERMIT.PrettyPrinter.Common++import HERMIT.Shell.Completion import HERMIT.Shell.Externals import HERMIT.Shell.Interpreter import HERMIT.Shell.KernelEffect@@ -39,6 +43,10 @@ import HERMIT.Shell.ShellEffect import HERMIT.Shell.Types +#ifdef mingw32_HOST_OS+import HERMIT.Win32.Console+#endif+ import System.IO  -- import System.Console.ANSI@@ -72,44 +80,58 @@     , "=============================================================="     ] +#ifdef mingw32_HOST_OS+cygwinWarning :: String+cygwinWarning = unlines+    [ "WARNING: HERMIT invoked in a Unix-like shell such as Cygwin."+    , "Cygwin does not handle Ctrl-C or tab completion well in some"+    , "Haskell executables. It is recommended that you use a native"+    , "Windows console (such as cmd.exe or PowerShell) instead."+    ]+#endif+ -- | The first argument includes a list of files to load.-commandLine :: [GHC.CommandLineOption] -> Behavior -> [External] -> CLT IO ()-commandLine opts behavior exts = do+commandLine :: forall m. (MonadCatch m, MonadException m, CLMonad m)+            => [Interp m ()] -> [GHC.CommandLineOption] -> [External] -> m ()+commandLine intp opts exts = do     let (flags, filesToLoad) = partition (isPrefixOf "-") opts         ws_complete = " ()"      modify $ \ st -> st { cl_externals = shell_externals ++ exts } -    clState <- get-    completionMVar <- liftIO $ newMVar clState--    let loop :: CLT (InputT IO) ()+    let loop :: InputT m ()         loop = do-            st <- get+            st <- lift get             let SAST n = cl_cursor st             mLine <- if cl_nav st                      then liftIO getNavCmd-                     else do liftIO $ modifyMVar_ completionMVar (const $ return st) -- so the completion can get the current state-                             lift $ getInputLine $ "hermit<" ++ show n ++ "> "+                     else getInputLine $ "hermit<" ++ show n ++ "> "              case mLine of-                Nothing          -> performShellEffect Resume+                Nothing          -> lift $ performShellEffect Resume                 Just ('-':'-':_) -> loop                 Just line        -> if all isSpace line                                     then loop-                                    else (evalScript line `catchFailHard` cl_putStrLn) >> loop+                                    else lift (evalScript intp line `catchFailHard` cl_putStrLn) >> loop      -- Display the banner     if any (`elem` ["-v0", "-v1"]) flags         then return ()         else cl_putStrLn banner +#ifdef mingw32_HOST_OS+    isCyg <- liftIO isCygwinConsole+    if isCyg+        then cl_putStrLn cygwinWarning+        else return ()+#endif+     -- Load and run any scripts     setRunningScript $ Just []     sequence_ [ case fileName of                  "abort"  -> performShellEffect Abort                  "resume" -> performShellEffect Resume-                 _        -> performScriptEffect runExprH $ loadAndRun fileName+                 _        -> performScriptEffect (runExprH intp) $ loadAndRun fileName               | fileName <- reverse filesToLoad               , not (null fileName)               ] `catchFailHard` \ msg -> cl_putStrLn $ "Booting Failure: " ++ msg@@ -117,26 +139,41 @@      -- Start the CLI     showWindow-    let settings = setComplete (completeWordWithPrev Nothing ws_complete (shellComplete completionMVar)) defaultSettings-    (r,s) <- get >>= liftIO . runInputTBehavior behavior settings . flip runCLT loop-    either throwError (\v -> put s >> return v) r+    let settings = setComplete (completeWordWithPrev Nothing ws_complete shellComplete) defaultSettings+    runInputT settings loop  -- | Like 'catchM', but checks the 'cl_failhard' setting and does so if needed.-catchFailHard :: MonadIO m => CLT m () -> (String -> CLT m ()) -> CLT m ()+catchFailHard :: (MonadCatch m, CLMonad m) => m () -> (String -> m ()) -> m () catchFailHard m failure = catchM m $ \ msg -> ifM (gets cl_failhard) (performQuery Display (CmdName "display") >> cl_putStrLn msg >> abort) (failure msg) -evalScript :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()-evalScript = parseScriptCLT >=> mapM_ runExprH+evalScript :: (MonadCatch m, CLMonad m) => [Interp m ()] -> String -> m ()+evalScript intp = parseScriptCLT >=> mapM_ (runExprH intp) -runExprH :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => ExprH -> m ()-runExprH expr = prefixFailMsg ("Error in expression: " ++ unparseExprH expr ++ "\n") $ do-    shellCmd <- interpExprH interpShellCommand expr-    case shellCmd of-        KernelEffect effect -> performKernelEffect effect expr-        ScriptEffect effect -> performScriptEffect runExprH effect-        ShellEffect effect  -> performShellEffect effect-        QueryFun query      -> performQuery query expr-        ProofCommand cmd    -> performProofCommand cmd+runExprH :: (MonadCatch m, CLMonad m) => [Interp m ()] -> ExprH -> m ()+runExprH intp expr = prefixFailMsg ("Error in expression: " ++ unparseExprH expr ++ "\n") $ interpExprH intp expr++-- | Interpret a boxed thing as one of the four possible shell command types.+interpShellCommand :: (MonadCatch m, MonadException m, CLMonad m) => [Interp m ()]+interpShellCommand =+  [ interpEM $ \ (RewriteCoreBox rr)           -> applyRewrite rr+  , interpEM $ \ (RewriteCoreTCBox rr)         -> applyRewrite rr+  , interpEM $ \ (BiRewriteCoreBox br)         -> applyRewrite $ whicheverR br+  , interpEM $ \ (CrumbBox cr)                 -> setPath (return (mempty @@ cr) :: TransformH CoreTC LocalPathH)+  , interpEM $ \ (PathBox p)                   -> setPath (return p :: TransformH CoreTC LocalPathH)+  , interpEM $ \ (TransformCorePathBox tt)     -> setPath tt+  , interpEM $ \ (TransformCoreTCPathBox tt)   -> setPath tt+  , interpEM $ \ (StringBox str)               -> performQuery (message str)+  , interpEM $ \ (TransformCoreStringBox tt)   -> performQuery (QueryString tt)+  , interpEM $ \ (TransformCoreTCStringBox tt) -> performQuery (QueryString tt)+  , interpEM $ \ (TransformCoreTCDocHBox tt)   -> performQuery (QueryDocH $ unTransformDocH tt)+  , interpEM $ \ (TransformCoreCheckBox tt)    -> performQuery (CorrectnessCritera tt)+  , interpEM $ \ (TransformCoreTCCheckBox tt)  -> performQuery (CorrectnessCritera tt)+  , interpEM $ \ (effect :: KernelEffect)      -> flip performKernelEffect effect+  , interpM  $ \ (effect :: ShellEffect)       -> performShellEffect effect+  , interpM  $ \ (effect :: ScriptEffect)      -> performScriptEffect (runExprH interpShellCommand) effect+  , interpEM $ \ (query :: QueryFun)           -> performQuery query+  , interpM  $ \ (cmd :: ProofCommand)         -> performProofCommand cmd+  ]  ------------------------------------------------------------------------------- 
+ src/HERMIT/Shell/Completion.hs view
@@ -0,0 +1,127 @@+{-# LANGUAGE FlexibleContexts, LambdaCase #-}+module HERMIT.Shell.Completion (shellComplete) where++import Control.Applicative+import Control.Arrow+import Control.Monad.State++import Data.Dynamic+import Data.List (isPrefixOf, nub)+import Data.Map (keys)+import Data.Maybe (fromMaybe)++import HERMIT.Kure+import HERMIT.External+import qualified HERMIT.GHC as GHC+import HERMIT.Kernel.Scoped+import HERMIT.Monad+import HERMIT.Parser++import HERMIT.Dictionary.Inline+import HERMIT.Dictionary.Navigation+import HERMIT.Dictionary.Reasoning+import HERMIT.Dictionary.Rules++import HERMIT.Shell.Interpreter+import HERMIT.Shell.Types++import System.Console.Haskeline hiding (catch, display)++----------------------------------------------------------------------------------++shellComplete :: (MonadCatch m, MonadIO m, MonadState CommandLineState m) => String -> String -> m [Completion]+shellComplete rPrev so_far = do+    let (partial, _) = toUnmatched rPrev+    if null partial+    then completionsFor so_far [CommandC]+    else case parseExprH partial of+            Left _   -> return []+            Right e  -> do+                eds <- attemptM $ exprToDyns e+                case eds of+                    Left msg -> liftIO $ putStrLn ("\n" ++ msg) >> return []+                    Right ds -> do+                        let ts = [ head args | d <- ds+                                             , let args = fst (splitFunTyArgs (dynTypeRep d))+                                             , not (null args) ]+                        completionsFor so_far $ filterUnknowns $ map (completionType.show) ts++completionsFor :: (MonadCatch m, MonadIO m, MonadState CommandLineState m)+               => String -> [CompletionType] -> m [Completion]+completionsFor so_far cts = do+    qs <- mapM completionQuery cts+    (k,(env,sast)) <- gets (cl_kernel &&& cl_kernel_env &&& cl_cursor)+    cls <- forM qs $ \ q -> catchM (queryS k q env sast) (\_ -> return [])+    return $ map simpleCompletion $ nub $ filter (so_far `isPrefixOf`) $ concat cls++data CompletionType = ConsiderC       -- considerable constructs and (deprecated) bindingOfT+                    | BindingOfC      -- bindingOfT+                    | BindingGroupOfC -- bindingGroupOfT+                    | RhsOfC          -- rhsOfT+                    | OccurrenceOfC   -- occurrenceOfT+                    | InlineC         -- complete with names that can be inlined+                    | InScopeC        -- complete with in-scope variable names+                    | LemmaC          -- complete with list of lemmas+                    | CommandC        -- complete using dictionary commands (default)+                    | CoreC           -- complete with opening Core fragment bracket [|+                    | NothingC        -- no completion+                    | RuleC           -- complete with GHC rewrite rule name+                    | StashC          -- complete with remembered labels+                    | StringC         -- complete with open quotes+                    | UnknownC String -- unknown Extern instance (empty completion)++completionType :: String -> CompletionType+completionType s = fromMaybe (UnknownC s) (lookup s m)+    where m = [ ("BindingName"   , BindingOfC)+              , ("Considerable"  , ConsiderC)+              , ("CoreBox"       , CoreC)+              , ("HermitName"    , NothingC)+              , ("IntBox"        , NothingC)+              , ("LemmaName"     , LemmaC)+              , ("OccurrenceName", OccurrenceOfC)+              , ("RememberedName", StashC)+              , ("RewriteCoreBox", CommandC) -- be more specific than CommandC?+              , ("RhsOfName"     , RhsOfC)+              , ("RuleName"      , RuleC)+              , ("StringBox"     , StringC)+              ]++filterUnknowns :: [CompletionType] -> [CompletionType]+filterUnknowns l = if null l' then l else l'+    where l' = filter (\case UnknownC _ -> False ; _ -> True) l++completionQuery :: (MonadIO m, MonadState CommandLineState m) => CompletionType -> m (TransformH CoreTC [String])+completionQuery ConsiderC       = return $ pure $ map fst considerables+completionQuery OccurrenceOfC   = return $ occurrenceOfTargetsT    >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery BindingOfC      = return $ bindingOfTargetsT       >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery BindingGroupOfC = return $ bindingGroupOfTargetsT  >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery RhsOfC          = return $ rhsOfTargetsT           >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery InlineC         = return $ promoteT inlineTargetsT >>^                         map ('\'':)+completionQuery InScopeC        = return $ pure ["'"] -- TODO+completionQuery LemmaC          = return $ liftM (map show . keys) $ getLemmasT+completionQuery NothingC        = return $ pure []+completionQuery RuleC           = return $ liftM (map (show . fst)) $ getHermitRulesT+completionQuery StashC          = return $ liftM (map show . keys) $ constT getStash+completionQuery StringC         = return $ pure ["\""]+completionQuery CommandC        = gets cl_externals >>= return . pure . map externName+completionQuery CoreC           = return $ pure ["[|"]+-- Need to modify opts in completionType function to add this type.+completionQuery (UnknownC s)    = do+    liftIO $ putStrLn $ "\nCannot tab complete: unknown argument type: " ++ s+    return (pure [])++-- | Take a reversed string, find substring back to first unmatched open paren (or the end).+-- Returns that substring (unreversed), and remaining (reversed) string.+--+-- ex 1. toUnmatched "zab rab( oof"        ==> ("bar baz"       , "( oof")+-- ex 2. toUnmatched ")xuuq zab( rab( oof" ==> ("bar (baz quux)", "( oof")+toUnmatched :: String -> (String, String)+toUnmatched = go 0 ""+    where go :: Int -> String -> String -> (String, String)+          go n acc s@('(':cs)+            | n > 0         = go (n-1) ('(':acc) cs+            | otherwise     = (acc, s)+          go n acc (')':cs) = go (n+1) (')':acc) cs+          go n acc (c:cs)   = go n     (c:acc)   cs+          go _ acc []       = (acc, [])+
src/HERMIT/Shell/Dictionary.hs view
@@ -1,11 +1,13 @@ {-# LANGUAGE ScopedTypeVariables #-} module HERMIT.Shell.Dictionary-    ( mkDict+    ( mkDictionary+    , addToDictionary     , pp_dictionary     ) where +import Data.Dynamic import Data.List-import Data.Map (Map, fromList, toList)+import Data.Map (Map, fromList, toList, fromListWith)  import HERMIT.External @@ -16,9 +18,24 @@  -------------------------------------------------------------------------- +-- | A 'Dictionary' is a collection of 'Dynamic's.+--   Looking up a 'Dynamic' (via an 'ExternalName' key) returns a list, as there+--   can be multiple 'Dynamic's with the same name.+type Dictionary = Map ExternalName [Dynamic]++-- | Build a 'Data.Map' from names to 'Dynamic' values.+toDictionary :: [External] -> Dictionary+toDictionary = fromListWith (++) . map toEntry++toEntry :: External -> (ExternalName, [Dynamic])+toEntry e = (externName e, [externDyn e])++addToDictionary :: External -> Dictionary -> Dictionary+addToDictionary ex d = fromListWith (++) $ toEntry ex : toList d+ -- | Create a dictionary from a list of 'External's.-mkDict :: [External] -> Dictionary-mkDict externs = toDictionary externs'+mkDictionary :: [External] -> Dictionary+mkDictionary externs = toDictionary externs'   where         msg = layoutTxt 60 (map (show . fst) dictionaryOfTags)         externs' = externs ++
src/HERMIT/Shell/Externals.hs view
@@ -4,7 +4,6 @@  import Control.Applicative -import Data.Monoid import Data.List (intercalate) import qualified Data.Map as M import Control.Monad (liftM)@@ -19,7 +18,6 @@ import HERMIT.PrettyPrinter.Common  import HERMIT.Shell.Dictionary-import HERMIT.Shell.Interpreter import HERMIT.Shell.KernelEffect import HERMIT.Shell.Proof as Proof import HERMIT.Shell.ScriptToRewrite@@ -28,36 +26,6 @@  ---------------------------------------------------------------------------------- --- | There are five types of commands.-data ShellCommand = KernelEffect KernelEffect -- ^ Command that modifies the state of the (scoped) kernel.-                  | ScriptEffect ScriptEffect -- ^ Command that deals with script files.-                  | ShellEffect  ShellEffect  -- ^ Command that modifies the state of the shell.-                  | QueryFun     QueryFun     -- ^ Command that queries the AST with a Transform (read only).-                  | ProofCommand ProofCommand -- ^ Command that deals with proofs.---- | Interpret a boxed thing as one of the four possible shell command types.-interpShellCommand :: [Interp ShellCommand]-interpShellCommand =-  [ interp $ \ (RewriteCoreBox rr)           -> KernelEffect (Apply rr)-  , interp $ \ (RewriteCoreTCBox rr)         -> KernelEffect (Apply rr)-  , interp $ \ (BiRewriteCoreBox br)         -> KernelEffect (Apply $ whicheverR br)-  , interp $ \ (CrumbBox cr)                 -> KernelEffect (Pathfinder (return (mempty @@ cr) :: TransformH CoreTC LocalPathH))-  , interp $ \ (PathBox p)                   -> KernelEffect (Pathfinder (return p :: TransformH CoreTC LocalPathH))-  , interp $ \ (TransformCorePathBox tt)     -> KernelEffect (Pathfinder tt)-  , interp $ \ (TransformCoreTCPathBox tt)   -> KernelEffect (Pathfinder tt)-  , interp $ \ (StringBox str)               -> QueryFun (message str)-  , interp $ \ (TransformCoreStringBox tt)   -> QueryFun (QueryString tt)-  , interp $ \ (TransformCoreTCStringBox tt) -> QueryFun (QueryString tt)-  , interp $ \ (TransformCoreTCDocHBox tt)   -> QueryFun (QueryDocH $ unTransformDocH tt)-  , interp $ \ (TransformCoreCheckBox tt)    -> QueryFun (CorrectnessCritera tt)-  , interp $ \ (TransformCoreTCCheckBox tt)  -> QueryFun (CorrectnessCritera tt)-  , interp $ \ (effect :: KernelEffect)      -> KernelEffect effect-  , interp $ \ (effect :: ShellEffect)       -> ShellEffect effect-  , interp $ \ (effect :: ScriptEffect)      -> ScriptEffect effect-  , interp $ \ (query :: QueryFun)           -> QueryFun query-  , interp $ \ (cmd :: ProofCommand)         -> ProofCommand cmd-  ]- shell_externals :: [External] shell_externals = map (.+ Shell)    [@@ -148,6 +116,11 @@             [(opt,"")] -> return $ setPrettyOpts st (updateCoShowOption opt (cl_pretty_opts st))             _          -> return st)        ["set how to show coercions (Show|Abstact|Omit)"]+   , external "set-pp-uniques" (\ str -> CLSModify $ \ st ->+        case reads str of+            [(b,"")] -> return $ setPrettyOpts st ((cl_pretty_opts st) { po_showUniques = b } )+            _        -> return st)+       ["set whether uniques are printed with variable names"]    , external "{"   BeginScope        ["push current lens onto a stack"]       -- tag as internal    , external "}"   EndScope
src/HERMIT/Shell/Interpreter.hs view
@@ -1,14 +1,21 @@-{-# LANGUAGE KindSignatures, GADTs, InstanceSigs, FlexibleContexts, ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds, KindSignatures, GADTs, InstanceSigs,+             FlexibleContexts, ScopedTypeVariables, CPP #-}  module HERMIT.Shell.Interpreter-        ( -- * The HERMIT Interpreter-          Interp-        , interp-        , interpExprH---        , runExprH-        ) where+    ( -- * The HERMIT Interpreter+      Interp+    , interp+    , interpM+    , interpEM+    , interpExprH+    , exprToDyns+    ) where +#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else import Control.Monad.Error+#endif import Control.Monad.State  import Data.Char@@ -16,48 +23,50 @@ import qualified Data.Map as M  import HERMIT.External+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Name import HERMIT.Parser-import HERMIT.Kure  +import HERMIT.Dictionary.Navigation+import HERMIT.Dictionary.Rules+ import HERMIT.Shell.Dictionary import HERMIT.Shell.Types  -- | An 'Interp' @cmd@ is a /possible/ means of converting a 'Typeable' value to a value of type @cmd@.-data Interp :: * -> * where-   Interp :: Typeable a => (a -> cmd) -> Interp cmd+data Interp :: (* -> *) -> * -> * where+   Interp :: Typeable b => (b -> ExprH -> m a) -> Interp m a --- | The primitive way of building an 'Interp'.-interp :: Typeable a => (a -> cmd) -> Interp cmd-interp = Interp+-- | An 'Interp' with no effects.+interp :: (Monad m, Typeable b) => (b -> a) -> Interp m a+interp f = Interp (const . return . f) -instance Functor Interp where-  fmap :: (a -> b) -> Interp a -> Interp b-  fmap f (Interp g) = Interp (f . g)+-- | An 'Interp' which can affect the shell.+interpM :: (CLMonad m, Typeable b) => (b -> m a) -> Interp m a+interpM f = Interp (const . f) -{--runExprH :: forall m r. (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => ExprH -> m r-runExprH e = do-    dyns <- interpExpr e-    CmdInterps interps <- gets cl_interps-    case [ performCommand $ f a | Interp f <- interps, Just a <- map fromDynamic dyns] of-        []  -> fail $ "Does not type-check: " ++ unparseExprH e ++ "\n"-        b:_ -> b :: m r--}+-- | Like 'InterpM', but with access to the original expression.+interpEM :: (CLMonad m, Typeable b) => (b -> ExprH -> m a) -> Interp m a+interpEM = Interp --- | Interpret an 'ExprH' by looking up the appropriate 'Dynamic'(s) in the provided 'Dictionary', --- then interpreting the 'Dynamic'(s) with the provided 'Interp's, returning the first --- interpretation to succeed (or an error string if none succeed).-interpExprH :: MonadState CommandLineState m => [Interp b] -> ExprH -> m b-interpExprH interps e = interpExpr e >>= runInterp e interps+instance Monad m => Functor (Interp m) where+  fmap :: (a -> b) -> Interp m a -> Interp m b+  fmap f (Interp g) = Interp (\ e -> liftM f . g e) -runInterp :: Monad m => ExprH -> [Interp b] -> [Dynamic] -> m b-runInterp e interps dyns = case [f a | Interp f <- interps, Just a <- map fromDynamic dyns] of-                            []  -> fail $ "Does not type-check: " ++ unparseExprH e ++ "\n"-                            b:_ -> return b+-- | Execute an 'ExprH' using a given interpreter. The given interpretations+-- are tried in order. The first one to match (have the proper type) will be executed.+interpExprH :: CLMonad m => [Interp m b] -> ExprH -> m b+interpExprH interps e = exprToDyns e >>= runInterp e interps -interpExpr :: MonadState CommandLineState m => ExprH -> m [Dynamic]-interpExpr = interpExpr' False+runInterp :: forall m b. CLMonad m => ExprH -> [Interp m b] -> [Dynamic] -> m b+runInterp e interps dyns = case [f a e :: m b | Interp f <- interps, Just a <- map fromDynamic dyns] of+                            []     -> fail $ "Does not type-check: " ++ unparseExprH e ++ "\n"+                            comp:_ -> comp +exprToDyns :: MonadState CommandLineState m => ExprH -> m [Dynamic]+exprToDyns = exprToDyns' False+ -- input: list length n, each elem is a variable length list of possible interpretations -- output: variable length list, each elem is list of length n fromDynList :: [[Dynamic]] -> [[Dynamic]]@@ -67,39 +76,48 @@ toBoxedList :: (Extern a, Typeable b) => [[Dynamic]] -> ([a] -> b) -> [Dynamic] toBoxedList dyns boxCon = [ toDyn $ boxCon (map unbox l) | dl <- dyns, Just l <- [mapM fromDynamic dl] ] -interpExpr' :: MonadState CommandLineState m => Bool -> ExprH -> m [Dynamic]-interpExpr' _   (SrcName str) = return [ toDyn $ StringBox str ]-interpExpr' _   (CoreH str)   = return [ toDyn $ CoreBox (CoreString str) ]-interpExpr' _   (ListH exprs) = do -    dyns <- liftM fromDynList $ mapM (interpExpr' True) exprs+exprToDyns' :: MonadState CommandLineState m => Bool -> ExprH -> m [Dynamic]+exprToDyns' _   (SrcName str) = do+    let hn = parseName str -- TODO: remove StringBox option below+                           -- TODO: change to SrcName :: HermitName -> ExprH+    return [ toDyn hn, toDyn (BindingName hn), toDyn (OccurrenceName hn), toDyn (RhsOfName hn), toDyn (StringBox str) ]+exprToDyns' _   (CoreH str)   = return [ toDyn $ CoreString str ]+exprToDyns' _   (ListH exprs) = do+    dyns <- liftM fromDynList $ mapM (exprToDyns' True) exprs     return $    toBoxedList dyns StringListBox              ++ toBoxedList dyns (PathBox . pathToSnocPath)                 -- ugly hack.  The whole dynamic stuff could do with overhauling.-             ++ toBoxedList dyns (TransformCorePathBox . return . pathToSnocPath) +             ++ toBoxedList dyns (TransformCorePathBox . return . pathToSnocPath)              ++ toBoxedList dyns IntListBox+             ++ toBoxedList dyns OccurrenceNameListBox              ++ toBoxedList dyns RewriteCoreListBox+             ++ toBoxedList dyns RuleNameListBox -interpExpr' rhs (CmdName str) +exprToDyns' rhs (CmdName str)     | all isDigit str = do         let i = read str         return [ -- An Int is either a Path, or will be interpreted specially later.                  toDyn $ IntBox i                  -- TODO: Find a better long-term solution.-               , toDyn $ TransformCorePathBox (deprecatedIntToPathT i) +               , toDyn $ TransformCorePathBox (deprecatedIntToPathT i)                ]     | otherwise = do-        dict <- gets (mkDict . cl_externals)+        dict <- gets (mkDictionary . cl_externals)         case M.lookup str dict of             Just dyns           -> do                 dyns' <- mapM provideState dyns                 return $ if rhs then toDyn (StringBox str) : dyns' else dyns'             -- not a command, try as a string arg... worst case: dynApply fails with "bad type of expression"             -- best case: 'help ls' works instead of 'help "ls"'. this is likewise done in the clause above-            Nothing | rhs       -> return [toDyn $ StringBox str]+            Nothing | rhs       -> let f = maybe id ((:) . toDyn) $ string2considerable str+                                   in return $ f [ toDyn $ StringBox str+                                                 , toDyn $ LemmaName str+                                                 , toDyn $ RememberedName str+                                                 , toDyn $ RuleName str]                     | otherwise -> fail $ "User error, unrecognised HERMIT command: " ++ show str-interpExpr' _ (AppH e1 e2) = liftM2 dynCrossApply (interpExpr' False e1) (interpExpr' True e2)+exprToDyns' _ (AppH e1 e2) = liftM2 dynCrossApply (exprToDyns' False e1) (exprToDyns' True e2) --- We essentially treat externals of the type 'CommandLineState -> b' specially,+-- We treat externals of the type 'CommandLineState -> b' specially, -- providing them the shell state here, so they don't need a monadic return type -- in order to access it themselves. provideState :: MonadState CommandLineState m => Dynamic -> m Dynamic
src/HERMIT/Shell/KernelEffect.hs view
@@ -1,12 +1,17 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, GADTs, TypeFamilies #-}+{-# LANGUAGE ConstraintKinds, DeriveDataTypeable, FlexibleContexts, LambdaCase, TypeFamilies #-} -module HERMIT.Shell.KernelEffect +module HERMIT.Shell.KernelEffect     ( KernelEffect(..)     , performKernelEffect+    , applyRewrite+    , setPath+    , goDirection+    , beginScope+    , endScope+    , deleteSAST     ) where  import Control.Monad.State-import Control.Monad.Error  import Data.Monoid import Data.Typeable@@ -28,21 +33,11 @@  ------------------------------------------------------------------------------- --- GADTs can't have docs on constructors. See Haddock ticket #43. -- | KernelEffects are things that affect the state of the Kernel---   - Apply a rewrite (giving a whole new lower-level AST).---   - Change the current location using a computed path.---   - Change the currect location using directions.---   - Begin or end a scope.---   - Delete an AST---   - Run a precondition or other predicate that must not fail.-data KernelEffect :: * where-   Apply      :: (Injection GHC.ModGuts g, Walker HermitC g) => RewriteH g              -> KernelEffect-   Pathfinder :: (Injection GHC.ModGuts g, Walker HermitC g) => TransformH g LocalPathH -> KernelEffect-   Direction  ::                                                Direction               -> KernelEffect-   BeginScope ::                                                                           KernelEffect-   EndScope   ::                                                                           KernelEffect-   Delete     ::                                                SAST                    -> KernelEffect+data KernelEffect = Direction  Direction -- Change the currect location using directions.+                  | BeginScope           -- Begin scope.+                  | EndScope             -- End scope.+                  | Delete     SAST      -- Delete an AST    deriving Typeable  instance Extern KernelEffect where@@ -50,12 +45,18 @@    box i = i    unbox i = i --------------------------------------------------------------------------------+performKernelEffect :: (MonadCatch m, CLMonad m) => ExprH -> KernelEffect -> m ()+performKernelEffect e = \case+                            Direction dir -> goDirection dir e+                            BeginScope    -> beginScope e+                            EndScope      -> endScope e+                            Delete sast   -> deleteSAST sast -performKernelEffect :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) -                    => KernelEffect -> ExprH -> m ()+------------------------------------------------------------------------------- -performKernelEffect (Apply rr) expr = do+applyRewrite :: (Injection GHC.ModGuts g, Walker HermitC g, MonadCatch m, CLMonad m)+             => RewriteH g -> ExprH -> m ()+applyRewrite rr expr = do     st <- get      let sk = cl_kernel st@@ -79,7 +80,9 @@                              (\ errs  -> liftIO (deleteS sk sast') >> fail errs)         else commit -performKernelEffect (Pathfinder t) expr = do+setPath :: (Injection GHC.ModGuts g, Walker HermitC g, MonadCatch m, CLMonad m)+        => TransformH g LocalPathH -> ExprH -> m ()+setPath t expr = do     st <- get     -- An extension to the Path     p <- prefixFailMsg "Cannot find path: " $ queryS (cl_kernel st) t (cl_kernel_env st) (cl_cursor st)@@ -87,24 +90,28 @@     put $ newSAST expr ast st     showWindow -performKernelEffect (Direction dir) expr = do+goDirection :: (MonadCatch m, CLMonad m) => Direction -> ExprH -> m ()+goDirection dir expr = do     st <- get     ast <- prefixFailMsg "Invalid move: " $ modPathS (cl_kernel st) (moveLocally dir) (cl_kernel_env st) (cl_cursor st)     put $ newSAST expr ast st     showWindow -performKernelEffect BeginScope expr = do+beginScope :: (MonadCatch m, CLMonad m) => ExprH -> m ()+beginScope expr = do     st <- get     ast <- beginScopeS (cl_kernel st) (cl_cursor st)     put $ newSAST expr ast st     showWindow -performKernelEffect EndScope expr = do+endScope :: (MonadCatch m, CLMonad m) => ExprH -> m ()+endScope expr = do     st <- get     ast <- endScopeS (cl_kernel st) (cl_cursor st)     put $ newSAST expr ast st     showWindow -performKernelEffect (Delete sast) _ = gets cl_kernel >>= flip deleteS sast+deleteSAST :: (MonadCatch m, CLMonad m) => SAST -> m ()+deleteSAST sast = gets cl_kernel >>= flip deleteS sast  -------------------------------------------------------------------------------
src/HERMIT/Shell/Proof.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,-             ScopedTypeVariables, TypeFamilies, TypeSynonymInstances #-}+{-# LANGUAGE ConstraintKinds, DeriveDataTypeable, FlexibleContexts, FlexibleInstances, LambdaCase,+             MultiParamTypeClasses, ScopedTypeVariables, TypeFamilies, TypeSynonymInstances, CPP #-}  module HERMIT.Shell.Proof     ( externals@@ -12,29 +12,36 @@  import Control.Arrow hiding (loop, (<+>)) import Control.Concurrent+#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else import Control.Monad.Error+#endif import Control.Monad.State  import Data.Char (isSpace) import Data.Dynamic import Data.List (delete, isInfixOf)+import Data.Map (filterWithKey, toList)+import Data.String (fromString)  import HERMIT.Core import HERMIT.External import HERMIT.GHC hiding (settings, (<>), text, sep, (<+>), ($+$), nest) import HERMIT.Kernel.Scoped import HERMIT.Kure+import HERMIT.Monad import HERMIT.Parser import HERMIT.Utilities  import HERMIT.Dictionary.GHC hiding (externals) import HERMIT.Dictionary.Induction import HERMIT.Dictionary.Reasoning hiding (externals)-import HERMIT.Dictionary.Rules hiding (externals)  import HERMIT.Plugin.Types import HERMIT.PrettyPrinter.Common +import HERMIT.Shell.Completion import HERMIT.Shell.Interpreter import HERMIT.Shell.KernelEffect import HERMIT.Shell.ScriptToRewrite@@ -49,59 +56,18 @@ --------------------------------------------------------------------------------------------------------  -- | Externals that get us into the prover shell, or otherwise deal with lemmas.+-- TODO: InteractiveProof is the only one that should be here, rest in Reasoning externals :: [External] externals = map (.+ Proof)-    [ external "rule-to-lemma" RuleToLemma-        [ "Create a lemma from a GHC RULE." ]-    , external "show-lemma" (ShowLemmas . Just)+    [ external "show-lemma" (ShowLemmas . Just)         [ "List lemmas whose names match search string." ]     , external "show-lemmas" (ShowLemmas Nothing)         [ "List lemmas." ]-    , external "lemma" ((\s -> promoteExprBiR . lemma False s) :: CommandLineState -> LemmaName -> BiRewriteH Core)-        [ "Generate a bi-directional rewrite from a proven lemma." ]-    , external "lemma-unsafe" ((\s -> promoteExprBiR . lemma True s) :: CommandLineState -> LemmaName -> BiRewriteH Core)-        [ "Generate a bi-directional rewrite from a lemma, even if it is unproven." ]-    , external "lemma-lhs-intro" (lemmaLhsIntroR :: CommandLineState -> LemmaName -> RewriteH Core)-        [ "Introduce the LHS of a lemma as a non-recursive binding, in either an expression or a program."-        , "body ==> let v = lhs in body" ] .+ Introduce .+ Shallow-    , external "lemma-rhs-intro" (lemmaRhsIntroR :: CommandLineState -> LemmaName -> RewriteH Core)-        [ "Introduce the RHS of a lemma as a non-recursive binding, in either an expression or a program."-        , "body ==> let v = rhs in body" ] .+ Introduce .+ Shallow     , external "prove-lemma" InteractiveProof         [ "Proof a lemma interactively." ]-    , external "inst-lemma" (\ nm v cs -> ModifyLemma nm id (instantiateEqualityVarR (cmpString2Var v) cs) id)-        [ "Instantiate one of the universally quantified variables of the given lemma,"-        , "with the given Core expression, creating a new lemma. Instantiating an"-        , "already proven lemma will result in the new lemma being considered proven." ]-    , external "inst-lemma-dictionaries" (\ nm -> ModifyLemma nm id instantiateDictsR id)-        [ "Instantiate all of the universally quantified dictionaries of the given lemma."-        , "Only works on dictionaries whose types are monomorphic (no free type variables)." ]-    , external "copy-lemma" (\ nm newName -> ModifyLemma nm (const newName) idR id)-        [ "Copy a given lemma, with a new name." ]-    , external "modify-lemma" (\ nm rr -> ModifyLemma nm id rr (const False))-        [ "Modify a given lemma. Resets the proven status to Not Proven." ]-    , external "query-lemma" QueryLemma-        [ "Apply a transformation to a lemma, returning the result." ]     , external "dump-lemma" DumpLemma         [ "Dump named lemma to a file."         , "dump-lemma <lemma-name> <filename> <renderer> <width>" ]-    , external "extensionality" (extensionalityR . Just :: String -> RewriteH CoreExprEquality)-        [ "Given a name 'x, then"-        , "f == g  ==>  forall x.  f x == g x" ]-    , external "extensionality" (extensionalityR Nothing :: RewriteH CoreExprEquality)-        [ "f == g  ==>  forall x.  f x == g x" ]-    , external "lhs" (lhsR . extractR :: RewriteH Core -> RewriteH CoreExprEquality)-        [ "Apply a rewrite to the LHS of an equality." ]-    , external "lhs" (lhsT . extractT :: TransformH CoreTC String -> TransformH CoreExprEquality String)-        [ "Apply a transformation to the LHS of an equality." ]-    , external "rhs" (rhsR . extractR :: RewriteH Core -> RewriteH CoreExprEquality)-        [ "Apply a rewrite to the RHS of an equality." ]-    , external "rhs" (rhsT . extractT :: TransformH CoreTC String -> TransformH CoreExprEquality String)-        [ "Apply a transformation to the RHS of an equality." ]-    , external "both" (bothR . extractR :: RewriteH Core -> RewriteH CoreExprEquality)-        [ "Apply a rewrite to both sides of an equality, succeeding if either succeed." ]-    , external "both" ((\t -> liftM (\(r,s) -> unlines [r,s]) (bothT (extractT t))) :: TransformH CoreTC String -> TransformH CoreExprEquality String)-        [ "Apply a transformation to the RHS of an equality." ]     ]  -- | Externals that are added to the dictionary only when in interactive proof mode.@@ -109,7 +75,7 @@ proof_externals = map (.+ Proof)     [ external "induction" (PCInduction . cmpString2Var :: String -> ProofShellCommand)         [ "Perform induction on given universally quantified variable."-        , "Each constructor case will generate a new CoreExprEquality to be proven."+        , "Each constructor case will generate a new equality to be proven."         ]     , external "dump" PCDump         [ "dump <filename> <renderer> <width>" ]@@ -122,10 +88,7 @@ --------------------------------------------------------------------------------------------------------  data ProofCommand-    = RuleToLemma RuleNameString-    | InteractiveProof LemmaName-    | ModifyLemma LemmaName (String -> String) (RewriteH CoreExprEquality) (Bool -> Bool)-    | QueryLemma LemmaName (TransformH CoreExprEquality String)+    = InteractiveProof LemmaName     | ShowLemmas (Maybe LemmaName)     | DumpLemma LemmaName String String Int     deriving (Typeable)@@ -137,135 +100,86 @@  -------------------------------------------------------------------------------------------------------- -getLemmaByName :: Monad m => CommandLineState -> LemmaName -> m Lemma-getLemmaByName st nm =-    case [ lm | lm@(n,_,_) <- cl_lemmas st, n == nm ] of-        []    -> fail ("No lemma named: " ++ nm)-        (l:_) -> return l--deleteLemmaByName :: MonadState CommandLineState m => LemmaName -> m ()-deleteLemmaByName nm = modify $ \ st -> st { cl_lemmas = [ l | l@(n,_,_) <- cl_lemmas st, nm /= n ] }--lemma :: Bool -> CommandLineState -> LemmaName -> BiRewriteH CoreExpr-lemma ok st nm = beforeBiR-                   (do (_,equality,proven) <- getLemmaByName st nm-                       guardMsg (proven || ok) ("Lemma " ++ nm ++ " has not been proven.")-                       return equality-                   )-                   birewrite------------------------------------------------------------------------------------------------------------lemmaNameToEqualityT :: Monad m => CommandLineState -> LemmaName -> m CoreExprEquality-lemmaNameToEqualityT st nm =-  do (_,eq,_) <- getLemmaByName st nm-     return eq---- | @e@ ==> @let v = lhs in e@  (also works in a similar manner at Program nodes)-lemmaLhsIntroR :: CommandLineState -> LemmaName -> RewriteH Core-lemmaLhsIntroR st = lemmaNameToEqualityT st >=> eqLhsIntroR---- | @e@ ==> @let v = rhs in e@  (also works in a similar manner at Program nodes)-lemmaRhsIntroR :: CommandLineState -> LemmaName -> RewriteH Core-lemmaRhsIntroR st = lemmaNameToEqualityT st >=> eqRhsIntroR----------------------------------------------------------------------------------------------------------+performProofCommand :: (MonadCatch m, MonadException m, CLMonad m) => ProofCommand -> m () -performProofCommand :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => ProofCommand -> m ()-performProofCommand (RuleToLemma nm) = do+performProofCommand (InteractiveProof nm) = do     st <- gets cl_pstate-    equality <- queryS (ps_kernel st) (ruleNameToEqualityT nm :: TransformH Core CoreExprEquality) (mkKernelEnv st) (ps_cursor st)-    _ <- addLemmas [(nm,equality,False)]-    return ()--performProofCommand (InteractiveProof nm) = get >>= flip getLemmaByName nm >>= interactiveProof True--performProofCommand (ModifyLemma nm nFn rr pFn) = do-    st <- get-    (_,eq,p) <- getLemmaByName st nm--    -- query so lemma is transformed in current context-    eq' <- queryS (cl_kernel st) (return eq >>> rr >>> (bothT lintExprT >> idR) :: TransformH Core CoreExprEquality) (cl_kernel_env st) (cl_cursor st)-    deleteLemmaByName (nFn nm)-    _ <- addLemmas [(nFn nm, eq', pFn p)]-    return ()--performProofCommand (QueryLemma nm t) = do-    st <- get-    (_,eq,_) <- getLemmaByName st nm--    -- query so lemma is transformed in current context-    res <- queryS (cl_kernel st) (return eq >>> t :: TransformH Core String) (cl_kernel_env st) (cl_cursor st)-    cl_putStrLn res+    l <- queryS (ps_kernel st) (getLemmaByNameT nm :: TransformH Core Lemma) (mkKernelEnv st) (ps_cursor st)+    interactiveProof True False (nm,l) -performProofCommand (DumpLemma nm fn r w) = dump (\ st -> getLemmaByName st nm >>> ppLemmaT (cl_pretty st)) fn r w+performProofCommand (DumpLemma nm fn r w) = dump (\ st -> getLemmaByNameT nm >>> ppLemmaT (cl_pretty st) nm) fn r w  performProofCommand (ShowLemmas mnm) = do-    ls <- gets $ filter (maybe (const True) (\ nm (n,_,_) -> nm `isInfixOf` n) mnm) . cl_lemmas-    forM_ ls printLemma+    st <- gets cl_pstate+    ls <- queryS (ps_kernel st) (getLemmasT :: TransformH Core Lemmas) (mkKernelEnv st) (ps_cursor st)+    mapM_ printLemma $ toList $ filterWithKey (maybe (\ _ _ -> True) (\ nm n _ -> show nm `isInfixOf` show n) mnm) ls  -------------------------------------------------------------------------------------------------------- -printLemma :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => Lemma -> m ()-printLemma lem = do++printLemma :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m)+           => (LemmaName,Lemma) -> m ()+printLemma (nm,lem) = do     st <- get-    doc <- queryS (cl_kernel st) (return lem >>> ppLemmaT (cl_pretty st) :: TransformH Core DocH) (cl_kernel_env st) (cl_cursor st)+    doc <- queryS (cl_kernel st) (return lem >>> ppLemmaT (cl_pretty st) nm :: TransformH Core DocH) (cl_kernel_env st) (cl_cursor st)     liftIO $ cl_render st stdout (cl_pretty_opts st) (Right doc) -ppLemmaT :: PrettyPrinter -> TransformH Lemma DocH-ppLemmaT pp = do-    (nm, eq, p) <- idR-    eqDoc <- return eq >>> ppCoreExprEqualityT pp-    let hDoc = text nm <+> text (if p then "(Proven)" else "(Not Proven)")+ppLemmaT :: PrettyPrinter -> LemmaName -> TransformH Lemma DocH+ppLemmaT pp nm = do+    Lemma eq p u <- idR+    eqDoc <- return eq >>> ppEqualityT pp+    let hDoc = text (show nm) <+> text (if p then "(Proven)" else "(Not Proven)")+                              <+> text (if u then "(Used)"   else "(Not Used)")     return $ hDoc $+$ nest 2 eqDoc  -------------------------------------------------------------------------------------------------------- -completeProof :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => LemmaName -> m ()-completeProof nm = do-    cl_putStrLn $ "Successfully proven: " ++ nm-    modify $ \ st -> st { cl_lemmas = [ (n,e, if n == nm then True else p) | (n,e,p) <- cl_lemmas st ] }-    get >>= continue+type NamedLemma = (LemmaName, Lemma) -interactiveProof :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => Bool -> Lemma -> m ()-interactiveProof topLevel lem = do-    origEs <- addProofExternals topLevel+interactiveProof :: forall m. (MonadCatch m, MonadException m, CLMonad m) => Bool -> Bool -> NamedLemma -> m ()+interactiveProof topLevel isTemporary lem@(nm,_) = do     origSt <- get-    completionMVar <- liftIO $ newMVar origSt+    origEs <- addProofExternals topLevel      let ws_complete = " ()"          -- Main proof input loop-        loop :: Lemma -> CLT (InputT IO) ()+        loop :: NamedLemma -> InputT m ()         loop l = do-            mExpr <- popScriptLine+            mExpr <- lift popScriptLine             case mExpr of                 Nothing -> do-                    printLemma l-                    st <- get-                    liftIO $ modifyMVar_ completionMVar (const $ return st) -- so the completion can get the current state-                    mLine <- lift $ getInputLine $ "proof> "+                    lift $ printLemma l+                    mLine <- getInputLine $ "proof> "                     case mLine of                         Nothing          -> fail "proof aborted (input: Nothing)"                         Just ('-':'-':_) -> loop l                         Just line        -> if all isSpace line                                             then loop l-                                            else (evalProofScript l line `catchM` (\msg -> cl_putStrLn msg >> return l)) >>= loop-                Just e -> (runExprH l e `catchM` (\msg -> setRunningScript Nothing >> cl_putStrLn msg >> return l)) >>= loop+                                            else lift (evalProofScript l line `catchM` (\msg -> cl_putStrLn msg >> return l)) >>= loop+                Just e -> lift (runExprH l e `catchM` (\msg -> setRunningScript Nothing >> cl_putStrLn msg >> return l)) >>= loop      -- Display a proof banner?      -- Start the CLI-    let settings = setComplete (completeWordWithPrev Nothing ws_complete (shellComplete completionMVar)) defaultSettings+    let settings = setComplete (completeWordWithPrev Nothing ws_complete shellComplete) defaultSettings         cleanup s = put (s { cl_externals = origEs })-    (r,_s) <- get >>= liftIO . runInputTBehavior defaultBehavior settings . flip runCLT (loop lem)-    case r of-        Right _               -> return ()      -- this case isn't possible, loop never returns-        Left CLAbort          -> cleanup origSt >> unless topLevel abort -- abandon proof attempt, bubble out to regular shell-        Left (CLContinue st') -> cleanup st'    -- successfully proven-        Left (CLError msg)    -> fail $ "Prover error: " ++ msg-        Left _                -> fail "unsupported exception in interactive prover"+    catchError (runInputT settings (loop lem))+               (\case+                    CLAbort        -> cleanup origSt >> unless topLevel abort -- abandon proof attempt, bubble out to regular shell+                    CLContinue st' -> do+                        cl_putStrLn $ "Successfully proven: " ++ show nm+                        if isTemporary+                        then cleanup st'    -- successfully proven+                        else do sast <- applyS (cl_kernel st')+                                               (modifyLemmaR nm id idR (const True) id :: RewriteH Core)+                                               (mkKernelEnv $ cl_pstate st')+                                               (cl_cursor st')+                                cleanup $ newSAST (CmdName "proven") sast st' +                    CLError msg    -> fail $ "Prover error: " ++ msg+                    _              -> fail "unsupported exception in interactive prover")+ addProofExternals :: MonadState CommandLineState m => Bool -> m [External] addProofExternals topLevel = do     st <- get@@ -275,16 +189,16 @@     when topLevel $ modify $ \ s -> s { cl_externals = newEs }     return es -evalProofScript :: MonadIO m => Lemma -> String -> CLT m Lemma+evalProofScript :: (MonadCatch m, MonadException m, CLMonad m) => NamedLemma -> String -> m NamedLemma evalProofScript lem = parseScriptCLT >=> foldM runExprH lem -runExprH :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => Lemma -> ExprH -> m Lemma+runExprH :: (MonadCatch m, MonadException m, CLMonad m) => NamedLemma -> ExprH -> m NamedLemma runExprH lem expr = prefixFailMsg ("Error in expression: " ++ unparseExprH expr ++ "\n")                   $ interpExprH interpProof expr >>= performProofShellCommand lem  -- | Verify that the lemma has been proven. Throws an exception if it has not.-endProof :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => Lemma -> m ()-endProof (nm, eq, _) = do+endProof :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => NamedLemma -> m ()+endProof (nm, Lemma eq _ _) = do     st <- get      let sk = cl_kernel st@@ -292,11 +206,11 @@         sast = cl_cursor st      -- Why do a query? We want to do our proof in the current context of the shell, whatever that is.-    b <- (queryS sk (return eq >>> testM verifyCoreExprEqualityT :: TransformH Core Bool) kEnv sast)-    if b then completeProof nm else fail $ "The two sides of " ++ nm ++ " are not alpha-equivalent."+    b <- (queryS sk (return eq >>> testM verifyEqualityT :: TransformH Core Bool) kEnv sast)+    if b then continue st else fail $ "The two sides of " ++ show nm ++ " are not alpha-equivalent." -performProofShellCommand :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => Lemma -> ProofShellCommand -> m Lemma-performProofShellCommand lem@(nm, eq, b) = go+performProofShellCommand :: (MonadCatch m, MonadException m, CLMonad m) => NamedLemma -> ProofShellCommand -> m NamedLemma+performProofShellCommand lem@(nm, Lemma eq p u) = go     where go (PCRewrite rr)         = do                 st <- get                 let sk = cl_kernel st@@ -304,8 +218,9 @@                     sast = cl_cursor st                  -- Why do a query? We want to do our proof in the current context of the shell, whatever that is.-                eq' <- queryS sk (return eq >>> rr >>> (bothT lintExprT >> idR) :: TransformH Core CoreExprEquality) kEnv sast-                return (nm, eq', b)+                -- TODO: query doesn't save side effects, which are needed for stash/lemmas+                eq' <- queryS sk (return eq >>> rr >>> (bothT lintExprT >> idR) :: TransformH Core Equality) kEnv sast+                return (nm, Lemma eq' p u)           go (PCTransform t)      = do                 st <- get                 let sk = cl_kernel st@@ -330,14 +245,14 @@                 st <- get                 -- Why do a query? We want to do our proof in the current context of the shell, whatever that is.                 queryS (cl_kernel st) (return eq >>> t :: TransformH Core ()) (cl_kernel_env st) (cl_cursor st)-                completeProof nm -- note: we assume that if 't' completes without failing, the lemma is proved, we don't actually check+                continue st -- note: we assume that if 't' completes without failing, the lemma is proved, we don't actually check                 return lem       -- never reached-          go (PCDump fName r w)   = dump (\ st -> return lem >>> ppLemmaT (cl_pretty st)) fName r w >> return lem+          go (PCDump fName r w)   = dump (\ st -> return (snd lem) >>> ppLemmaT (cl_pretty st) (fst lem)) fName r w >> return lem           go PCEnd                = endProof lem >> return lem           go (PCUnsupported s)    = cl_putStrLn (s ++ " command unsupported in proof mode.") >> return lem -performInduction :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => Lemma -> (Id -> Bool) -> m Lemma-performInduction lem@(nm, eq@(CoreExprEquality bs lhs rhs), _) idPred = do+performInduction :: (MonadCatch m, MonadException m, CLMonad m) => NamedLemma -> (Id -> Bool) -> m NamedLemma+performInduction lem@(nm, Lemma eq@(Equality bs lhs rhs) _ _) idPred = do     st <- get     let sk = cl_kernel st         kEnv = cl_kernel_env st@@ -355,29 +270,38 @@         eqs <- forM vs_matching_i_type $ \ i' ->                     liftM discardUniVars $ instantiateEqualityVar (==i) (Var i') [] eq -        let nms = [ "ind-hyp-" ++ show n | n :: Int <- [0..] ]-            hypLemmas = zip3 nms eqs (repeat True)-            caseLemma = ( nm ++ "-induction-on-" ++ getOccString i ++ "-case-" ++ maybe "undefined" getOccString mdc-                        , CoreExprEquality (delete i bs ++ vs) lhsE rhsE-                        , False )+        let nms = [ fromString ("ind-hyp-" ++ show n) | n :: Int <- [0..] ]+            hypLemmas = zip nms $ zipWith3 Lemma eqs (repeat True) (repeat False)+            lemmaName = fromString $ show nm ++ "-induction-on-"+                                             ++ unqualifiedName i ++ "-case-"+                                             ++ maybe "undefined" unqualifiedName mdc+            caseLemma = Lemma (Equality (delete i bs ++ vs) lhsE rhsE) False False -        origLemmas <- addLemmas hypLemmas-        interactiveProof False caseLemma -- recursion!-        modify $ \ s -> s { cl_lemmas = origLemmas } -- put original lemmas back+        -- this is pretty hacky+        sast' <- addLemmas hypLemmas  -- add temporary lemmas+        interactiveProof False True (lemmaName,caseLemma) -- recursion!+        modify $ flip setCursor sast' -- discard temporary lemmas -    completeProof nm+    get >>= continue     return lem -- this is never reached, but the type says we need it. -addLemmas :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => [Lemma] -> m [Lemma]+addLemmas :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m)+          => [NamedLemma] -> m SAST addLemmas lems = do     ifM isRunningScript (return ()) $ forM_ lems printLemma+    let addAllAtOnceR :: RewriteH Core+        addAllAtOnceR = sideEffectR $ \ _ _ -> forM_ lems $ \ (nm,l) -> insertLemma nm l+     st <- get-    put $ st { cl_lemmas = cl_lemmas st ++ lems }-    return $ cl_lemmas st+    sast <- applyS (cl_kernel st) addAllAtOnceR (mkKernelEnv $ cl_pstate st) (cl_cursor st)+    put $ newSAST (CmdName "adding lemmas") sast st +    -- return original SAST+    return $ cl_cursor st+ data ProofShellCommand-    = PCRewrite (RewriteH CoreExprEquality)-    | PCTransform (TransformH CoreExprEquality String)+    = PCRewrite (RewriteH Equality)+    | PCTransform (TransformH Equality String)     | PCInduction (Id -> Bool)     | PCShell ShellEffect     | PCScript ScriptEffect@@ -390,9 +314,9 @@     deriving Typeable  -- keep abstract to avoid breaking things if we modify this later-newtype UserProofTechnique = UserProofTechnique (TransformH CoreExprEquality ())+newtype UserProofTechnique = UserProofTechnique (TransformH Equality ()) -userProofTechnique :: TransformH CoreExprEquality () -> UserProofTechnique+userProofTechnique :: TransformH Equality () -> UserProofTechnique userProofTechnique = UserProofTechnique  instance Extern ProofShellCommand where@@ -407,29 +331,29 @@     box = UserProofTechniqueBox     unbox (UserProofTechniqueBox t) = t -interpProof :: [Interp ProofShellCommand]+interpProof :: Monad m => [Interp m ProofShellCommand] interpProof =-  [ interp $ \ (RewriteCoreBox rr)                    -> PCRewrite $ bothR $ extractR rr-  , interp $ \ (RewriteCoreTCBox rr)                  -> PCRewrite $ bothR $ extractR rr-  , interp $ \ (BiRewriteCoreBox br)                  -> PCRewrite $ bothR $ (extractR (forwardT br) <+ extractR (backwardT br))-  , interp $ \ (effect :: ShellEffect)                -> PCShell effect-  , interp $ \ (effect :: ScriptEffect)               -> PCScript effect-  , interp $ \ (StringBox str)                        -> PCQuery (message str)-  , interp $ \ (query :: QueryFun)                    -> PCQuery query-  , interp $ \ (cmd :: ProofCommand)                  -> PCProofCommand cmd-  , interp $ \ (RewriteCoreExprEqualityBox r)         -> PCRewrite r-  , interp $ \ (TransformCoreExprEqualityStringBox t) -> PCTransform t-  , interp $ \ (UserProofTechniqueBox t)              -> PCUser t-  , interp $ \ (cmd :: ProofShellCommand)             -> cmd-  , interp $ \ (CrumbBox _cr)                         -> PCUnsupported "CrumbBox"-  , interp $ \ (PathBox _p)                           -> PCUnsupported "PathBox"-  , interp $ \ (TransformCorePathBox _tt)             -> PCUnsupported "TransformCorePathBox"-  , interp $ \ (TransformCoreTCPathBox _tt)           -> PCUnsupported "TransformCoreTCPathBox"-  , interp $ \ (TransformCoreStringBox _tt)           -> PCUnsupported "TransformCoreStringBox"-  , interp $ \ (TransformCoreTCStringBox _tt)         -> PCUnsupported "TransformCoreTCStringBox"-  , interp $ \ (TransformCoreTCDocHBox _tt)           -> PCUnsupported "TransformCoreTCDocHBox"-  , interp $ \ (TransformCoreCheckBox _tt)            -> PCUnsupported "TransformCoreCheckBox"-  , interp $ \ (TransformCoreTCCheckBox _tt)          -> PCUnsupported "TransformCoreTCCheckBox"-  , interp $ \ (_effect :: KernelEffect)              -> PCUnsupported "KernelEffect"+  [ interp $ \ (RewriteCoreBox rr)            -> PCRewrite $ bothR $ extractR rr+  , interp $ \ (RewriteCoreTCBox rr)          -> PCRewrite $ bothR $ extractR rr+  , interp $ \ (BiRewriteCoreBox br)          -> PCRewrite $ bothR $ (extractR (forwardT br) <+ extractR (backwardT br))+  , interp $ \ (effect :: ShellEffect)        -> PCShell effect+  , interp $ \ (effect :: ScriptEffect)       -> PCScript effect+  , interp $ \ (StringBox str)                -> PCQuery (message str)+  , interp $ \ (query :: QueryFun)            -> PCQuery query+  , interp $ \ (cmd :: ProofCommand)          -> PCProofCommand cmd+  , interp $ \ (RewriteEqualityBox r)         -> PCRewrite r+  , interp $ \ (TransformEqualityStringBox t) -> PCTransform t+  , interp $ \ (UserProofTechniqueBox t)      -> PCUser t+  , interp $ \ (cmd :: ProofShellCommand)     -> cmd+  , interp $ \ (CrumbBox _cr)                 -> PCUnsupported "CrumbBox"+  , interp $ \ (PathBox _p)                   -> PCUnsupported "PathBox"+  , interp $ \ (TransformCorePathBox _tt)     -> PCUnsupported "TransformCorePathBox"+  , interp $ \ (TransformCoreTCPathBox _tt)   -> PCUnsupported "TransformCoreTCPathBox"+  , interp $ \ (TransformCoreStringBox _tt)   -> PCUnsupported "TransformCoreStringBox"+  , interp $ \ (TransformCoreTCStringBox _tt) -> PCUnsupported "TransformCoreTCStringBox"+  , interp $ \ (TransformCoreTCDocHBox _tt)   -> PCUnsupported "TransformCoreTCDocHBox"+  , interp $ \ (TransformCoreCheckBox _tt)    -> PCUnsupported "TransformCoreCheckBox"+  , interp $ \ (TransformCoreTCCheckBox _tt)  -> PCUnsupported "TransformCoreTCCheckBox"+  , interp $ \ (_effect :: KernelEffect)      -> PCUnsupported "KernelEffect"   ] 
src/HERMIT/Shell/ScriptToRewrite.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, LambdaCase, MultiParamTypeClasses, ScopedTypeVariables, TypeFamilies #-}+{-# LANGUAGE ConstraintKinds, DeriveDataTypeable, FlexibleContexts, LambdaCase,+             MultiParamTypeClasses, ScopedTypeVariables, TypeFamilies, CPP #-}  module HERMIT.Shell.ScriptToRewrite     ( -- * Converting Scripts to Rewrites@@ -15,7 +16,11 @@     ) where  import Control.Arrow+#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else import Control.Monad.Error+#endif import Control.Monad.State import Control.Exception hiding (catch) @@ -66,7 +71,7 @@ popScriptLine = gets cl_running_script >>= maybe (return Nothing) (\case []     -> setRunningScript Nothing >> return Nothing                                                                          (e:es) -> setRunningScript (Just es) >> return (Just e)) -performScriptEffect :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => (ExprH -> m ()) -> ScriptEffect -> m ()+performScriptEffect :: (MonadCatch m, CLMonad m) => (ExprH -> m ()) -> ScriptEffect -> m () performScriptEffect runner = go     where go (SeqMeta ms) = mapM_ go ms           go (LoadFile scriptName fileName) = do@@ -74,7 +79,7 @@             res <- liftIO $ try (readFile fileName)             case res of                 Left (err :: IOException) -> fail ("IO error: " ++ show err)-                Right str -> do +                Right str -> do                     script <- parseScriptCLT str                     modify $ \ st -> st {cl_scripts = (scriptName,script) : cl_scripts st}                     putStrToConsole ("Script \"" ++ scriptName ++ "\" loaded successfully from \"" ++ fileName ++ "\".")@@ -104,7 +109,7 @@             putStrToConsole ("Script \"" ++ scriptName ++ "\" ran successfully.")             showWindow -          go (SaveScript fileName scriptName) = do +          go (SaveScript fileName scriptName) = do             script <- lookupScript scriptName             putStrToConsole $ "Saving script \"" ++ scriptName ++ "\" to file \"" ++ fileName ++ "\"."             liftIO $ writeFile fileName $ unparseScript script@@ -164,7 +169,7 @@  ----------------------------------- -interpScriptR :: [Interp UnscopedScriptR]+interpScriptR :: Monad m => [Interp m UnscopedScriptR] interpScriptR =   [ interp (\ (RewriteCoreBox r)           -> ScriptPrimUn $ ScriptRewriteHCore r)   , interp (\ (RewriteCoreTCBox _)         -> ScriptUnsupported "rewrite that traverses types and coercions") -- TODO@@ -201,7 +206,7 @@  ----------------------------------- -scriptToRewrite :: MonadState CommandLineState m => Script -> m (RewriteH Core)+scriptToRewrite :: CLMonad m => Script -> m (RewriteH Core) scriptToRewrite scr = do     unscoped <- mapM (interpExprH interpScriptR) scr     scoped   <- unscopedToScopedScriptR $ zip scr unscoped@@ -210,13 +215,13 @@ -----------------------------------  -- | Insert a script into the 'Dictionary'.-addScriptToDict :: MonadState CommandLineState m => ScriptName -> Script -> m ()+addScriptToDict :: CLMonad m => ScriptName -> Script -> m () addScriptToDict nm scr = do     r <- scriptToRewrite scr      let ext = external nm r [ "User-loaded script." ] -    modify $ \ st -> st { cl_externals = ext : cl_externals st } +    modify $ \ st -> st { cl_externals = ext : cl_externals st }  ----------------------------------- 
src/HERMIT/Shell/ShellEffect.hs view
@@ -2,18 +2,21 @@              DeriveDataTypeable, GeneralizedNewtypeDeriving, LambdaCase,              MultiParamTypeClasses, ScopedTypeVariables #-} -module HERMIT.Shell.ShellEffect +module HERMIT.Shell.ShellEffect     ( ShellEffect(..)     , performShellEffect     , dump     ) where +#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else import Control.Monad.Error+#endif import Control.Monad.State  import Data.Typeable -import HERMIT.Dictionary import HERMIT.External import HERMIT.Kure import HERMIT.Kernel.Scoped@@ -33,7 +36,7 @@     | CLSModify (CommandLineState -> IO CommandLineState) -- ^ Modify shell state     | PluginComp (PluginM ())     | Continue -- ^ exit the shell, but don't abort/resume-    | Dump (CommandLineState -> TransformH CoreTC DocH) String String Int +    | Dump (CommandLineState -> TransformH CoreTC DocH) String String Int     | Resume     deriving Typeable @@ -46,11 +49,7 @@  performShellEffect :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => ShellEffect -> m () performShellEffect Abort  = abort-performShellEffect Resume = do-    st <- get-    sast' <- applyS (cl_kernel st) occurAnalyseAndDezombifyR (cl_kernel_env st) (cl_cursor st)-    resume sast'-+performShellEffect Resume = gets cl_cursor >>= resume performShellEffect Continue = get >>= continue performShellEffect (Dump pp fileName renderer width) = dump pp fileName renderer width 
src/HERMIT/Shell/Types.hs view
@@ -1,21 +1,22 @@-{-# LANGUAGE CPP, KindSignatures, GADTs, FlexibleContexts, DeriveDataTypeable, +{-# LANGUAGE ConstraintKinds, CPP, KindSignatures, GADTs, FlexibleContexts, DeriveDataTypeable,              FunctionalDependencies, GeneralizedNewtypeDeriving, InstanceSigs,              LambdaCase, RankNTypes, ScopedTypeVariables, TypeFamilies #-}  module HERMIT.Shell.Types where  import Control.Applicative-import Control.Arrow-import Control.Concurrent import Control.Concurrent.STM import Control.Monad.State+#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else import Control.Monad.Error+#endif -import Data.Char (isSpace) import Data.Dynamic-import Data.List (intercalate, isPrefixOf, nub)+import Data.List (intercalate) import qualified Data.Map as M-import Data.Maybe (isJust)+import Data.Maybe (fromMaybe, isJust) import Data.Monoid (mempty)  import HERMIT.Context@@ -23,9 +24,8 @@ import HERMIT.Kure import HERMIT.External import qualified HERMIT.GHC as GHC-import HERMIT.Kernel (AST, queryK)+import HERMIT.Kernel (AST, queryK, KernelEnv) import HERMIT.Kernel.Scoped-import HERMIT.Monad import HERMIT.Parser import HERMIT.PrettyPrinter.Common @@ -33,35 +33,17 @@ import HERMIT.Plugin.Renderer import HERMIT.Plugin.Types -import HERMIT.Dictionary.Inline-import HERMIT.Dictionary.Navigation-import HERMIT.Dictionary.Reasoning (CoreExprEquality)- import System.Console.Haskeline hiding (catch, display) import System.IO (Handle, stdout) -#ifndef mingw32_HOST_OS-import Data.Maybe (fromMaybe)+#ifdef mingw32_HOST_OS+import HERMIT.Win32.Console+#else import System.Console.Terminfo (setupTermFromEnv, getCapability, termColumns, termLines) #endif  ---------------------------------------------------------------------------------- -{---- | How to perform a given set of commands.------ Mnemonic:--- c = command type--- a = extra arguments type (use tuple for more than one)--- r = result type------ Often, a and r are (), but sometimes we need more clever things.-class ShellCommandSet c a r | c -> a r where-    performCommand :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m) => c -> a -> m r--}------------------------------------------------------------------------------------- data QueryFun :: * where    QueryString   :: (Injection GHC.ModGuts g, Walker HermitC g)                  => TransformH g String                                   -> QueryFun@@ -80,8 +62,7 @@    box i = i    unbox i = i -performQuery :: (MonadCatch m, MonadError CLException m, MonadIO m, MonadState CommandLineState m)-             => QueryFun -> ExprH -> m ()+performQuery :: (MonadCatch m, CLMonad m) => QueryFun -> ExprH -> m ()  performQuery (QueryString q) _ = do     st <- get@@ -156,7 +137,9 @@                  | CLContinue CommandLineState -- TODO: needed?                  | CLError String +#if !(MIN_VERSION_mtl(2,2,1)) instance Error CLException where strMsg = CLError+#endif  abort :: MonadError CLException m => m () abort = throwError CLAbort@@ -181,16 +164,41 @@ ----------------------------------------------------------------------------------  -- | This type is similiar to PluginM, except that its exception and state types are--- supersets of those for PluginM, and it is a transformer. There are two functions: --- `clm` and `pluginM` for converting between the two. The reason we do this is to obtain --- a clean separation of plugin state from commandline state without nesting state --- transformers. Nesting StateT leads to a lot of awkward lifting and manual state +-- supersets of those for PluginM, and it is a transformer. There are two functions:+-- `clm` and `pluginM` for converting between the two. The reason we do this is to obtain+-- a clean separation of plugin state from commandline state without nesting state+-- transformers. Nesting StateT leads to a lot of awkward lifting and manual state -- management in the command line code. -- -- NB: an alternative to monad transformers, like Oleg's Extensible Effects, might be useful here.+#if MIN_VERSION_mtl(2,2,1)+newtype CLT m a = CLT { unCLT :: ExceptT CLException (StateT CommandLineState m) a }+#else newtype CLT m a = CLT { unCLT :: ErrorT CLException (StateT CommandLineState m) a }+#endif     deriving (Functor, Applicative, MonadIO, MonadError CLException, MonadState CommandLineState) +-- Adapted from System.Console.Haskeline.MonadException, which hasn't provided an instance for ExceptT yet+#if MIN_VERSION_mtl(2,2,1)+instance MonadException m => MonadException (ExceptT e m) where+    controlIO f = ExceptT $ controlIO $ \(RunIO run) -> let+                    run' = RunIO (fmap ExceptT . run . runExceptT)+                    in fmap runExceptT $ f run'+#endif++instance MonadException m => MonadException (CLT m) where+    controlIO f = CLT $ controlIO $ \(RunIO run) -> let run' = RunIO (fmap CLT . run . unCLT)+                                                    in fmap unCLT $ f run'++-- This is copied verbatim from Haskeline, which provides an instance for strict State only.+-- This allows lazy State to enjoy the same benefits.+instance MonadException m => MonadException (StateT s m) where+    controlIO f = StateT $ \s -> controlIO $ \(RunIO run) -> let+                    run' = RunIO (fmap (StateT . const) . run . flip runStateT s)+                    in fmap (flip runStateT s) $ f run'++type CLMonad m = (MonadIO m, MonadState CommandLineState m, MonadError CLException m)+ instance MonadTrans CLT where     -- lift :: Monad m => m a -> CLT m a     lift = CLT . lift . lift@@ -206,7 +214,11 @@  -- | Run a CLT computation. runCLT :: CommandLineState -> CLT m a -> m (Either CLException a, CommandLineState)+#if MIN_VERSION_mtl(2,2,1)+runCLT s = flip runStateT s . runExceptT . unCLT+#else runCLT s = flip runStateT s . runErrorT . unCLT+#endif  -- | Lift a CLT IO computation into a CLT computation over an arbitrary MonadIO. clm2clt :: MonadIO m => CLT IO a -> CLT m a@@ -225,7 +237,7 @@         Right r' -> put (cl_pstate s') >> return r'  -- | Lift a PluginM computation into the CLM monad.-pluginM :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => PluginM a -> m a+pluginM :: CLMonad m => PluginM a -> m a pluginM m = do     s <- get     (r,ps) <- liftIO $ runPluginT (cl_pstate s) m@@ -268,7 +280,6 @@                                                   --   because nested StateT is a pain.     , cl_height         :: Int                    -- ^ console height, in lines     , cl_scripts        :: [(ScriptName,Script)]-    , cl_lemmas         :: [Lemma]                -- ^ list of lemmas, with flag indicating whether proven     , cl_nav            :: Bool                   -- ^ keyboard input the nav panel     , cl_version        :: VersionStore     , cl_window         :: PathH                  -- ^ path to beginning of window, always a prefix of focus path in kernel@@ -306,7 +317,7 @@ cl_kernel :: CommandLineState -> ScopedKernel cl_kernel = ps_kernel . cl_pstate -cl_kernel_env :: CommandLineState -> HermitMEnv+cl_kernel_env :: CommandLineState -> KernelEnv cl_kernel_env = mkKernelEnv . cl_pstate  cl_pretty :: CommandLineState -> PrettyPrinter@@ -324,16 +335,15 @@ cl_render :: CommandLineState -> (Handle -> PrettyOptions -> Either String DocH -> IO ()) cl_render = ps_render . cl_pstate --- | Create default CommandLineState from PluginState. +-- | Create default CommandLineState from PluginState. -- Note: the dictionary (cl_dict) will be empty, and should be populated if needed. mkCLS :: PluginM CommandLineState mkCLS = do     ps <- get-    (w,h) <- liftIO getTermDimensions    +    (w,h) <- liftIO getTermDimensions     let st = CommandLineState { cl_pstate         = ps                               , cl_height         = h                               , cl_scripts        = []-                              , cl_lemmas         = []                               , cl_nav            = False                               , cl_version        = VersionStore { vs_graph = [] , vs_tags = [] }                               , cl_window         = mempty@@ -346,7 +356,8 @@ getTermDimensions :: IO (Int, Int) getTermDimensions = do #ifdef mingw32_HOST_OS-    return (80,25) -- these are the standard windows CLI dimensions+    consoleSz <- getConsoleWindowSize+    return $ fromMaybe (80,25) consoleSz #else     term <- setupTermFromEnv     let w = fromMaybe 80 $ getCapability term termColumns@@ -361,8 +372,6 @@     box = CLSBox  type ScriptName = String-type LemmaName = String-type Lemma = (LemmaName,CoreExprEquality,Bool)  -- tick counter tick :: TVar (M.Map String Int) -> String -> IO Int@@ -374,10 +383,10 @@         writeTVar var (M.insert msg c m)         return c -cl_putStr :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()+cl_putStr :: CLMonad m => String -> m () cl_putStr = pluginM . ps_putStr -cl_putStrLn :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()+cl_putStrLn :: CLMonad m => String -> m () cl_putStrLn = pluginM . ps_putStrLn  isRunningScript :: MonadState CommandLineState m => m Bool@@ -387,65 +396,12 @@ setRunningScript ms = modify $ \st -> st { cl_running_script = ms }  -- TODO: rename?-putStrToConsole :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => String -> m ()+putStrToConsole :: CLMonad m => String -> m () putStrToConsole str = ifM isRunningScript (return ()) (cl_putStrLn str)  ------------------------------------------------------------------------------ -shellComplete :: MVar CommandLineState -> String -> String -> IO [Completion]-shellComplete mvar rPrev so_far = do-    st <- readMVar mvar-    targetQuery <- completionQuery st (completionType rPrev)-    -- (liftM.liftM) (map simpleCompletion . nub . filter (so_far `isPrefixOf`))-    --     $ queryS (cl_kernel st) (cl_cursor (cl_session st)) targetQuery-    -- TODO: I expect you want to build a silent version of the kernal_env for this query-    cl <- catchM (queryS (cl_kernel st) targetQuery (cl_kernel_env st) (cl_cursor st)) (\_ -> return [])-    return $ (map simpleCompletion . nub . filter (so_far `isPrefixOf`)) cl--data CompletionType = ConsiderC       -- considerable constructs and (deprecated) bindingOfT-                    | BindingOfC      -- bindingOfT-                    | BindingGroupOfC -- bindingGroupOfT-                    | RhsOfC          -- rhsOfT-                    | OccurrenceOfC   -- occurrenceOfT-                    | InlineC         -- complete with names that can be inlined-                    | CommandC        -- complete using dictionary commands (default)-                    | AmbiguousC [CompletionType]  -- completionType function needs to be more specific-    deriving (Show)---- TODO: reverse rPrev and parse it, to better figure out what possiblities are in context?---       for instance, completing "any-bu (inline " should be different than completing just "inline "---       this would also allow typed completion?-completionType :: String -> CompletionType-completionType = go . dropWhile isSpace-    where go rPrev = case [ ty | (nm, ty) <- opts, reverse nm `isPrefixOf` rPrev ] of-                        []  -> CommandC-                        [t] -> t-                        ts  -> AmbiguousC ts-          opts = [ ("inline"          , InlineC  )-                 , ("consider"        , ConsiderC)-                 , ("binding-of"      , BindingOfC)-                 , ("binding-group-of", BindingGroupOfC)-                 , ("rhs-of"          , RhsOfC)-                 , ("occurrence-of"   , OccurrenceOfC)-                 ]--completionQuery :: CommandLineState -> CompletionType -> IO (TransformH CoreTC [String])-completionQuery _ ConsiderC       = return $ bindingOfTargetsT       >>^ GHC.varSetToStrings >>^ map ('\'':) >>^ (++ map fst considerables) -- the use of bindingOfTargetsT here is deprecated-completionQuery _ OccurrenceOfC   = return $ occurrenceOfTargetsT    >>^ GHC.varSetToStrings >>^ map ('\'':)-completionQuery _ BindingOfC      = return $ bindingOfTargetsT       >>^ GHC.varSetToStrings >>^ map ('\'':)-completionQuery _ BindingGroupOfC = return $ bindingGroupOfTargetsT  >>^ GHC.varSetToStrings >>^ map ('\'':)-completionQuery _ RhsOfC          = return $ rhsOfTargetsT           >>^ GHC.varSetToStrings >>^ map ('\'':)-completionQuery _ InlineC         = return $ promoteT inlineTargetsT >>^                         map ('\'':)-completionQuery s CommandC        = return $ pure (map externName (cl_externals s))--- Need to modify opts in completionType function. No key can be a suffix of another key.-completionQuery _ (AmbiguousC ts) = do-    putStrLn "\nCannot tab complete: ambiguous completion type."-    putStrLn $ "Possibilities: " ++ intercalate ", " (map show ts)-    return (pure [])----------------------------------------------------------------------------------fixWindow :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => m ()+fixWindow :: CLMonad m => m () fixWindow = do     st <- get     -- check to make sure new path is still inside window@@ -457,7 +413,7 @@        $ put $ st { cl_window = focusPath } -}     put $ st { cl_window = focusPath } -- TODO: temporary until we figure out a better highlight interface -showWindow :: (MonadError CLException m, MonadIO m, MonadState CommandLineState m) => m ()+showWindow :: CLMonad m => m () showWindow = ifM isRunningScript (return ()) $ fixWindow >> gets cl_window >>= pluginM . display . Just  ------------------------------------------------------------------------------@@ -470,7 +426,7 @@                 [ [ unparseExprH b ++ "\n" ++ showGraph graph tags c ]                 | (b,c) <- paths                 ])-  where  +  where           paths = [ (b,c) | (a,b,c) <- graph, a == this ]  ------------------------------------------------------------------------------
src/HERMIT/Utilities.hs view
@@ -1,15 +1,14 @@ module HERMIT.Utilities-  ( -- * Utilities-    nodups-  , dups-  , dupsBy-  , soleElement-  , equivalentBy-  , equivalent-  , whenJust-  , maybeM-  )-where+    ( -- * Utilities+      nodups+    , dups+    , dupsBy+    , soleElement+    , equivalentBy+    , equivalent+    , whenJust+    , maybeM+    ) where  ------------------------------------------------------------------------------ 
+ src/HERMIT/Win32/Console.hsc view
@@ -0,0 +1,105 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-- | Taken from <https://github.com/batterseapower/ansi-terminal/blob/master/System/Console/ANSI/Windows/Foreign.hs> in the ansi-terminal package by batterseapower, licensed under BSD3+module HERMIT.Win32.Console+    (+      getConsoleWindowSize+    , isCygwinConsole+    ) where++import Control.Applicative+import Control.Exception (try)++import Foreign.C.Types+import Foreign.Marshal+import Foreign.Ptr+import Foreign.Storable++import System.Environment+import System.Win32.Types++#include <windows.h>+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)++type SHORT = CShort++isCygwinConsole :: IO Bool+isCygwinConsole = do+    result <- try $ getEnv "_" -- Cygwin defines this, Windows Cmd does not+    return $ case (result :: Either IOError String) of+                  Left _ -> False+                  Right _ -> True++getConsoleWindowSize :: IO (Maybe (Int, Int))+getConsoleWindowSize = do+    hStdout <- getStdHandle sTD_OUTPUT_HANDLE+    csbiInfo <- getConsoleScreenBufferInfo hStdout+    return $ fmap coords csbiInfo+        where coords :: CONSOLE_SCREEN_BUFFER_INFO -> (Int, Int)+              coords info = case csbi_maximum_window_size info of+                                 (COORD x y) -> (fromIntegral x, fromIntegral y)++sTD_OUTPUT_HANDLE :: DWORD+sTD_OUTPUT_HANDLE = #{const STD_OUTPUT_HANDLE}++foreign import ccall unsafe "windows.h GetStdHandle"+    getStdHandle :: DWORD -> IO HANDLE+foreign import ccall unsafe "windows.h GetConsoleScreenBufferInfo"+    cGetConsoleScreenBufferInfo :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFO -> IO BOOL++getConsoleScreenBufferInfo :: HANDLE -> IO (Maybe CONSOLE_SCREEN_BUFFER_INFO)+getConsoleScreenBufferInfo handle = alloca $ \ptr_console_screen_buffer_info -> do+    ret <- cGetConsoleScreenBufferInfo handle ptr_console_screen_buffer_info+    if ret then peek ptr_console_screen_buffer_info >>= return . Just+           else return Nothing++data CONSOLE_SCREEN_BUFFER_INFO = CONSOLE_SCREEN_BUFFER_INFO {+        _csbi_size :: COORD,+        _csbi_cursor_position :: COORD,+        _csbi_attributes :: WORD,+        _csbi_window :: SMALL_RECT,+        csbi_maximum_window_size :: COORD+    }++instance Storable CONSOLE_SCREEN_BUFFER_INFO where+    sizeOf _ = #{size CONSOLE_SCREEN_BUFFER_INFO}+    alignment _ = #{alignment CONSOLE_SCREEN_BUFFER_INFO}+    peek ptr = CONSOLE_SCREEN_BUFFER_INFO                        <$>+        #{peek CONSOLE_SCREEN_BUFFER_INFO, dwSize} ptr           <*>+        #{peek CONSOLE_SCREEN_BUFFER_INFO, dwCursorPosition} ptr <*>+        #{peek CONSOLE_SCREEN_BUFFER_INFO, wAttributes} ptr      <*>+        #{peek CONSOLE_SCREEN_BUFFER_INFO, srWindow} ptr         <*>+        #{peek CONSOLE_SCREEN_BUFFER_INFO, dwMaximumWindowSize} ptr+    poke ptr (CONSOLE_SCREEN_BUFFER_INFO size cursor_position attributes window maximum_window_size) = do+        #{poke CONSOLE_SCREEN_BUFFER_INFO, dwSize} ptr size+        #{poke CONSOLE_SCREEN_BUFFER_INFO, dwCursorPosition} ptr cursor_position+        #{poke CONSOLE_SCREEN_BUFFER_INFO, wAttributes} ptr attributes+        #{poke CONSOLE_SCREEN_BUFFER_INFO, srWindow} ptr window+        #{poke CONSOLE_SCREEN_BUFFER_INFO, dwMaximumWindowSize} ptr maximum_window_size++data COORD = COORD SHORT SHORT++instance Storable COORD where+    sizeOf _ = #{size COORD}+    alignment _ = #{alignment COORD}+    peek ptr =+        COORD <$> #{peek COORD, X} ptr+              <*> #{peek COORD, Y} ptr+    poke ptr (COORD x y) = do+        #{poke COORD, X} ptr x+        #{poke COORD, Y} ptr y++data SMALL_RECT = SMALL_RECT SHORT SHORT SHORT SHORT++instance Storable SMALL_RECT where+    sizeOf _ = #{size SMALL_RECT}+    alignment _ = #{alignment SMALL_RECT}+    peek ptr =+        SMALL_RECT <$> #{peek SMALL_RECT, Left} ptr+                   <*> #{peek SMALL_RECT, Top} ptr+                   <*> #{peek SMALL_RECT, Right} ptr+                   <*> #{peek SMALL_RECT, Bottom} ptr+    poke ptr (SMALL_RECT l t r b) = do+        #{poke SMALL_RECT, Left} ptr l+        #{poke SMALL_RECT, Top} ptr t+        #{poke SMALL_RECT, Right} ptr r+        #{poke SMALL_RECT, Bottom} ptr b
+ src/HERMIT/Win32/IO.hsc view
@@ -0,0 +1,239 @@+-- | Adapted from circular-ruin's StackOverflow answer at <http://stackoverflow.com/a/10779150>+{-# LANGUAGE ForeignFunctionInterface, CPP, NoImplicitPrelude #-}+module HERMIT.Win32.IO (+    HERMIT.Win32.IO.putChar+  , HERMIT.Win32.IO.putStr+  , HERMIT.Win32.IO.putStrLn+  , HERMIT.Win32.IO.print+  , ePutChar+  , ePutStr+  , ePutStrLn+  , ePrint+  , HERMIT.Win32.IO.hPutChar+  , HERMIT.Win32.IO.hPutStr+  , HERMIT.Win32.IO.hPutStrLn+  , HERMIT.Win32.IO.hPrint+  , trace+  , traceIO+  ) where++#include <windows.h>++import Control.Concurrent.MVar+import Control.Exception (bracket)++import Data.Char (ord)+import Data.Typeable++#if MIN_VERSION_base(4,7,0)+import Foreign+#else+import Foreign hiding (unsafePerformIO)+#endif+import Foreign.C.Types++import GHC.IO.FD (FD(..)) -- A wrapper around an Int32+import GHC.IO.Handle.Types (Handle(..), Handle__(..))++import Prelude hiding (putStr, putStrLn) --(IO, Read, Show, String)++import qualified System.IO (hPutChar, hPutStr, hPutStrLn)+import System.IO hiding (putStr, putStrLn, hPutChar, hPutStr, hPutStrLn)+import System.IO.Unsafe (unsafePerformIO)+import System.Win32.Types (BOOL, HANDLE, DWORD, LPDWORD, LPWSTR, LPVOID)++-- | <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx>+--   HANDLE WINAPI GetStdHandle(DWORD nStdHandle);+--   returns INVALID_HANDLE_VALUE, NULL, or a valid handle+foreign import ccall unsafe "GetStdHandle"+    win32GetStdHandle :: DWORD -> IO HANDLE++sTD_OUTPUT_HANDLE, sTD_ERROR_HANDLE :: DWORD+sTD_OUTPUT_HANDLE = (#const STD_OUTPUT_HANDLE)  -- all DWORD arithmetic is performed modulo 2^n+sTD_ERROR_HANDLE  = (#const STD_ERROR_HANDLE)++-- | <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx>+--   DWORD WINAPI GetFileType(HANDLE hFile);+foreign import ccall unsafe "GetFileType"+    win32GetFileType :: HANDLE -> IO DWORD++fILE_TYPE_CHAR, fILE_TYPE_REMOTE :: DWORD+fILE_TYPE_CHAR   = (#const FILE_TYPE_CHAR)+fILE_TYPE_REMOTE = (#const FILE_TYPE_REMOTE)++-- | <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx>+--   BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode);+foreign import ccall unsafe "GetConsoleMode"+    win32GetConsoleMode :: HANDLE -> LPDWORD -> IO BOOL++iNVALID_HANDLE_VALUE :: HANDLE+iNVALID_HANDLE_VALUE = intPtrToPtr $ -1++isAConsole :: HANDLE -> IO Bool+isAConsole handle+  = if (handle == iNVALID_HANDLE_VALUE) then return False+      else do ft <- win32GetFileType handle+              if ((ft .&. complement fILE_TYPE_REMOTE) /= fILE_TYPE_CHAR) then return False+                else do ptr <- malloc+                        cm  <- win32GetConsoleMode handle ptr+                        free ptr+                        return cm++-- | BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars,+--                             LPDWORD lpCharsWritten, LPVOID lpReserved); -}+foreign import ccall unsafe "WriteConsoleW" win32WriteConsoleW+  :: HANDLE -> LPWSTR -> DWORD -> LPDWORD -> LPVOID -> IO BOOL++data ConsoleInfo = ConsoleInfo Int (Ptr CWchar) (Ptr DWORD) HANDLE++writeConsole :: ConsoleInfo -> String -> IO ()+writeConsole (ConsoleInfo bufsize buf written handle) string+  = let fillbuf :: Int -> String -> IO ()+        fillbuf i [] = emptybuf buf i []+        fillbuf i remain@(first:rest)+          | i + 1 < bufsize && ordf <= 0xffff = do pokeElemOff buf i asWord+                                                   fillbuf (i+1) rest+          | i + 1 < bufsize && ordf >  0xffff = do pokeElemOff buf i word1+                                                   pokeElemOff buf (i+1) word2+                                                   fillbuf (i+2) rest+          | otherwise                         = emptybuf buf i remain+          where ordf   = ord first+                asWord = fromInteger (toInteger ordf) :: CWchar+                sub    = ordf - 0x10000+                word1' = ((shiftR sub 10) .&. 0x3ff) + 0xD800+                word2' = (sub .&. 0x3FF)             + 0xDC00+                word1  = fromInteger . toInteger $ word1'+                word2  = fromInteger . toInteger $ word2'++        emptybuf :: (Ptr CWchar) -> Int -> String -> IO ()+        emptybuf _ 0 []     = return ()+        emptybuf _ 0 remain = fillbuf 0 remain+        emptybuf ptr nLeft remain+          = do let nLeft'    = fromInteger . toInteger $ nLeft+               ret          <- win32WriteConsoleW handle ptr nLeft' written nullPtr+               nWritten     <- peek written+               let nWritten' = fromInteger . toInteger $ nWritten+               if ret && (nWritten > 0)+                  then emptybuf (ptr `plusPtr` (nWritten' * szWChar)) (nLeft - nWritten') remain+                  else fail "WriteConsoleW failed.\n"++    in  fillbuf 0 string++szWChar :: Int+szWChar = sizeOf (0 :: CWchar)++makeConsoleInfo :: DWORD -> Handle -> IO (Either ConsoleInfo Handle)+makeConsoleInfo nStdHandle fallback = do+    handle <- win32GetStdHandle nStdHandle+    handleToConsoleInfo handle fallback++handleToConsoleInfo :: HANDLE -> Handle -> IO (Either ConsoleInfo Handle)+handleToConsoleInfo handle fallback = do+    isConsole <- isAConsole handle+    let bufsize = 10000+    if not isConsole then return $ Right fallback+        else do buf <- mallocBytes (szWChar * bufsize)+                written <- malloc+                return . Left $ ConsoleInfo bufsize buf written handle++{-# NOINLINE stdoutConsoleInfo #-}+stdoutConsoleInfo :: Either ConsoleInfo Handle+stdoutConsoleInfo = unsafePerformIO $ makeConsoleInfo sTD_OUTPUT_HANDLE stdout++{-# NOINLINE stderrConsoleInfo #-}+stderrConsoleInfo :: Either ConsoleInfo Handle+stderrConsoleInfo = unsafePerformIO $ makeConsoleInfo sTD_ERROR_HANDLE stderr++conPutChar :: ConsoleInfo -> Char -> IO ()+conPutChar ci = writeConsole ci . replicate 1++conPutStr :: ConsoleInfo -> String -> IO ()+conPutStr = writeConsole++conPutStrLn :: ConsoleInfo -> String -> IO ()+conPutStrLn ci = writeConsole ci . (++ "\n")++putChar :: Char -> IO ()+putChar = (either conPutChar System.IO.hPutChar) stdoutConsoleInfo++putStr :: String -> IO ()+putStr = (either conPutStr System.IO.hPutStr) stdoutConsoleInfo++putStrLn :: String -> IO ()+putStrLn = (either conPutStrLn System.IO.hPutStrLn) stdoutConsoleInfo++print :: Show a => a -> IO ()+print = putStrLn . show++ePutChar :: Char -> IO ()+ePutChar = (either conPutChar System.IO.hPutChar) stderrConsoleInfo++ePutStr :: String -> IO ()+ePutStr = (either conPutStr System.IO.hPutStr) stderrConsoleInfo++ePutStrLn :: String -> IO ()+ePutStrLn = (either conPutStrLn System.IO.hPutStrLn) stderrConsoleInfo++ePrint :: Show a => a -> IO ()+ePrint = ePutStrLn . show++hPutChar :: Handle -> Char -> IO ()+hPutChar haskHandle c = withHandleToHANDLE haskHandle $ \ winHandle -> do+    eitherHandle <- handleToConsoleInfo winHandle haskHandle+    either conPutChar System.IO.hPutChar eitherHandle c++hPutStr :: Handle -> String -> IO ()+hPutStr haskHandle str = withHandleToHANDLE haskHandle $ \ winHandle -> do+    eitherHandle <- handleToConsoleInfo winHandle haskHandle+    either conPutStr System.IO.hPutStr eitherHandle str++hPutStrLn :: Handle -> String -> IO ()+hPutStrLn haskHandle str = withHandleToHANDLE haskHandle $ \ winHandle -> do+    eitherHandle <- handleToConsoleInfo winHandle haskHandle+    either conPutStrLn System.IO.hPutStrLn eitherHandle str++hPrint :: Show a => Handle -> a -> IO ()+hPrint = (. show) . hPutStrLn++trace :: String -> a -> a+trace string expr = unsafePerformIO $ do+    traceIO string+    return expr++traceIO :: String -> IO ()+traceIO = ePutStrLn++-------------------------------------------------------------------------------+-- All code that follows is taken from ansi-terminal by batterseapower, which+-- is licensed under BSD3++-- This essential function comes from the C runtime system. It is certainly provided by msvcrt, and also seems to be provided by the mingw C library - hurrah!+foreign import ccall unsafe "_get_osfhandle"+    cget_osfhandle :: CInt -> IO HANDLE++-- | This bit is all highly dubious. The problem is that we want to output ANSI to arbitrary Handles rather than forcing+-- people to use stdout. However, the Windows ANSI emulator needs a Windows HANDLE to work it's magic, so we need to be able+-- to extract one of those from the Haskell Handle.+--+-- This code accomplishes this, albeit at the cost of only being compatible with GHC.+withHandleToHANDLE :: Handle -> (HANDLE -> IO a) -> IO a+withHandleToHANDLE haskell_handle action =+    -- Create a stable pointer to the Handle. This prevents the garbage collector+    -- getting to it while we are doing horrible manipulations with it, and hence+    -- stops it being finalized (and closed).+    withStablePtr haskell_handle $ const $ do+        -- Grab the write handle variable from the Handle+        let write_handle_mvar = case haskell_handle of+                FileHandle _ handle_mvar -> handle_mvar+                DuplexHandle _ _ handle_mvar -> handle_mvar -- This is "write" MVar, we could also take the "read" one++        Just fd <- fmap (\(Handle__ { haDevice = dev }) -> fmap fdFD (cast dev)) $ readMVar write_handle_mvar++        -- Finally, turn that (C-land) FD into a HANDLE using msvcrt+        windows_handle <- cget_osfhandle fd++        -- Do what the user originally wanted+        action windows_handle++withStablePtr :: a -> (StablePtr a -> IO b) -> IO b+withStablePtr value = bracket (newStablePtr value) freeStablePtr