[m-rev.] for discussion: subtypes documentation

Mark Brown dougl at cs.mu.OZ.AU
Sun Nov 24 22:36:55 AEDT 2002


Hi,

The following diff is a draft of the subtypes documentation.  I'm not
intending to commit this yet; I'm posting this now to allow any early
review comments on the design.

A couple of notes about the diff:

	- The given syntax cannot express some subtypes that we may wish
	  to use.  For example, there is no way for the supertype to be
	  a pred or func type.  We may therefore need one or more
	  additional variants on the syntax, such as the first variant
	  in Fergus' proposal.

	- I've expounded on subtypes a little bit more in the modes
	  section, describing subtype information as being attached
	  to the and-nodes of a type tree.  That was the simplest way I
	  could find of describing the semantics of subtypes.

Index: reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.263
diff -u -r1.263 reference_manual.texi
--- reference_manual.texi	7 Nov 2002 06:14:09 -0000	1.263
+++ reference_manual.texi	24 Nov 2002 11:08:04 -0000
@@ -97,6 +97,7 @@
 * Type classes::      Constrained polymorphism.
 * Existential types:: Support for data abstraction and heterogeneous
                       collections.
+* Subtypes::          Subtypes provide a convenient way to express some modes.
 * Semantics::         Declarative and operational semantics of Mercury
                       programs.
 * Foreign language interface:: Calling code written in other programming
@@ -498,6 +499,7 @@
 pragma            fx        1199
 promise           fx        1199
 rule              fx        1199
+subtype           fx        1199
 typeclass         fx        1199
 use_module        fx        1199
 -->               xfx       1200
@@ -534,6 +536,7 @@
 :- func
 :- inst
 :- mode
+:- subtype
 :- typeclass
 :- instance
 :- pragma
@@ -550,6 +553,7 @@
 The @samp{type}, @samp{pred} and @samp{func} declarations are used for the
 type system,
 the @samp{inst} and @samp{mode} declarations are for the mode system,
+the @samp{subtype} declarations are for the type and mode systems,
 the @samp{pragma} declarations are for the C interface, and for
 compiler hints about inlining, and the remainder are for the module system. 
 They are described in more detail in their respective chapters.
@@ -1536,8 +1540,8 @@
 @chapter Types
 
 The type system is based on many-sorted logic, and supports polymorphism,
-type classes (@pxref{Type classes}), and existentially quantified types
-(@pxref{Existential types}).
+type classes (@pxref{Type classes}), existentially quantified types
+(@pxref{Existential types}), and subtypes (@pxref{Subtypes}).
 
 @menu
 * Builtin types::
@@ -2087,15 +2091,17 @@
 that can be used to construct terms of that type;
 the children of an and-node are the types
 of the arguments of the constructors.
-We attach mode information to the or-nodes of type trees.
+We attach mode information to the and-nodes and the or-nodes of type trees.
 
 An @dfn{instantiatedness tree} is an assignment
 of an @dfn{instantiatedness} --- either @dfn{free} or @dfn{bound} ---
-to each or-node of a type tree,
+to each node of a type tree,
 with the constraint that all descendants of a free node must be free.
 
 A term is @dfn{approximated by} an instantiatedness tree
-if for every node in the instantiatedness tree,
+if for every function symbol in the term
+the corresponding and-node is ``bound'',
+and for every or-node in the instantiatedness tree,
 
 @itemize @bullet
 @item
@@ -2138,10 +2144,13 @@
 The shape of these trees is determined by
 the type of the variable to which they apply.
 
-As execution proceeds, variables may become more instantiated.
+As execution proceeds, variables may become more instantiated,
+which means that the or-nodes in the type tree become more instantiated.
+An or-node that is bound is considered more instantiated than
+one that is free.
 A @dfn{mode mapping} is a mapping
 from an initial instantiatedness tree to a final instantiatedness tree,
-with the constraint that no node of the type tree
+with the constraint that no or-node of the type tree
 is transformed from bound to free.
 Mercury allows the user to specify mode mappings directly
 by expressions such as @code{inst1 >> inst2},
@@ -2174,7 +2183,8 @@
 These two modes are enough for most functions and predicates.
 Nevertheless, Mercury's mode system is sufficiently
 expressive to handle more complex data-flow patterns,
-including those involving partially instantiated data structures.  
+including those involving subtypes (@pxref{Subtypes}),
+and those involving partially instantiated data structures.  
 (The current implementation does not handle
 partially instantiated data structures yet.)
 
@@ -2472,9 +2482,13 @@
 
 
 Constrained polymorphic modes are particularly useful when passing
-objects with higher-order types to polymorphic predicates
+values with higher-order types to polymorphic predicates
 since they allow the higher-order mode information to be retained
 (@pxref{Higher-order}).
+Similarly, constrained polymorphic modes are useful when passing
+values that belong to a subtype to predicates that take a supertype,
+since they allow the subtype information to be retained
+(@pxref{Subtypes}).
 
 @node Different clauses for different modes
 @section Different clauses for different modes
@@ -5084,6 +5098,274 @@
 good_example3_univ("foo"::in(bound("foo")), univ(42)::out).
 good_example3_univ("bar"::in(bound("bar")), univ("blah")::out).
 @end example
+
+ at node Subtypes
+ at chapter Subtypes
+
+Subtype information about variables is expressed by Mercury's mode system.
+For a given or-node in an instantiatedness tree,
+the set of function symbols which may occur at that location in a term
+is specified by which of the children of the or-node are bound.
+This set does not necessarily include every function symbol
+in the corresponding type,
+since some and-nodes may be free.
+A variable's instantiatedness tree therefore describes (for first order terms)
+a subset of the values of the variable's type.
+
+To make subtypes easier to use,
+Mercury allows users to declare subtypes such as
+
+ at example
+:- subtype non_empty_list(T) < list(T) ---> [T | list(T)].
+ at end example
+
+This subtype describes a list whose top function symbol is @code{[|]/2},
+whose first argument has a subtype given by the parameter @code{T},
+and whose second argument is any list of @code{T}'s.
+If this subtype is used in an argument of a predicate or function
+declaration, the subtype information is propagated into the
+corresponding modes in a way we describe below.
+
+ at menu
+* Subtype declarations::
+* Semantics of Mercury programs with subtypes::
+* An example using subtypes::
+ at c * Abstract subtypes::
+* Higher-order subtypes::
+ at end menu
+
+ at node Subtype declarations
+ at section Subtype declarations
+
+Subtype declarations have the form
+
+ at example
+:- subtype @var{Sub} < @var{Super} ---> @var{Body}.
+ at end example
+
+ at noindent
+ at var{Sub} is a non-variable type
+whose arguments (if any) are distinct variables.
+ at var{Super} is a type or subtype.
+ at var{Body} is a sequence of constructors separated by semi-colons,
+whose arguments are types or subtypes.
+Types or subtypes in the body of the definition may be inst qualified
+using the @code{::} operator,
+provided that the specified inst is compatible with @code{ground}.
+
+Any type variable appearing in @var{Super} must also appear in @var{Sub}.
+Any type variable appearing in @var{Body} must also appear in @var{Super},
+except that anonymous variables (i.e., variables beginning with @code{_})
+are allowed to appear in the body.
+
+Circularities are not allowed, so it is an error if some part of @var{Super}
+is ultimately defined to be a subtype of @var{Sub}.
+
+The values described by a subtype are meant (for first order types)
+to be a subset of those described by the supertype.  Hence for each
+function symbol in the body of the subtype declaration there must be a
+matching function symbol in the definition of the supertype, and each
+argument of the former should in turn be a subtype of
+the corresponding argument of the latter.
+
+The only subtype of a universally quantified type variable
+is the variable itself,
+so where the supertype uses such a variable the subtype must use the
+same variable in the corresponding location.
+Similarly, where the supertype uses an existentially quantified type variable
+the subtype must use an anonymous type variable in the corresponding location.
+Existential quantifiers and class constraints are always implicitly
+determined from the supertype, and should not be explicitly given.
+
+ at node Semantics of Mercury programs with subtypes
+ at section Semantics of Mercury programs with subtypes
+
+For every subtype we define a type, the @dfn{base type},
+which is the type used internally to represent values of the subtype,
+and an inst, the @dfn{base inst},
+which encompasses the subtype information about values of the subtype.
+
+The base type is determined by treating each subtype declaration
+
+ at example
+:- subtype @var{Sub} < @var{Super} ---> @var{Body}.
+ at end example
+
+ at noindent
+as if it is the equivalence type declaration
+
+ at example
+:- type @var{Sub} == @var{Super}.
+ at end example
+
+ at noindent
+and expanding out all of these equivalences in the usual way.
+
+The base inst is defined on the type tree of the base type.
+Consider the subtype at the root or-node of the type tree:
+
+ at itemize @bullet
+ at item
+If it is an anonymous variable (which is allowed in subtype definitions),
+the inst is ground.  That is, every node in the type tree maps to bound.
+
+ at item
+If it is inst qualified (which is allowed in subtype definitions),
+then the subtype information on the left hand side
+is propagated into the inst on the right hand side
+to form the base inst of the qualified type.
+The propagation of a subtype into an inst is described below.
+
+ at item
+If it is defined by a subtype declaration or a discriminated union type
+(modulo equivalence) then the root or-node maps to bound,
+and for each function symbol in the type or subtype definition
+the corresponding and-node maps to bound,
+and the children of this and-node are
+the base insts of the arguments of the function symbol.
+All other and-nodes (if any) map to free.
+
+ at item
+If it is defined by an abstract type ...
+
+XXX I suppose we will have to treat this as ground, which will ignore
+any subtype information in arguments of the type.
+
+ at item
+If it is a pred or func type, the base inst is just the subtype itself.
+This is not a valid Mercury inst, so attempting to use it directly
+will result in an error.
+However, if a base inst like this is propagated into another inst,
+as described below, then a valid inst may result
+and using this resulting inst would therefore not be a problem.
+
+ at item
+If it is a tuple type @code{@{@}/N}, it is treated as
+a discriminated union type with the single function symbol @code{@{@}/N}.
+
+ at item
+Other built-in types map to ground.
+
+ at end itemize
+
+A subtype constructor can be used in some, but not all,
+of the places where it is legal to use a type constructor.
+Subtypes are allowed in predicate and function declarations,
+in method declarations in the ``where'' part of typeclass declarations,
+and in the bodies and supertypes of subtype declarations.
+Subtypes are not allowed anywhere else;
+in particular, they are not allowed to be used in the definition
+of ordinary types (i.e., those defined with a @code{type} declaration),
+or on the right hand side of a @code{with_type} qualifier in a goal.
+
+Using a subtype in a predicate or function declaration has two effects,
+one on the type of the argument and one on each mode of the argument.
+In the type, an occurrence of a subtype constructor
+is replaced by the base type,
+and each argument of the constructor is substituted into the base type
+in the appropriate places.
+In each mode, the base inst is propagated into the initial and final insts,
+so that the new mode contains the information from both the existing mode
+as well as the subtype.
+The propagation of a base inst into an existing inst can be described by
+showing the effect on each node of the type tree.
+
+For or-nodes, the new inst is usually the same as the existing inst.
+There are two exceptions.
+First, if the existing inst is a (constrained) variable
+and the subtype is a non-variable,
+then the base inst is propagated into the variable's constraint.
+Second, if the existing inst is a higher-order pred or func inst
+and the subtype is a higher-order pred or func type,
+then the base inst for each argument (and possibly return value)
+is propagated into the argument's mode in the existing inst,
+and the existing determinism remains unchanged.
+See @ref{Higher-order subtypes} for further details.
+
+For and-nodes, the new inst is given by the following table:
+
+ at example
+        base inst         existing inst       new inst
+
+        free              free                free
+        bound             free                free
+        free              bound               free
+        bound             bound               bound
+ at end example
+
+ at node An example using subtypes
+ at section An example using subtypes
+
+ at c XXX
+
+ at c @node Abstract subtypes
+ at c @section Abstract subtypes
+ at c
+ at c We don't support abstract subtypes yet.  They won't be supported
+ at c unless/until abstract insts are supported.
+ at c
+
+ at node Higher-order subtypes
+ at section Higher-order subtypes
+
+As stated earlier, the subtype relation on first-order types
+is the same as the subset relation.
+For higher-order types, the subtype relation is slightly more complex.
+We extend the relation to higher-order types with the following two cases.
+
+ at itemize @bullet
+ at item
+A type @code{func(@var{S1}, @dots{}, @var{SN}) = @var{S}}
+is a subtype of @code{func(@var{T1}, @dots{}, @var{TN}) = @var{T}}
+iff @var{S} is a subtype of @var{T},
+and for each argument @var{i}, @var{Si} is a subtype of @var{Ti}.
+
+ at item
+A type @code{pred(@var{S1}, @dots{}, @var{SN})}
+is a subtype of @code{pred(@var{T1}, @dots{}, @var{TN})}
+iff for each argument @var{i}, @var{Si} is a subtype of @var{Ti}.
+
+ at end itemize
+
+ at noindent
+In other words the subtype relation on predicate and function types
+is @emph{covariant} in the argument values
+and (for function types) the return values.
+ at c This is in contrast to the usual object-oriented view of subtypes,
+ at c where inputs are contravariant and outputs are covariant.  We use
+ at c covariant subtypes because they work much better with parametric
+ at c polymorphism.
+Mercury's mode system provides enough information for the compiler
+to statically check that the use of covariant subtypes is safe.
+
+An inst qualifier can be used in a subtype definition
+to give more information about a predicate or function type
+than just the subtype of each argument.
+For example, the qualifier may specify the determinism of a function
+or predicate, or the uniqueness of its arguments.
+If a predicate or function type @var{S} is to be a subtype of @var{T},
+then any extra information must be identical in both @var{S} and @var{T}.
+Hence
+
+ at example
+pred(S) :: pred(out) is det
+ at end example
+
+cannot be a subtype of
+
+ at example
+pred(T) :: pred(out) is multi
+ at end example
+
+even if @var{S} is a subtype of @var{T},
+because the determinisms are not identical.
+Similarly, if a pred or func type is propagated into a pred or func inst,
+the determinism, uniqueness and freeness information must match exactly;
+if they don't match it is a mode error.
+
+Here is an example using higher-order subtypes ...
+
+ at c XXX
 
 @node Semantics
 @chapter Semantics
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list