module PlutusIR.Mark (
  markNonFreshTerm,
  markNonFreshType,
  markNonFreshProgram,
) where

import PlutusCore.Core qualified as PLC
import PlutusCore.Name.Unique qualified as PLC

import PlutusCore.Quote

import Data.Set.Lens (setOf)
import PlutusIR.Core

{- | Marks all the 'Unique's in a term as used, so they will not be generated in future.
Useful if you have a term which was not generated in 'Quote'.
-}
markNonFreshTerm ::
  (PLC.HasUniques (Term tyname name uni fun ann), MonadQuote m) =>
  Term tyname name uni fun ann ->
  m ()
markNonFreshTerm :: forall tyname name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term tyname name uni fun ann), MonadQuote m) =>
Term tyname name uni fun ann -> m ()
markNonFreshTerm = Set Unique -> m ()
forall (m :: * -> *). MonadQuote m => Set Unique -> m ()
markNonFreshMax (Set Unique -> m ())
-> (Term tyname name uni fun ann -> Set Unique)
-> Term tyname name uni fun ann
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Set Unique) (Term tyname name uni fun ann) Unique
-> Term tyname name uni fun ann -> Set Unique
forall a s. Getting (Set a) s a -> s -> Set a
setOf Getting (Set Unique) (Term tyname name uni fun ann) Unique
forall tyname name (uni :: * -> *) fun ann.
HasUniques (Term tyname name uni fun ann) =>
Fold (Term tyname name uni fun ann) Unique
Fold (Term tyname name uni fun ann) Unique
termUniquesDeep

{- | Marks all the 'Unique's in a type as used, so they will not be generated in future.
Useful if you have a type which was not generated in 'Quote'.
-}
markNonFreshType ::
  (PLC.HasUniques (Type tyname uni ann), MonadQuote m) =>
  Type tyname uni ann ->
  m ()
markNonFreshType :: forall tyname (uni :: * -> *) ann (m :: * -> *).
(HasUniques (Type tyname uni ann), MonadQuote m) =>
Type tyname uni ann -> m ()
markNonFreshType = Set Unique -> m ()
forall (m :: * -> *). MonadQuote m => Set Unique -> m ()
markNonFreshMax (Set Unique -> m ())
-> (Type tyname uni ann -> Set Unique)
-> Type tyname uni ann
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Set Unique) (Type tyname uni ann) Unique
-> Type tyname uni ann -> Set Unique
forall a s. Getting (Set a) s a -> s -> Set a
setOf Getting (Set Unique) (Type tyname uni ann) Unique
forall tyname (uni :: * -> *) ann.
HasUniques (Type tyname uni ann) =>
Fold (Type tyname uni ann) Unique
Fold (Type tyname uni ann) Unique
typeUniquesDeep

{- | Marks all the 'Unique's in a program as used, so they will not be generated in future.
Useful if you have a program which was not generated in 'Quote'.
-}
markNonFreshProgram ::
  (PLC.HasUniques (Program tyname name uni fun ann), MonadQuote m) =>
  Program tyname name uni fun ann ->
  m ()
markNonFreshProgram :: forall tyname name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Program tyname name uni fun ann), MonadQuote m) =>
Program tyname name uni fun ann -> m ()
markNonFreshProgram (Program ann
_ Version
_ Term tyname name uni fun ann
body) = Term tyname name uni fun ann -> m ()
forall tyname name (uni :: * -> *) fun ann (m :: * -> *).
(HasUniques (Term tyname name uni fun ann), MonadQuote m) =>
Term tyname name uni fun ann -> m ()
markNonFreshTerm Term tyname name uni fun ann
body