Skip to content

Commit 78e6caa

Browse files
committed
revert headspine
1 parent dd1328d commit 78e6caa

File tree

7 files changed

+265
-70
lines changed

7 files changed

+265
-70
lines changed

plutus-core/plutus-core/src/PlutusCore/Builtin/KnownType.hs

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ module PlutusCore.Builtin.KnownType
2121
, KnownBuiltinType
2222
, BuiltinResult (..)
2323
, ReadKnownM
24-
, Spine (..)
2524
, HeadSpine (..)
2625
, headSpine
2726
, MonoHeadSpine
@@ -47,11 +46,9 @@ import PlutusCore.Pretty
4746
import Control.Monad.Except
4847
import Data.Bifunctor
4948
import Data.Either.Extras
50-
import Data.Functor.Identity
5149
import Data.String
5250
import GHC.Exts (inline, oneShot)
5351
import GHC.TypeLits
54-
import Prettyprinter
5552
import Text.PrettyBy.Internal
5653
import Universe
5754

@@ -282,13 +279,6 @@ readKnownConstant val = asConstant val >>= oneShot \case
282279
Nothing -> throwError $ BuiltinUnliftingEvaluationError $ typeMismatchError uniExp uniAct
283280
{-# INLINE readKnownConstant #-}
284281

285-
-- | A non-empty spine. Isomorphic to 'NonEmpty', except is strict and is defined as a single
286-
-- recursive data type.
287-
data Spine a
288-
= SpineLast a
289-
| SpineCons a (Spine a)
290-
deriving stock (Show, Eq, Foldable, Functor)
291-
292282
-- | The head-spine form of an iterated application. Provides O(1) access to the head of the
293283
-- application. @NonEmpty a ~ HeadSpine a a@, except is strict and the no-spine case is made a separate
294284
-- constructor for performance reasons (it only takes a single pattern match to access the head when
@@ -297,47 +287,30 @@ data Spine a
297287
--
298288
-- Used in built-in functions returning function applications such as 'CaseList'.
299289
data HeadSpine a b
300-
= HeadOnly a
301-
| HeadSpine a (Spine b)
290+
= Head a
291+
| Snoc (HeadSpine a b) b
302292
deriving stock (Show, Eq, Functor)
303293

304294
-- | @HeadSpine@ but the type of head and spine is same
305295
type MonoHeadSpine a = HeadSpine a a
306296

307297
instance Bifunctor HeadSpine where
308-
bimap headF _ (HeadOnly a) = HeadOnly $ headF a
309-
bimap headF spineF (HeadSpine a b) = HeadSpine (headF a) (spineF <$> b)
298+
bimap f g = go where
299+
go (Head x) = Head (f x)
300+
go (Snoc ys y) = Snoc (go ys) (g y)
301+
{-# INLINE bimap #-}
310302

311303
-- | Construct @HeadSpine@ from head and list.
312304
headSpine :: a -> [b] -> HeadSpine a b
313-
headSpine h [] = HeadOnly h
314-
headSpine h (x:xs) =
315-
-- It's critical to use 'foldr' here, so that deforestation kicks in.
316-
-- See Note [Definition of foldl'] in "GHC.List" and related Notes around for an explanation
317-
-- of the trick.
318-
HeadSpine h $ foldr (\x2 r x1 -> SpineCons x1 $ r x2) SpineLast xs x
305+
-- It's critical to use 'foldl' here, so that deforestation kicks in.
306+
-- See Note [Definition of foldl'] in "GHC.List" and related Notes around for an explanation
307+
-- of the trick.
308+
headSpine = foldl Snoc . Head
319309
{-# INLINE headSpine #-}
320310

321-
-- |
322-
--
323-
-- >>> import Text.Pretty
324-
-- >>> pretty (SpineCons 'a' $ SpineLast 'b')
325-
-- [a, b]
326-
instance Pretty a => Pretty (Spine a) where pretty = pretty . map Identity . toList
327-
instance PrettyBy config a => DefaultPrettyBy config (Spine a)
328-
deriving via PrettyCommon (Spine a)
329-
instance PrettyDefaultBy config (Spine a) => PrettyBy config (Spine a)
330-
331-
-- |
332-
--
333-
-- >>> import Text.Pretty
334-
-- >>> pretty (HeadOnly 'z')
335-
-- z
336-
-- >>> pretty (HeadSpine 'f' (SpineCons 'x' $ SpineLast 'y'))
337-
-- f `applyN` [x, y]
338311
instance (Pretty a, Pretty b) => Pretty (HeadSpine a b) where
339-
pretty (HeadOnly x) = pretty x
340-
pretty (HeadSpine f xs) = pretty f <+> "`applyN`" <+> pretty xs
312+
pretty _ = ""
313+
341314
instance (PrettyBy config a, PrettyBy config b) => DefaultPrettyBy config (HeadSpine a b)
342315
deriving via PrettyCommon (HeadSpine a b)
343316
instance PrettyDefaultBy config (HeadSpine a b) => PrettyBy config (HeadSpine a b)

plutus-core/plutus-core/src/PlutusCore/Default/Universe.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
{-# OPTIONS -fno-warn-missing-pattern-synonym-signatures #-}
23
-- on 9.2.4 this is the flag that suppresses the above warning
34
{-# OPTIONS -Wno-missing-signatures #-}
@@ -552,11 +553,11 @@ instance CaseBuiltin DefaultUni where
552553
-- We allow there to be only one branch as long as the scrutinee is 'False'.
553554
-- This is strictly to save size by not having the 'True' branch if it was gonna be
554555
-- 'Error' anyway.
555-
False | len == 1 || len == 2 -> Right $ HeadOnly $ branches Vector.! 0
556-
True | len == 2 -> Right $ HeadOnly $ branches Vector.! 1
556+
False | len == 1 || len == 2 -> Right $ Head $ branches Vector.! 0
557+
True | len == 2 -> Right $ Head $ branches Vector.! 1
557558
_ -> Left $ outOfBoundsErr someVal branches
558559
DefaultUniInteger
559-
| 0 <= x && x < toInteger len -> Right $ HeadOnly $ branches Vector.! fromInteger x
560+
| 0 <= x && x < toInteger len -> Right $ Head $ branches Vector.! fromInteger x
560561
| otherwise -> Left $ outOfBoundsErr someVal branches
561562
DefaultUniList ty
562563
| len == 1 ->
@@ -565,7 +566,7 @@ instance CaseBuiltin DefaultUni where
565566
(y : ys) -> Right $ headSpine (branches Vector.! 0) [someValueOf ty y, someValueOf uni ys]
566567
| len == 2 ->
567568
case x of
568-
[] -> Right $ HeadOnly $ branches Vector.! 1
569+
[] -> Right $ Head $ branches Vector.! 1
569570
(y : ys) -> Right $ headSpine (branches Vector.! 0) [someValueOf ty y, someValueOf uni ys]
570571
| otherwise -> Left $ outOfBoundsErr someVal branches
571572
_ -> Left $ display uni <> " isn't supported in 'case'"

plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/Ck.hs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,12 @@ FrameCase cs : stack <| e = case e of
247247
case unCaserBuiltin caser val $ Vector.fromList cs of
248248
Left err ->
249249
throwErrorWithCause (OperationalError $ CkCaseBuiltinError err) $ ckValueToTerm e
250-
Right (HeadOnly fX) -> stack |> fX
251-
Right (HeadSpine f xs) -> transferConstantSpine xs stack |> f
250+
Right hSp ->
251+
let go stack' (Head f) = stack' |> f
252+
go stack' (Snoc xs x) = go (FrameAwaitFunValue (VCon x) : stack') xs
253+
in go stack hSp
252254
_ -> throwErrorWithCause (StructuralError NonConstrScrutinizedMachineError) $ ckValueToTerm e
253255

254-
transferConstantSpine :: Spine (Some (ValueOf uni)) -> Context uni fun -> Context uni fun
255-
transferConstantSpine args ctx = foldr ((:) . FrameAwaitFunValue . VCon) ctx args
256-
257256
-- | Take a possibly partial builtin application and
258257
--
259258
-- - either create a 'CkValue' by evaluating the application if it's saturated (emitting logs, if

plutus-core/plutus-core/src/PlutusCore/MkPlc.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,10 @@ mkFreshTermLet aT a = do
341341

342342
-- | 'apply' the head of the application to the arguments iteratively.
343343
headSpineToTerm :: TermLike term tyname name uni fun => ann -> MonoHeadSpine (term ann) -> term ann
344-
headSpineToTerm _ (HeadOnly t) = t
345-
headSpineToTerm ann (HeadSpine t ts) = foldl (apply ann) t ts
344+
headSpineToTerm _ (Head f) = f
345+
headSpineToTerm ann (Snoc ys y) = apply ann (headSpineToTerm ann ys) y
346346

347347
-- | @headSpineToTerm@ but without annotation.
348348
headSpineToTermNoAnn :: TermLike term tyname name uni fun => MonoHeadSpine (term ()) -> term ()
349-
headSpineToTermNoAnn (HeadOnly t) = t
350-
headSpineToTermNoAnn (HeadSpine t ts) = foldl (apply ()) t ts
349+
headSpineToTermNoAnn (Head f) = f
350+
headSpineToTermNoAnn (Snoc ys y) = apply () (headSpineToTermNoAnn ys) y

plutus-core/untyped-plutus-core/src/UntypedPlutusCore/Evaluation/Machine/Cek/Internal.hs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -707,14 +707,6 @@ But in case of 'Spine' the builtins machinery directly produces values, not term
707707
directly to the head of the application. Which is why 'transferSpine' is a right fold.
708708
-}
709709

710-
-- | Transfers a 'Spine' of constant values onto the stack. The first argument will be at the top of the stack.
711-
transferConstantSpine
712-
:: Spine (Some (ValueOf uni))
713-
-> Context uni fun ann
714-
-> Context uni fun ann
715-
transferConstantSpine args ctx = foldr (FrameAwaitFunValue . VCon) ctx args
716-
{-# INLINE transferConstantSpine #-}
717-
718710
runCekM
719711
:: forall cost uni fun ann
720712
. ThrowableBuiltins uni fun
@@ -876,8 +868,10 @@ enterComputeCek = computeCek
876868
-- Proceed with caser when expression given is not Constr.
877869
VCon val -> case unCaserBuiltin ?cekCaserBuiltin val cs of
878870
Left err -> throwErrorDischarged (OperationalError $ CekCaseBuiltinError err) e
879-
Right (HeadOnly fX) -> computeCek ctx env fX
880-
Right (HeadSpine f xs) -> computeCek (transferConstantSpine xs ctx) env f
871+
Right hSp ->
872+
let go ctx' (Head f) = computeCek ctx' env f
873+
go ctx' (Snoc xs x) = go (FrameAwaitFunValue (VCon x) ctx') xs
874+
in go ctx hSp
881875
_ -> throwErrorDischarged (StructuralError NonConstrScrutinizedMachineError) e
882876

883877
-- | @force@ a term and proceed.

plutus-core/untyped-plutus-core/src/UntypedPlutusCore/Evaluation/Machine/SteppableCek/Internal.hs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,6 @@ data Context uni fun ann
106106
deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni)
107107
=> Show (Context uni fun ann)
108108

109-
-- | Transfers a 'Spine' of contant values onto the stack. The first argument will be at the top of the stack.
110-
transferConstantSpine :: ann -> Spine (Some (ValueOf uni)) -> Context uni fun ann -> Context uni fun ann
111-
transferConstantSpine ann args ctx =
112-
foldr (FrameAwaitFunValue ann . VCon) ctx args
113-
114109
computeCek
115110
:: forall uni fun ann s
116111
. (ThrowableBuiltins uni fun, GivenCekReqs uni fun ann s)
@@ -217,9 +212,11 @@ returnCek (FrameCases ann env cs ctx) e = case e of
217212
in computeCek ctx' env t
218213
Nothing -> throwErrorDischarged (StructuralError $ MissingCaseBranchMachineError i) e
219214
VCon val -> case unCaserBuiltin ?cekCaserBuiltin val cs of
220-
Left err -> throwErrorDischarged (OperationalError $ CekCaseBuiltinError err) e
221-
Right (HeadOnly fX) -> pure $ Computing ctx env fX
222-
Right (HeadSpine f xs) -> pure $ Computing (transferConstantSpine ann xs ctx) env f
215+
Left err -> throwErrorDischarged (OperationalError $ CekCaseBuiltinError err) e
216+
Right hSp ->
217+
let go ctx' (Head f) = computeCek ctx' env f
218+
go ctx' (Snoc xs x) = go (FrameAwaitFunValue ann (VCon x) ctx') xs
219+
in go ctx hSp
223220
_ -> throwErrorDischarged (StructuralError NonConstrScrutinizedMachineError) e
224221

225222
-- | @force@ a term and proceed.

0 commit comments

Comments
 (0)