covenant
Copyright(C) MLabs 2025
LicenseApache 2.0
Maintainerkoz@mlabs.city, sean@mlabs.city
Safe HaskellNone
LanguageHaskell2010

Covenant.ASG

Description

The Covenant ASG, and ways to programmatically build it.

Note

We use the term 'ASG' to refer to 'abstract syntax graph'. This is because Covenant uses hash consing to ensure duplicate nodes do not exist, thus producing a DAG structure, rather than a tree.

Since: 1.0.0

Synopsis

The ASG itself

Types

data ASG Source #

A fully-assembled Covenant ASG.

Since: 1.0.0

Instances

Instances details
Show ASG Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

showsPrec :: Int -> ASG -> ShowS #

show :: ASG -> String #

showList :: [ASG] -> ShowS #

Eq ASG Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

(==) :: ASG -> ASG -> Bool #

(/=) :: ASG -> ASG -> Bool #

Functions

topLevelNode :: ASG -> ASGNode Source #

Retrieves the top-level node of an ASG.

Since: 1.0.0

nodeAt :: Id -> ASG -> ASGNode Source #

Given an Id and an ASG, produces the node corresponding to that Id.

Important note

This is only safe to use if the Id comes from a node in the argument ASG. Ids valid in one ASG are not likely to be valid in another. 'Mixing and matching' Ids from different ASGs will at best produce unexpected results, and at worst will crash. You have been warned.

Since: 1.0.0

ASG components

Types

data Id Source #

A unique identifier for a node in a Covenant program.

Since: 1.0.0

Instances

Instances details
Bounded Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

minBound :: Id #

maxBound :: Id #

Enum Id Source #

Needed for internal reasons, even though this type class is terrible.

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

succ :: Id -> Id #

pred :: Id -> Id #

toEnum :: Int -> Id #

fromEnum :: Id -> Int #

enumFrom :: Id -> [Id] #

enumFromThen :: Id -> Id -> [Id] #

enumFromTo :: Id -> Id -> [Id] #

enumFromThenTo :: Id -> Id -> Id -> [Id] #

Show Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

showsPrec :: Int -> Id -> ShowS #

show :: Id -> String #

showList :: [Id] -> ShowS #

Eq Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: Id -> Id -> Bool #

(/=) :: Id -> Id -> Bool #

Ord Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

compare :: Id -> Id -> Ordering #

(<) :: Id -> Id -> Bool #

(<=) :: Id -> Id -> Bool #

(>) :: Id -> Id -> Bool #

(>=) :: Id -> Id -> Bool #

max :: Id -> Id -> Id #

min :: Id -> Id -> Id #

MonadHashCons Id ASGNode ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

data Ref Source #

A general reference in a Covenant program.

Since: 1.0.0

Constructors

AnArg Arg

A function argument.

Since: 1.0.0

AnId Id

A link to an ASG node.

Since: 1.0.0

Instances

Instances details
Show Ref Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

showsPrec :: Int -> Ref -> ShowS #

show :: Ref -> String #

showList :: [Ref] -> ShowS #

Eq Ref Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: Ref -> Ref -> Bool #

(/=) :: Ref -> Ref -> Bool #

Ord Ref Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

compare :: Ref -> Ref -> Ordering #

(<) :: Ref -> Ref -> Bool #

(<=) :: Ref -> Ref -> Bool #

(>) :: Ref -> Ref -> Bool #

(>=) :: Ref -> Ref -> Bool #

max :: Ref -> Ref -> Ref #

min :: Ref -> Ref -> Ref #

data Arg Source #

An argument passed to a function in a Covenant program.

Since: 1.0.0

Instances

Instances details
Show Arg Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

showsPrec :: Int -> Arg -> ShowS #

show :: Arg -> String #

showList :: [Arg] -> ShowS #

Eq Arg Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: Arg -> Arg -> Bool #

(/=) :: Arg -> Arg -> Bool #

Ord Arg Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

compare :: Arg -> Arg -> Ordering #

(<) :: Arg -> Arg -> Bool #

(<=) :: Arg -> Arg -> Bool #

(>) :: Arg -> Arg -> Bool #

(>=) :: Arg -> Arg -> Bool #

max :: Arg -> Arg -> Arg #

min :: Arg -> Arg -> Arg #

data CompNodeInfo where Source #

Computation-term-specific node information.

Since: 1.0.0

Bundled Patterns

pattern Builtin1 :: OneArgFunc -> CompNodeInfo

A Plutus primop with one argument.

Since: 1.0.0

pattern Builtin2 :: TwoArgFunc -> CompNodeInfo

A Plutus primop with two arguments.

Since: 1.0.0

pattern Builtin3 :: ThreeArgFunc -> CompNodeInfo

A Plutus primop with three arguments.

Since: 1.0.0

pattern Lam :: Id -> CompNodeInfo

A lambda.

Since: 1.0.0

pattern Force :: Ref -> CompNodeInfo

Force a thunk back into the computation it wraps.

Since: 1.0.0

pattern Return :: Ref -> CompNodeInfo

Produce the result of a computation.

Since: 1.0.0

data ValNodeInfo where Source #

Value-term-specific node information.

Since: 1.0.0

Bundled Patterns

pattern Lit :: AConstant -> ValNodeInfo

A compile-time literal of a flat builtin type.

Since: 1.0.0

pattern App :: Id -> Vector Ref -> ValNodeInfo

An application of a computation (the Id field) to some arguments (the Vector field).

Since: 1.0.0

pattern Thunk :: Id -> ValNodeInfo

Wrap a computation into a value (essentially delaying it).

Since: 1.0.0

data ASGNode Source #

A single node in a Covenant ASG. Where appropriate, these carry their types.

Since: 1.0.0

Constructors

ACompNode (CompT AbstractTy) CompNodeInfo

A computation-typed node.

Since: 1.0.0

AValNode (ValT AbstractTy) ValNodeInfo

A value-typed node

Since: 1.0.0

AnError

An error node.

Since: 1.0.0

Instances

Instances details
Show ASGNode Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Eq ASGNode Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: ASGNode -> ASGNode -> Bool #

(/=) :: ASGNode -> ASGNode -> Bool #

Ord ASGNode Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

MonadHashCons Id ASGNode ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Functions

typeASGNode :: ASGNode -> ASGNodeType Source #

Produces the type of any ASG node.

Since: 1.0.0

ASG builder

Types

data CovenantError Source #

Any problem that might arise when building an ASG programmatically.

Since: 1.0.0

Constructors

TypeError (Bimap Id ASGNode) CovenantTypeError

There was a type error when assembling the ASG. This provides the hash-consed state up to the point of the error.

Since: 1.0.0

EmptyASG

We tried to generate an ASG with no nodes in it.

Since: 1.0.0

TopLevelError

We tried to generate as ASG whose top-level node is an error.

Since: 1.0.0

TopLevelValue (Bimap Id ASGNode) (ValT AbstractTy) ValNodeInfo

We tried to generate an ASG whose top-level node is a value.

Since: 1.0.0

Instances

Instances details
Show CovenantError Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Eq CovenantError Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

data ScopeInfo Source #

A tracker for scope-related information while building an ASG programmatically. Currently only tracks available arguments.

Important note

This is a fairly low-level type, designed specifically for ASG construction. While you can do arbitrary things with it, changing things in it outside of the functionality provided by this module is not recommended, unless you know exactly what you're doing.

Since: 1.0.0

Instances

Instances details
Show ScopeInfo Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Eq ScopeInfo Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

MonadReader ScopeInfo ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

(k ~ A_Lens, a ~ Vector (Vector (ValT AbstractTy)), b ~ Vector (Vector (ValT AbstractTy))) => LabelOptic "argumentInfo" k ScopeInfo ScopeInfo a b Source #

Gives access to the argument information for the current, and all enclosing, scopes. The 'outer' Vector is a stack of scopes, with lower indexes corresponding to closer scopes: index 0 is our scope, 1 is our enclosing scope, 2 is the enclosing scope of our enclosing scope, etc. The 'inner' Vectors are positional lists of argument types.

Since: 1.0.0

Instance details

Defined in Covenant.ASG

data ASGBuilder a Source #

A concrete monadic stack, providing the minimum amount of functionality needed to build an ASG using the combinators given in this module.

Since: 1.0.0

Instances

Instances details
Applicative ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

pure :: a -> ASGBuilder a #

(<*>) :: ASGBuilder (a -> b) -> ASGBuilder a -> ASGBuilder b #

liftA2 :: (a -> b -> c) -> ASGBuilder a -> ASGBuilder b -> ASGBuilder c #

(*>) :: ASGBuilder a -> ASGBuilder b -> ASGBuilder b #

(<*) :: ASGBuilder a -> ASGBuilder b -> ASGBuilder a #

Functor ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

fmap :: (a -> b) -> ASGBuilder a -> ASGBuilder b #

(<$) :: a -> ASGBuilder b -> ASGBuilder a #

Monad ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

(>>=) :: ASGBuilder a -> (a -> ASGBuilder b) -> ASGBuilder b #

(>>) :: ASGBuilder a -> ASGBuilder b -> ASGBuilder b #

return :: a -> ASGBuilder a #

MonadError CovenantTypeError ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

MonadReader ScopeInfo ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

MonadHashCons Id ASGNode ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

data CovenantTypeError Source #

An error that can arise during the construction of an ASG by programmatic means.

Since: 1.0.0

Constructors

BrokenIdReference Id

An Id has no corresponding node. This error should not arise under normal circumstances: the most likely explanation is that you're using an Id that was made by a different ASG builder computation.

Since: 1.0.0

ForceCompType (CompT AbstractTy)

Computation-typed nodes can't be forced, but we tried anyway.

Since: 1.0.0

ForceNonThunk (ValT AbstractTy)

Value-typed nodes that aren't thunks can't be forced, but we tried anyway.

Since: 1.0.0

ForceError

Error nodes can't be forced, but we tried anyway.

Since: 1.0.0

ThunkValType (ValT AbstractTy)

Value-typed nodes can't be thunked, but we tried anyway.

Since: 1.0.0

ThunkError

Error nodes can't be thunked, but we tried anyway.

Since: 1.0.0

ApplyToValType (ValT AbstractTy)

Arguments can't be applied to a value-typed node, but we tried anyway.

Since: 1.0.0

ApplyToError

Arguments can't be applied to error nodes, but we tried anyway.

Since: 1.0.0

ApplyCompType (CompT AbstractTy)

Computation-typed nodes can't be applied as arguments, but we tried anyway.

Since: 1.0.0

RenameFunctionFailed (CompT AbstractTy) RenameError

Renaming the function in an application failed.

Since: 1.0.0

RenameArgumentFailed (ValT AbstractTy) RenameError

Renaming an argument in an application failed.

Since: 1.0.0

UnificationError TypeAppError

We failed to unify an expected argument type with the type of the argument we were actually given.

Since: 1.0.0

NoSuchArgument DeBruijn (Index "arg")

An argument was requested that doesn't exist.

Since: 1.0.0

ReturnCompType (CompT AbstractTy)

Can't return a computation-typed node, but we tried anyway.

Since: 1.0.0

LambdaResultsInValType (ValT AbstractTy)

The body of a lambda results in a value-typed node, which isn't allowed.

Since: 1.0.0

LambdaResultsInNonReturn (CompT AbstractTy)

The body of a lambda results in a computation-typed node which isn't a return, which isn't allowed.

Since: 1.0.0

ReturnWrapsError

A lambda body's return is wrapping an error, instead of being directly an error. This should not happen under normal circumstances and is most certainly a bug.

Since: 1.0.0

ReturnWrapsCompType (CompT AbstractTy)

We tried to return a computation-typed node, but this isn't allowed.

Since: 1.0.0

WrongReturnType (ValT AbstractTy) (ValT AbstractTy)

The result of an application is not what the computation being applied expected.

First field is the expected type, the second is what we actually got.

Since: 1.0.0

data RenameError Source #

Ways in which the renamer can fail.

Since: 1.0.0

Constructors

InvalidAbstractionReference Int (Index "tyvar")

An attempt to reference an abstraction in a scope where this abstraction doesn't exist. First field is the true level, second is the index that was requested.

Since: 1.0.0

IrrelevantAbstraction

A value type specifies an abstraction that never gets used anywhere. For example, the type forall a b . [a] has b irrelevant.

Since: 1.0.0

UndeterminedAbstraction

A computation type specifies an abstraction which is not used by any argument. For example, the type forall a b . a -> !(b -> !a) has b undetermined.

Since: 1.0.0

Instances

Instances details
Show RenameError Source # 
Instance details

Defined in Covenant.Internal.Rename

Eq RenameError Source # 
Instance details

Defined in Covenant.Internal.Rename

Introducers

arg :: (MonadError CovenantTypeError m, MonadReader ScopeInfo m) => DeBruijn -> Index "arg" -> m Arg Source #

Given a scope and a positional argument index, construct that argument. Will fail if that argument doesn't exist in the specified scope, or if the specified scope doesn't exist.

Since: 1.0.0

builtin1 :: MonadHashCons Id ASGNode m => OneArgFunc -> m Id Source #

Construct a node corresponding to the given Plutus primop.

Since: 1.0.0

builtin2 :: MonadHashCons Id ASGNode m => TwoArgFunc -> m Id Source #

As builtin1, but for two-argument primops.

Since: 1.0.0

builtin3 :: MonadHashCons Id ASGNode m => ThreeArgFunc -> m Id Source #

As builtin1, but for three-argument primops.

Since: 1.0.0

force :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m) => Ref -> m Id Source #

Given a reference to a thunk, turn it back into a computation. Will fail if the reference isn't a thunk.

Since: 1.0.0

ret :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m) => Ref -> m Id Source #

Given the result of a function body (either a value or an error), construct the return for it. Will fail if that reference aims at a computation node.

Since: 1.0.0

lam :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ScopeInfo m) => CompT AbstractTy -> m Id -> m Id Source #

Given a desired type, and a computation which will construct a lambda body when executed (with the scope extended with the arguments the functions can expect), construct a lambda.

Important note

This combinator works slightly differently to the others in this module. This is required because, due to hash consing, an ASG is typically built 'bottom-up', whereas function arguments (and their scopes) are necessarily top-down. Thus, we need to 'delay' the construction of a lambda's body to ensure that proper scoped argument information can be given to it, hence why the argument being passed is an m Id.

Since: 1.0.0

err :: MonadHashCons Id ASGNode m => m Id Source #

Construct the error node.

Since: 1.0.0

lit :: MonadHashCons Id ASGNode m => AConstant -> m Id Source #

Construct a node corresponding to the given constant.

Since: 1.0.0

thunk :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m) => Id -> m Id Source #

Given an Id referring to a computation, build a thunk wrapping it. Will fail if the Id does not refer to a computation node.

Since: 1.0.0

app :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m) => Id -> Vector Ref -> m Id Source #

Given an Id referring to a computation, and a Vector of Refs to the desired arguments, construct the application of the arguments to that computation. This can fail for a range of reasons:

  • Type mismatch between what the computation expects and what it's given
  • Too many or too few arguments
  • Not a computation type for Id argument
  • Not value types for Refs

Since: 1.0.0

Elimination

runASGBuilder :: ASGBuilder a -> Either CovenantError ASG Source #

Executes an ASGBuilder to make a 'finished' ASG.

Since: 1.0.0