rzk-0.11.3: An experimental proof assistant for synthetic ∞-categories
Safe HaskellNone
LanguageHaskell2010

Language.Rzk.Foil.Names

Description

Surface names, binders and modalities.

These are what the checker shows the user, and they are independent of how a term represents its variables: a VarIdent is a surface identifier (with the position of its defining occurrence), and a Binder records the names a binder introduces — including a pair pattern, which still binds exactly one variable whose components are projections of it.

Synopsis

Documentation

markUnresolved :: VarIdent -> VarIdent Source #

An identifier that is not in scope becomes a hole under a marked name.

A free-foil term refers to a variable by name, and an unresolved identifier has none — so the term cannot represent it. Elaboration marks it instead, and the checker reports it when it reaches it, which is what keeps the error where the identifier was used (inside the binders and topes it was written under) rather than at the top of the declaration.

The marker cannot be mistaken for a hole the user wrote: the grammar forbids # in an identifier.

type Display = (VarIdent, Binder) Source #

What a bound name is shown as: the display name standing for the variable itself, and the (freshened) binder, which gives the pattern to print and the component names to fold projections back to.

data TypeInfo term Source #

The annotation on every node of a typed term: its type, plus its memoised weak head and normal forms.

Constructors

TypeInfo 

Fields

Instances

Instances details
Functor TypeInfo Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Methods

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

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

Foldable TypeInfo Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Methods

fold :: Monoid m => TypeInfo m -> m #

foldMap :: Monoid m => (a -> m) -> TypeInfo a -> m #

foldMap' :: Monoid m => (a -> m) -> TypeInfo a -> m #

foldr :: (a -> b -> b) -> b -> TypeInfo a -> b #

foldr' :: (a -> b -> b) -> b -> TypeInfo a -> b #

foldl :: (b -> a -> b) -> b -> TypeInfo a -> b #

foldl' :: (b -> a -> b) -> b -> TypeInfo a -> b #

foldr1 :: (a -> a -> a) -> TypeInfo a -> a #

foldl1 :: (a -> a -> a) -> TypeInfo a -> a #

toList :: TypeInfo a -> [a] #

null :: TypeInfo a -> Bool #

length :: TypeInfo a -> Int #

elem :: Eq a => a -> TypeInfo a -> Bool #

maximum :: Ord a => TypeInfo a -> a #

minimum :: Ord a => TypeInfo a -> a #

sum :: Num a => TypeInfo a -> a #

product :: Num a => TypeInfo a -> a #

Traversable TypeInfo Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Methods

traverse :: Applicative f => (a -> f b) -> TypeInfo a -> f (TypeInfo b) #

sequenceA :: Applicative f => TypeInfo (f a) -> f (TypeInfo a) #

mapM :: Monad m => (a -> m b) -> TypeInfo a -> m (TypeInfo b) #

sequence :: Monad m => TypeInfo (m a) -> m (TypeInfo a) #

ZipMatchK TypeInfo Source #

The annotation is ignored in matching, so two terms differing only in their types are α-equivalent. The ZipMatchK API makes an annotation holding terms construct its result through the mapping, so it cannot be dropped from the match — but it is made lazy: infoType below is a thunk never forced, because AnnSigs Bifoldable does not visit the annotation. So the 30-deep universe tower inside a type is never walked. The memoised forms are dropped (every consumer of the zipped result discards them). This is the annotation-blind pattern from the Annotated haddock.

Instance details

Defined in Language.Rzk.Foil.Syntax

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> (TypeInfo :@@: as) -> (TypeInfo :@@: bs) -> Maybe (TypeInfo :@@: cs) #

newtype VarIdent Source #

Constructors

VarIdent 

Instances

Instances details
IsString VarIdent Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Show VarIdent Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Eq VarIdent Source #

Identifiers are equal when they are spelled the same, whatever their source positions.

Written out rather than (==) `on` (void . getVarIdent), which allocated a position-free copy of the whole syntax node and compared that: identifier equality is on the hot path (every name lookup, every refreshing of a display name, every match of two terms that mention a hole), and profiling put it at 6% of the checker's time.

Instance details

Defined in Language.Rzk.Foil.Names

Ord VarIdent Source #

Identifiers are ordered by name, ignoring the source position, so that the order agrees with Eq. Only used to key identifiers in a set or a map.

Instance details

Defined in Language.Rzk.Foil.Names

ZipMatchK VarIdent Source # 
Instance details

Defined in Language.Rzk.Foil.Syntax

Methods

zipMatchWithK :: forall (as :: LoT Type) (bs :: LoT Type) (cs :: LoT Type). Mappings as bs cs -> (VarIdent :@@: as) -> (VarIdent :@@: bs) -> Maybe (VarIdent :@@: cs) #

ZipMatchK (Maybe VarIdent) Source #

A hole's name is a whole field (HoleF), so it is matched as a constant rather than through the Maybe functor.

Instance details

Defined in Language.Rzk.Foil.Syntax

Methods

zipMatchWithK :: forall (as :: LoT Type) (bs :: LoT Type) (cs :: LoT Type). Mappings as bs cs -> (Maybe VarIdent :@@: as) -> (Maybe VarIdent :@@: bs) -> Maybe (Maybe VarIdent :@@: cs) #

holeName :: Text -> Maybe VarIdent Source #

The display name of a hole from its surface token text. The token includes the leading ?; an anonymous hole (bare ?) has no name.

holeIdentToken :: Maybe VarIdent -> Text Source #

The surface token text (including the leading ?) for a hole name.

data Binder Source #

The name(s) a binder introduces. A binder may name a single (possibly anonymous) variable, or destructure a pair/tuple via a pattern. The pattern structure is kept around purely so that goals, holes and error messages can show the user's original names (e.g. t and s for \ (t , s) -> …) instead of projections of a fresh variable (e.g. π₁ x₄ and π₂ x₄).

Operationally a pair pattern still binds a single variable; the components are projections of it (see toScopePattern). Binder only records the names so they can be restored when rendering.

Constructors

BinderVar (Maybe VarIdent)

a single variable (Nothing for _)

BinderPair Binder Binder

a pair pattern (l , r)

BinderUnit

the unit pattern unit

Instances

Instances details
Eq Binder Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Methods

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

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

ZipMatchK Binder Source # 
Instance details

Defined in Language.Rzk.Foil.Syntax

Methods

zipMatchWithK :: forall (as :: LoT Type) (bs :: LoT Type) (cs :: LoT Type). Mappings as bs cs -> (Binder :@@: as) -> (Binder :@@: bs) -> Maybe (Binder :@@: cs) #

binderName :: Binder -> Maybe VarIdent Source #

The single name of a binder, if it binds exactly one named variable. A pair/unit pattern has no single name, so this is Nothing for them. Used wherever the old Maybe VarIdent binder name is still sufficient.

data TModality Source #

Constructors

Sharp 
Flat 
Op 
Id 

Instances

Instances details
Show TModality Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Eq TModality Source # 
Instance details

Defined in Language.Rzk.Foil.Names

ModeTheory TModality Source # 
Instance details

Defined in Rzk.TypeCheck.Context

ZipMatchK TModality Source #

Matching the non-recursive fields of the signature.

A modality and a hole's name are part of the term: they must agree. A Binder is not: it records the names a binder introduces, purely so that goals and error messages can show the user's own names, and two terms that differ only in them are the same term. The old representation compared them (its Eq was derived), so x -> x and y -> y compared unequal; on the new one they are α-equivalent, as they should be.

Instance details

Defined in Language.Rzk.Foil.Syntax

Methods

zipMatchWithK :: forall (as :: LoT Type) (bs :: LoT Type) (cs :: LoT Type). Mappings as bs cs -> (TModality :@@: as) -> (TModality :@@: bs) -> Maybe (TModality :@@: cs) #

desugarTuple :: BNFC'Position -> [Pattern] -> Pattern -> Pattern -> Pattern Source #

A tuple pattern is sugar for nested pairs.

flattenBinderApp :: Term -> [Term] Source #

Split a binder term into the individual variables it names. A multi-variable binder like (x y : A) is parsed as the application spine x y; this returns [x, y] so each can become its own nested binder. A single binder term (a variable, a pair pattern, …) is returned unchanged as a singleton.

data Proj Source #

A projection step: first (π₁) or second (π₂) component.

Constructors

PFst 
PSnd 

Instances

Instances details
Eq Proj Source # 
Instance details

Defined in Language.Rzk.Foil.Names

Methods

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

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

binderToPattern :: Binder -> Pattern Source #

Render a Binder as a surface pattern (used to display the binder itself, e.g. (t , s)). Anonymous variables become _.

binderDisplayName :: Binder -> VarIdent Source #

A VarIdent that prints as the binder's surface pattern, e.g. (t , s). Used to display a pattern binder in a hole's local context as the pattern itself rather than as the underlying single variable.

binderPaths :: Binder -> [([Proj], VarIdent)] Source #

The named leaves of a binder, each paired with the projection path that reaches it from the bound variable. For example (t , (a , b)) yields [([PFst], t), ([PSnd, PFst], a), ([PSnd, PSnd], b)].

binderLeaves :: Binder -> [VarIdent] Source #

The names appearing in a binder.

binderIsCompound :: Binder -> Bool Source #

Does this binder destructure a pair/tuple (as opposed to naming a single variable or _)?

freshenBinderLeaves :: [VarIdent] -> Binder -> Binder Source #

Refresh the named leaves of a binder so they avoid the given names (and one another). Anonymous leaves and the unit pattern are left unchanged.

defaultVarIdents :: [VarIdent] Source #

Decompose a chain of projections applied to a variable into the projection path from the variable outwards, matching binderPaths. The outermost projection is applied last, so it goes at the end of the path: e.g. π₂ (π₁ x) (select π₁ first, then π₂) becomes Just ([PFst, PSnd], x).

>>> :set -XOverloadedStrings
>>> import qualified Data.Text as T
>>> import qualified Data.Set as Set

refreshVar :: [VarIdent] -> VarIdent -> VarIdent Source #

Given a list of used variable names in the current context, generate a unique fresh name based on a given one.

>>> print $ refreshVar ["x", "y", "x₁", "z"] "x"
x₂

refreshVarIn :: Set VarIdent -> VarIdent -> VarIdent Source #

Refresh a name against a set of taken ones.

The list version above is O(taken) per call, and naming a whole context calls it once per entry, which made reading the naming off a context with every top-level definition of a project in it quadratic.

>>> print $ refreshVarIn (Set.fromList ["x", "y", "x₁", "z"]) "x"
x₂

freshenBinderLeavesIn :: Set VarIdent -> Binder -> Binder Source #

freshenBinderLeaves against a set of taken names, for the same reason refreshVarIn exists beside refreshVar.

incIndex :: Text -> Text Source #

Increment the subscript number at the end of the indentifier.

>>> putStrLn $ T.unpack $ incIndex "x"
x₁
>>> putStrLn $ T.unpack $ incIndex "x₁₉"
x₂₀