|
| 1 | +module Main where |
| 2 | + |
| 3 | +import Control.Lens (traverseOf) |
| 4 | +import Plutarch.Prelude |
| 5 | +import Plutarch.Internal.Term (compile, punsafeCoerce, punsafeBuiltin) |
| 6 | +import Plutarch.Script |
| 7 | +import PlutusCore.Pretty |
| 8 | +import UntypedPlutusCore (programMapNames, fakeNameDeBruijn, progTerm, unDeBruijnTerm) |
| 9 | +import PlutusCore (runQuoteT, FreeVariableError) |
| 10 | +import PlutusCore qualified as PLC |
| 11 | + |
| 12 | +-- conditional with no hoisting |
| 13 | +pif'' :: Term s PBool -> Term s a -> Term s a -> Term s a |
| 14 | +pif'' cond ifT ifF = |
| 15 | + pforce $ (pforce $ punsafeBuiltin PLC.IfThenElse) # cond # pdelay ifT # pdelay ifF |
| 16 | + |
| 17 | +pfix' :: (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b) |
| 18 | +pfix' f = |
| 19 | + (plam $ \r -> (punsafeCoerce r) # r) # |
| 20 | + (plam $ \r -> f ((punsafeCoerce r) # r)) |
| 21 | + |
| 22 | +pfactorial :: Term s (PInteger :--> PInteger) |
| 23 | +pfactorial = |
| 24 | + -- This is concise, but slower |
| 25 | + pfix' $ \r -> plam $ \x -> pif'' (x #== 0) 1 (x * (r # (x - 1))) |
| 26 | + -- This bloats the script size, but faster |
| 27 | + -- punrollBound 11 perror $ \r -> plam $ \x -> pif (x #== 1) x (x * (r # (x - 1))) |
| 28 | + |
| 29 | +main :: IO () |
| 30 | +main = |
| 31 | + case compile mempty $ pfactorial # 10 of |
| 32 | + Left _ -> error "compiliation failed" |
| 33 | + Right (Script s) -> |
| 34 | + case runQuoteT $ traverseOf progTerm unDeBruijnTerm $ programMapNames fakeNameDeBruijn s of |
| 35 | + Left (_ :: FreeVariableError) -> error "debruijn conversion failed" |
| 36 | + Right s' -> print $ prettyPlcClassic s' |
0 commit comments