{-# LANGUAGE BlockArguments  #-}
{-# LANGUAGE LambdaCase      #-}
{-# LANGUAGE PatternSynonyms #-}

module PlutusIR.Transform.RewriteRules.RemoveTrace
  ( rewriteRuleRemoveTrace
  ) where

import PlutusCore.Default (DefaultFun)
import PlutusCore.Default.Builtins qualified as Builtin
import PlutusIR.Transform.RewriteRules.Common (pattern A, pattern B, pattern I)
import PlutusIR.Transform.RewriteRules.Internal (RewriteRules (..))

{- Note [Impure trace messages]

Removing of traces could change behavior of those programs that use impure trace messages
e.g. `trace (error ()) foo`.

While it is possible to force evaluation of a trace message when removing a trace call
for the sake of a behavior preservation, this has a downside that pure messages remain
in the program and are not elimitated as a "dead" code.

This downside would defeat the purpose of removing traces, so we decided to not force.
-}

rewriteRuleRemoveTrace :: RewriteRules uni DefaultFun
rewriteRuleRemoveTrace :: forall (uni :: * -> *). RewriteRules uni DefaultFun
rewriteRuleRemoveTrace = (forall tyname (m :: * -> *) a.
 (MonadQuote m, Monoid a) =>
 VarsInfo tyname Name uni a
 -> Term tyname Name uni DefaultFun a
 -> m (Term tyname Name uni DefaultFun a))
-> RewriteRules uni DefaultFun
forall (uni :: * -> *) fun.
(forall tyname (m :: * -> *) a.
 (MonadQuote m, Monoid a) =>
 VarsInfo tyname Name uni a
 -> Term tyname Name uni fun a -> m (Term tyname Name uni fun a))
-> RewriteRules uni fun
RewriteRules \VarsInfo tyname Name uni a
_varsInfo -> \case
  B DefaultFun
Builtin.Trace `I` Type tyname uni a
_argTy `A` Term tyname Name uni DefaultFun a
_msg `A` Term tyname Name uni DefaultFun a
arg -> Term tyname Name uni DefaultFun a
-> m (Term tyname Name uni DefaultFun a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Term tyname Name uni DefaultFun a
arg
  Term tyname Name uni DefaultFun a
term -> Term tyname Name uni DefaultFun a
-> m (Term tyname Name uni DefaultFun a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Term tyname Name uni DefaultFun a
term