-- Replace all top-level discharged coeffects with a variable
-- and derelict anything else
-- but add a var
discToFreshVarsIn :: (?globals :: Globals) => Span -> [Id] -> Ctxt Assumption -> Coeffect
  -> Checker (Ctxt Assumption)
discToFreshVarsIn s vars ctxt coeffect = mapM toFreshVar (relevantSubCtxt vars ctxt)
  where
    toFreshVar (var, Discharged t c) = do
      (coeffTy, _) <- mguCoeffectTypesFromCoeffects s c coeffect
      return (var, Discharged t (CSig c coeffTy))

    toFreshVar (var, Linear t) = do
      coeffTy <- inferCoeffectType s coeffect
      return (var, Discharged t (COne coeffTy))


-- `freshVarsIn names ctxt` creates a new context with
-- all the variables names in `ctxt` that appear in the list
-- `vars` and are discharged are
-- turned into discharged coeffect assumptions annotated
-- with a fresh coeffect variable (and all variables not in
-- `vars` get deleted).
-- Returns also the list of newly generated type variables
-- e.g.
--  `freshVarsIn ["x", "y"] [("x", Discharged (2, Int),
--                           ("y", Linear Int),
--                           ("z", Discharged (3, Int)]
--  -> ([("x", Discharged (c5 :: Nat, Int),
--      ("y", Linear Int)]
--     , [c5 :: Nat])
discToFreshVarsIn :: (?globals :: Globals) => Span -> [Id] -> Ctxt Assumption -> Coeffect
  -> Checker (Ctxt Assumption)
discToFreshVarsIn s vars ctxt coeffect = mapM toFreshVar (relevantSubCtxt vars ctxt)
  where
    toFreshVar (var, Discharged t c) = do
      (coeffTy, _) <- mguCoeffectTypesFromCoeffects s c coeffect
      return (var, Discharged t (CSig c coeffTy))

    toFreshVar (var, Linear t) = do
      coeffTy <- inferCoeffectType s coeffect
      return (var, Discharged t (COne coeffTy))


-- `freshVarsIn names ctxt` creates a new context with
-- all the variables names in `ctxt` that appear in the list
-- `vars` and are discharged are
-- turned into discharged coeffect assumptions annotated
-- with a fresh coeffect variable (and all variables not in
-- `vars` get deleted).
-- Returns also the list of newly generated type variables
-- e.g.
--  `freshVarsIn ["x", "y"] [("x", Discharged (2, Int),
--                           ("y", Linear Int),
--                           ("z", Discharged (3, Int)]
--  -> ([("x", Discharged (c5 :: Nat, Int),
--      ("y", Linear Int)]
--     , [c5 :: Nat])
discToFreshVarsIn s vars ctxt coeffect = mapM toFreshVar (relevantSubCtxt vars ctxt)
  where
    toFreshVar (var, Discharged t c) = do
      (coeffTy, _) <- mguCoeffectTypesFromCoeffects s c coeffect
      return (var, Discharged t (CSig c coeffTy))

    toFreshVar (var, Linear t) = do
      coeffTy <- inferCoeffectType s coeffect
      return (var, Discharged t (COne coeffTy))


-- `freshVarsIn names ctxt` creates a new context with
-- all the variables names in `ctxt` that appear in the list
-- `vars` and are discharged are
-- turned into discharged coeffect assumptions annotated
-- with a fresh coeffect variable (and all variables not in
-- `vars` get deleted).
-- Returns also the list of newly generated type variables
-- e.g.
--  `freshVarsIn ["x", "y"] [("x", Discharged (2, Int),
--                           ("y", Linear Int),
--                           ("z", Discharged (3, Int)]
--  -> ([("x", Discharged (c5 :: Nat, Int),
--      ("y", Linear Int)]
--     , [c5 :: Nat])