From 9f8d71163896a8683a694e5e0f130f893a6d621c Mon Sep 17 00:00:00 2001 From: Iavor Diatchki Date: Fri, 10 Jun 2022 15:38:25 -0700 Subject: [PATCH] Add some documentation about the module system --- docs/RefMan/BasicSyntax.rst | 11 +- docs/RefMan/Modules.rst | 450 +++++++++++++----- .../_build/doctrees/BasicSyntax.doctree | Bin 45069 -> 45261 bytes docs/RefMan/_build/doctrees/Modules.doctree | Bin 32406 -> 53135 bytes .../RefMan/_build/doctrees/environment.pickle | Bin 109593 -> 113537 bytes docs/RefMan/_build/html/BasicSyntax.html | 8 +- docs/RefMan/_build/html/Modules.html | 443 +++++++++++++---- docs/RefMan/_build/html/RefMan.html | 14 +- .../_build/html/_sources/BasicSyntax.rst.txt | 11 +- .../_build/html/_sources/Modules.rst.txt | 450 +++++++++++++----- docs/RefMan/_build/html/objects.inv | Bin 352 -> 389 bytes docs/RefMan/_build/html/searchindex.js | 2 +- docs/chop.hs | 4 +- 13 files changed, 1053 insertions(+), 340 deletions(-) diff --git a/docs/RefMan/BasicSyntax.rst b/docs/RefMan/BasicSyntax.rst index 6486da62..90e31090 100644 --- a/docs/RefMan/BasicSyntax.rst +++ b/docs/RefMan/BasicSyntax.rst @@ -94,6 +94,8 @@ not be used for programmer defined names: private include module + submodule + interface newtype pragma property @@ -117,11 +119,10 @@ not be used for programmer defined names: .. code-block:: none :caption: Keywords - else include property let infixl parameter - extern module then import infixr constraint - if newtype type as infix down - private pragma where hiding primitive by - + as extern include interface parameter property where + by hiding infix let pragma submodule else + constraint if infixl module primitive then + down import infixr newtype private type The following table contains Cryptol's operators and their associativity with lowest precedence operators first, and highest diff --git a/docs/RefMan/Modules.rst b/docs/RefMan/Modules.rst index 540e12bf..4d694e5e 100644 --- a/docs/RefMan/Modules.rst +++ b/docs/RefMan/Modules.rst @@ -196,7 +196,7 @@ It is good practice to place such declarations in *private blocks*: The private block only needs to be indented if it might be followed by additional public declarations. If all remaining declarations are to be -private then no additional indentation is needed as the `private` block will +private then no additional indentation is needed as the ``private`` block will extend to the end of the module. .. code-block:: cryptol @@ -238,139 +238,373 @@ is equivalent to the previous one: helper2 = 3 +Nested Modules +-------------- + +Module may be declared withing other modules, using the ``submodule`` keword. + +.. code-block:: cryptol + :caption: Declaring a nested module called N + + module M where + + x = 0x02 + + submodule N where + y = x + 2 + +Submodules may refer to names in their enclosing scope. +Declarations in a sub-module will shadow names in the outer scope. + +Declarations in a submdule may be imported with ``import submodule``, +which works just like an ordinary import except that ``X`` refers +to the name of a submodule. + + +.. code-block:: cryptol + :caption: Using declarations from a submodule. + + module M where + + x = 0x02 + + submodule N where + y = x + 2 + + import submodule N as P + + z = 2 * P::y + +Note that recursive definitions across modules are not allowed. +So, in the previous example, it would be an error if ``y`` was +to try to use ``z`` in its definition. + + + +Implicit Imports +~~~~~~~~~~~~~~~~ + +For convenience, we add an implicit qualified submodule import for +each locally defined submodules. + +.. code-block:: cryptol + :caption: Making use of the implicit import for a submodule. + + module M where + + x = 0x02 + + submodule N where + y = x + 2 + + z = 2 * N::y + +``N::y`` works in the previous example because Cryptol added +an implicit import ``import submoulde N as N``. + + +Managing Module Names +~~~~~~~~~~~~~~~~~~~~~ + +The names of nested modules are managed by the module system just +like the name of any other declaration in Cryptol. Thus, nested +modules may declared in the public or private sections of their +containing module, and need to be imported before they can be used. +Thus, to use a submodule defined in top-level module ``A`` into +another top-level module ``B`` requires two steps: + + 1. First we need to import ``A`` to bring the name of the submodule in scope + 2. Then we need to import the submodule to bring the names defined in it in scope. + +.. code-block:: cryptol + :caption: Using a nested module from a different top-level module. + + module A where + + x = 0x02 + + submodule N where + y = x + 2 + + module B where + import A // Brings `N` in scope + import submodule N // Brings `y` in scope + z = 2 * y + Parameterized Modules --------------------- -.. warning:: - This section documents the current design, but we are in the process of - redesigning some aspects of the parameterized modules mechanism. +Interface Modules +~~~~~~~~~~~~~~~~~ + +An *interface module* describes the content of a module +without providing a concrete implementation. .. code-block:: cryptol + :caption: An interface module. + + interface module I where + + type n : # // `n` is a numeric type + + type constraint (fin n, n >= 1) + // Assumptions about the declared numeric type + + x : [n] // A declarations of a constant + +Like other modules, interfaces modules may be nested in +other modules: + +.. code-block:: cryptol + :caption: A nested interface module module M where - parameter - type n : # // `n` is a numeric type parameter + interface submodule I where + type n : # // `n` is a numeric type + + type constraint (fin n, n >= 1) + // Assumptions about the declared numeric type + + x : [n] // A declarations of a constant + + +Importing an Interface Module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A module may be parameterized by importing an interface, +instead of a concrete module + +.. code-block:: cryptol + :caption: A parameterized module + + // The interface desribes the parmaeters + interface module I where + type n : # type constraint (fin n, n >= 1) - // Assumptions about the parameter - - x : [n] // A value parameter - - // This definition uses the parameters. - f : [n] - f = 1 + x + x : [n] -Named Module Instantiations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // This module is parameterized + module F where + import interface I -One way to use a parameterized module is through a named instantiation: + y : [n] + y = x + 1 + +To import a nested interface use ``import interface sumbodule I`` +and make sure that ``I`` is in scope. + +It is also possible to import multiple interface modules, +or the same interface module more than once. Each import +of an interface module maybe be linked to a different concrete +module, as described in :ref:`instantiating_modules`. + + +.. code-block:: cryptol + :caption: Multiple interface parameters + + interface module I where + type n : # + type constraint (fin n, n >= 1) + x : [n] + + + module F where + import interface I as I + import interface I as J + + y : [I::n] + y = I::x + 1 + + z : [J::n] + z = J::x + 1 + + +Interface Constraints +~~~~~~~~~~~~~~~~~~~~~ + +When working with multiple interfaces, it is to useful +to be able to impose additional constraints on the +types imported from the interface. + +.. code-block:: cryptol + :caption: Adding constraints to interface parameters + + interface module I where + type n : # + type constraint (fin n, n >= 1) + x : [n] + + + module F where + import interface I as I + import interface I as J + + interface constraint (I::n == J::n) + + y : [I::n] + y = I::x + J::x + +In this example we impose the constraint that ``n`` +(the width of ``x``) in both interfaces must be the +same. Note that, of course, the two instantiations +may provide different values for ``x``. + + +.. _instantiating_modules: + + +Instantiating a Parameterized Module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use a parameterized module we need to provide concrete +implementations for the interfaces that it uses, and provide +a name for the resulting module. This is done as follows: + +.. code-block:: cryptol + :caption: Instantiating a parameterized module using a single interface. + + interface module I where + type n : # + type constraint (fin n, n >= 1) + x : [n] + + module F where + import interface I + + y : [n] + y = x + 1 + + module Impl where + type n = 8 + x = 26 + + module MyF = F { Impl } + +Here we defined a new module called ``MyF`` which is +obtained by filling in module ``Impl`` for the interface +used by ``F``. + +If a module is parameterized my multiple interfaces +we need to provide an implementation module for each +interface, using a slight variation on the previous notation. + +.. code-block:: cryptol + :caption: Instantiating a parameterized module by name. + + // I is defined as above + + module F where + import interface I as I + import interface I as J + + interface constraint (I::n == J::n) + + y : [I::n] + y = I::x + J::x + + module Impl1 where + type n = 8 + x = 26 + + module Impl2 where + type n = 8 + x = 30 + + module MyF = F { I = Impl1, J = Impl 2 } + +Each interface import is identified by its name, +which is derived from the ``as`` clause on the +interface import. If there is no ``as`` clause, +then the name of the parameter is derived from +the name of the interface itself. + +Since interfaces are identified by name, the +order in which they are provided is not important. + +Modules defined by instantiation may be nested, +just like any other module: + +.. code-block:: cryptol + :caption: Nested module instantiation. + + module M where + + import Somewhere // defines G + + submodule F = submodule G { I } + +In this example, ``submodule F`` is defined +by instantiating some other parameterized +module ``G``, presumably imported from ``Somewhere``. +Note that in this case the argument to the instantiation +``I`` is a top-level module, because it is not +preceded by the ``submodule`` keyword. + + +Anonymous Interface Modules +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If we need to just parameterize a module by a couple of types/values, +it is quite cumbersome to have to define a whole separate interface module. +To make this more convenient we provide the following notation for defining +an anonymous interface and using it straight away: + +.. code-block:: cryptol + :caption: Simple parameterized module. + + module M where + + parameter + type n : # + type constraint (fin n, n >= 1) + x : [n] + + f : [n] + f = 1 + x + +The ``parameter`` block defines an interface module and uses it. +Note that the parameters may not use things defined in ``M`` as +the interface is declared outside of ``M``. + + +Anonymous Instantiation Arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes it is also a bit cumbersome to have to define a whole +separate module just to pass it as an argument to some parameterized +module. To make this more convenient we support the following notion +for instantiation a module: .. code-block:: cryptol // A parameterized module module M where - parameter - type n : # - x : [n] - y : [n] + parameter + type n : # + x : [n] + y : [n] - f : [n] - f = x + y + f : [n] + f = x + y // A module instantiation - module N = M where + module N = M + where + type n = 32 + x = 11 + y = helper - type n = 32 - x = 11 - y = helper - - helper = 12 - -The second module, ``N``, is computed by instantiating the parameterized -module ``M``. Module ``N`` will provide the exact same definitions as ``M``, -except that the parameters will be replaced by the values in the body -of ``N``. In this example, ``N`` provides just a single definition, ``f``. - -Note that the only purpose of the body of ``N`` (the declarations -after the ``where`` keyword) is to define the parameters for ``M``. - - -Parameterized Instantiations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is possible for a module instantiation to be itself parameterized. -This could be useful if we need to define some of a module's parameters -but not others. - -.. code-block:: cryptol - - // A parameterized module - module M where - - parameter - type n : # - x : [n] - y : [n] - - f : [n] - f = x + y - - - // A parameterized instantiation - module N = M where - - parameter - x : [32] - - type n = 32 - y = helper - - helper = 12 - -In this case ``N`` has a single parameter ``x``. The result of instantiating -``N`` would result in instantiating ``M`` using the value of ``x`` and ``12`` -for the value of ``y``. - - -Importing Parameterized Modules -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is also possible to import a parameterized module without using -a module instantiation: - -.. code-block:: cryptol - - module M where - - parameter - x : [8] - y : [8] - - f : [8] - f = x + y - -.. code-block:: cryptol - - module N where - - import `M - - g = f { x = 2, y = 3 } - -A *backtick* at the start of the name of an imported module indicates -that we are importing a parameterized module. In this case, Cryptol -will import all definitions from the module as usual, however every -definition will have some additional parameters corresponding to -the parameters of a module. All value parameters are grouped in a record. - -This is why in the example ``f`` is applied to a record of values, -even though its definition in ``M`` does not look like a function. + helper = 12 +The declarations in the ``where`` block are treated as the +definition of an anonymous module which is passed as the argument +to parameterized module ``M``. diff --git a/docs/RefMan/_build/doctrees/BasicSyntax.doctree b/docs/RefMan/_build/doctrees/BasicSyntax.doctree index 19a264ceb2496aa3c86cd91c9f0333a32575cbc7..f8dbc64c3b12d5fe10be31a1606d9247d4b4672a 100644 GIT binary patch delta 1819 zcmdUwZA@Eb6vsKGPk}~04Ch>;k`m*1Stb<~Bu*S;o5A4bP{Ifzmi9s~_RZVd7LWy) zju9N)<|*!lkx^l4jIfNy8GJ#7Y-AyBnNAl!m`$TI(PeA8h(W*T>2urb{Gi|bU_bP^ z|KItad(Ly7C%Hr48qR)aF!r+H`4h&nHL!&1*R<#O11)Z^BjA$EvPYGaR+}Be`CXWs zpYd;o1yHfBpcw*qvLM_Oa^BHyNl!})v^XmY`yx9c1x~iT2GY`Oe#_r}QU{grXh`*!b5?bw~^w|`fTOy=IeTvs7DQc&tLQYAM%q>Yp%ptf_cF3MK%_4hRM^nU6kD6yrW1Ytf=DjEWVU-fepRv2JT#ZwN-OpiuI$k!rRVw-*)6MbFxj>0lssmK zHJ3 zZ38wy@N0ra_*6+ysAZv+OO{{|uirnx2FX#5m1TFMwK4~h&1Tr%7Z~cx>AG> zmhLvNFqsag5N;?R6y(ND#Kiw7f5m9pN5&k6w$eg;zhY3xX-z7R#!X1kFEsh;hM#9_tN`zXjin9Y0s}*YX#vmNvdpF(%a0n+iO|U~0nx>GI_ixTh zhY{RY{W=>V_%MFHC9%&;{G^)kw#PldMhQ0xJXVv9<{FP6;RNAhHO6#ylnhhJybQds zRTboRTv1zu!6)M^O7SvMRy?xJ2T`6~J7r+w1Vh5|^V2Gf^X9rQfgK|l6R@Q|XiBL3 zti)V+#`d28-sbU!dVqJZy734c=RY=X0n;>jCWQy>O_rgw>6)2Q6s%@Q&j zw>h)}T=`s#y+>r7PD*S$1$jaz-`iqrhCFVafPFxaA)U?87AOA#Jztpb6v@dcOGP>wUkJ|1ds=lIc3hY`->od=8Yv2H(n#Xsz> zG0>9PGs57q;1^zg5w7s9yCMc!e%LKBh!MA9*N_i>;a7(gpyk=UvzhQa@i8#)*@JZC z27cS&j&v~d@Mx|PvN1fmnxBsDF&J(I@!Fje4X_HonHZ=4-eV`Jm(n-h%%U&YrQ^ka E0>?*c!T)>LyjH*fPMt4(`rwhuLMJ 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 literal 32406 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 atR-*e@gDt{83#cM1PG+uBpao>Joo>ylZLVY diff --git a/docs/RefMan/_build/doctrees/environment.pickle b/docs/RefMan/_build/doctrees/environment.pickle index 1cddc950852ebab8731783ae4bdc3afad117f33a..62c0616e6a98aee11ee4e0daddc4d61df34e9e51 100644 GIT binary patch literal 113537 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 DdJPg1 literal 109593 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 diff --git a/docs/RefMan/_build/html/BasicSyntax.html b/docs/RefMan/_build/html/BasicSyntax.html index ca22cae8..b919ea8e 100644 --- a/docs/RefMan/_build/html/BasicSyntax.html +++ b/docs/RefMan/_build/html/BasicSyntax.html @@ -152,10 +152,10 @@ names (see

-
else       include    property    let       infixl       parameter
-extern     module     then        import    infixr       constraint
-if         newtype    type        as        infix        down
-private    pragma     where       hiding    primitive    by
+
as              extern      include      interface      parameter      property      where
+by              hiding      infix        let            pragma         submodule     else
+constraint      if          infixl       module         primitive      then
+down            import      infixr       newtype        private        type
 
diff --git a/docs/RefMan/_build/html/Modules.html b/docs/RefMan/_build/html/Modules.html index 0edb5ab2..8766421e 100644 --- a/docs/RefMan/_build/html/Modules.html +++ b/docs/RefMan/_build/html/Modules.html @@ -51,10 +51,18 @@
  • Private Blocks
  • +
  • Nested Modules +
  • Parameterized Modules
  • @@ -262,7 +270,7 @@ It is good practice to place such declarations in private blocks:

    The private block only needs to be indented if it might be followed by additional public declarations. If all remaining declarations are to be -private then no additional indentation is needed as the private block will +private then no additional indentation is needed as the private block will extend to the end of the module.

    Private blocks
    @@ -303,121 +311,348 @@ is equivalent to the previous one:

    -
    -

    Parameterized Modules

    -
    -

    Warning

    -

    This section documents the current design, but we are in the process of -redesigning some aspects of the parameterized modules mechanism.

    -
    +
    +

    Nested Modules

    +

    Module may be declared withing other modules, using the submodule keword.

    +
    +
    Declaring a nested module called N
    module M where
     
    -parameter
    -  type n : #              // `n` is a numeric type parameter
    +  x = 0x02
     
    -  type constraint (fin n, n >= 1)
    -    // Assumptions about the parameter
    -
    -  x : [n]                 // A value parameter
    -
    -// This definition uses the parameters.
    -f : [n]
    -f = 1 + x
    +  submodule N where
    +    y = x + 2
     
    -
    -

    Named Module Instantiations

    -

    One way to use a parameterized module is through a named instantiation:

    +
    +

    Submodules may refer to names in their enclosing scope. +Declarations in a sub-module will shadow names in the outer scope.

    +

    Declarations in a submdule may be imported with import submodule, +which works just like an ordinary import except that X refers +to the name of a submodule.

    +
    +
    Using declarations from a submodule.
    +
    module M where
    +
    +  x = 0x02
    +
    +  submodule N where
    +    y = x + 2
    +
    +  import submodule N as P
    +
    +  z = 2 * P::y
    +
    +
    +
    +

    Note that recursive definitions across modules are not allowed. +So, in the previous example, it would be an error if y was +to try to use z in its definition.

    +
    +

    Implicit Imports

    +

    For convenience, we add an implicit qualified submodule import for +each locally defined submodules.

    +
    +
    Making use of the implicit import for a submodule.
    +
    module M where
    +
    +  x = 0x02
    +
    +  submodule N where
    +    y = x + 2
    +
    +  z = 2 * N::y
    +
    +
    +
    +

    N::y works in the previous example because Cryptol added +an implicit import import submoulde N as N.

    +
    +
    +

    Managing Module Names

    +

    The names of nested modules are managed by the module system just +like the name of any other declaration in Cryptol. Thus, nested +modules may declared in the public or private sections of their +containing module, and need to be imported before they can be used. +Thus, to use a submodule defined in top-level module A into +another top-level module B requires two steps:

    +
    +
      +
    1. First we need to import A to bring the name of the submodule in scope

    2. +
    3. Then we need to import the submodule to bring the names defined in it in scope.

    4. +
    +
    +
    +
    Using a nested module from a different top-level module.
    +
    module A where
    +
    +  x = 0x02
    +
    +  submodule N where
    +    y = x + 2
    +
    +module B where
    +  import A            // Brings `N` in scope
    +  import submodule N  // Brings `y` in scope
    +  z = 2 * y
    +
    +
    +
    +
    +
    +
    +

    Parameterized Modules

    +
    +

    Interface Modules

    +

    An interface module describes the content of a module +without providing a concrete implementation.

    +
    +
    An interface module.
    +
    interface module I where
    +
    +  type n : #      // `n` is a numeric type
    +
    +  type constraint (fin n, n >= 1)
    +                  // Assumptions about the declared numeric type
    +
    +  x : [n]         // A declarations of a constant
    +
    +
    +
    +

    Like other modules, interfaces modules may be nested in +other modules:

    +
    +
    A nested interface module
    +
    module M where
    +
    +  interface submodule I where
    +
    +    type n : #      // `n` is a numeric type
    +
    +    type constraint (fin n, n >= 1)
    +                    // Assumptions about the declared numeric type
    +
    +    x : [n]         // A declarations of a constant
    +
    +
    +
    +
    +
    +

    Importing an Interface Module

    +

    A module may be parameterized by importing an interface, +instead of a concrete module

    +
    +
    A parameterized module
    +
    // The interface desribes the parmaeters
    +interface module I where
    +  type n : #
    +  type constraint (fin n, n >= 1)
    +  x : [n]
    +
    +
    +// This module is parameterized
    +module F where
    +  import interface I
    +
    +  y : [n]
    +  y = x + 1
    +
    +
    +
    +

    To import a nested interface use import interface sumbodule I +and make sure that I is in scope.

    +

    It is also possible to import multiple interface modules, +or the same interface module more than once. Each import +of an interface module maybe be linked to a different concrete +module, as described in Instantiating a Parameterized Module.

    +
    +
    Multiple interface parameters
    +
    interface module I where
    +  type n : #
    +  type constraint (fin n, n >= 1)
    +  x : [n]
    +
    +
    +module F where
    +  import interface I as I
    +  import interface I as J
    +
    +  y : [I::n]
    +  y = I::x + 1
    +
    +  z : [J::n]
    +  z = J::x + 1
    +
    +
    +
    +
    +
    +

    Interface Constraints

    +

    When working with multiple interfaces, it is to useful +to be able to impose additional constraints on the +types imported from the interface.

    +
    +
    Adding constraints to interface parameters
    +
    interface module I where
    +  type n : #
    +  type constraint (fin n, n >= 1)
    +  x : [n]
    +
    +
    +module F where
    +  import interface I as I
    +  import interface I as J
    +
    +  interface constraint (I::n == J::n)
    +
    +  y : [I::n]
    +  y = I::x + J::x
    +
    +
    +
    +

    In this example we impose the constraint that n +(the width of x) in both interfaces must be the +same. Note that, of course, the two instantiations +may provide different values for x.

    +
    +
    +

    Instantiating a Parameterized Module

    +

    To use a parameterized module we need to provide concrete +implementations for the interfaces that it uses, and provide +a name for the resulting module. This is done as follows:

    +
    +
    Instantiating a parameterized module using a single interface.
    +
    interface module I where
    +  type n : #
    +  type constraint (fin n, n >= 1)
    +  x : [n]
    +
    +module F where
    +  import interface I
    +
    +  y : [n]
    +  y = x + 1
    +
    +module Impl where
    +  type n = 8
    +  x = 26
    +
    +module MyF = F { Impl }
    +
    +
    +
    +

    Here we defined a new module called MyF which is +obtained by filling in module Impl for the interface +used by F.

    +

    If a module is parameterized my multiple interfaces +we need to provide an implementation module for each +interface, using a slight variation on the previous notation.

    +
    +
    Instantiating a parameterized module by name.
    +
    // I is defined as above
    +
    +module F where
    +  import interface I as I
    +  import interface I as J
    +
    +  interface constraint (I::n == J::n)
    +
    +  y : [I::n]
    +  y = I::x + J::x
    +
    +module Impl1 where
    +  type n = 8
    +  x = 26
    +
    +module Impl2 where
    +  type n = 8
    +  x = 30
    +
    +module MyF = F { I = Impl1, J = Impl 2 }
    +
    +
    +
    +

    Each interface import is identified by its name, +which is derived from the as clause on the +interface import. If there is no as clause, +then the name of the parameter is derived from +the name of the interface itself.

    +

    Since interfaces are identified by name, the +order in which they are provided is not important.

    +

    Modules defined by instantiation may be nested, +just like any other module:

    +
    +
    Nested module instantiation.
    +
    module M where
    +
    +  import Somewhere // defines G
    +
    +  submodule F = submodule G { I }
    +
    +
    +
    +

    In this example, submodule F is defined +by instantiating some other parameterized +module G, presumably imported from Somewhere. +Note that in this case the argument to the instantiation +I is a top-level module, because it is not +preceded by the submodule keyword.

    +
    +
    +

    Anonymous Interface Modules

    +

    If we need to just parameterize a module by a couple of types/values, +it is quite cumbersome to have to define a whole separate interface module. +To make this more convenient we provide the following notation for defining +an anonymous interface and using it straight away:

    +
    +
    Simple parameterized module.
    +
    module M where
    +
    +  parameter
    +    type n : #
    +    type constraint (fin n, n >= 1)
    +    x : [n]
    +
    +  f : [n]
    +  f = 1 + x
    +
    +
    +
    +

    The parameter block defines an interface module and uses it. +Note that the parameters may not use things defined in M as +the interface is declared outside of M.

    +
    +
    +

    Anonymous Instantiation Arguments

    +

    Sometimes it is also a bit cumbersome to have to define a whole +separate module just to pass it as an argument to some parameterized +module. To make this more convenient we support the following notion +for instantiation a module:

    // A parameterized module
     module M where
     
    -parameter
    -  type n : #
    -  x      : [n]
    -  y      : [n]
    +  parameter
    +    type n : #
    +    x      : [n]
    +    y      : [n]
     
    -f : [n]
    -f = x + y
    +  f : [n]
    +  f = x + y
     
     
     // A module instantiation
    -module N = M where
    +module N = M
    +  where
    +  type n = 32
    +  x      = 11
    +  y      = helper
     
    -type n = 32
    -x      = 11
    -y      = helper
    -
    -helper = 12
    +  helper = 12
     
    -

    The second module, N, is computed by instantiating the parameterized -module M. Module N will provide the exact same definitions as M, -except that the parameters will be replaced by the values in the body -of N. In this example, N provides just a single definition, f.

    -

    Note that the only purpose of the body of N (the declarations -after the where keyword) is to define the parameters for M.

    -
    -
    -

    Parameterized Instantiations

    -

    It is possible for a module instantiation to be itself parameterized. -This could be useful if we need to define some of a module’s parameters -but not others.

    -
    // A parameterized module
    -module M where
    -
    -parameter
    -  type n : #
    -  x      : [n]
    -  y      : [n]
    -
    -f : [n]
    -f = x + y
    -
    -
    -// A parameterized instantiation
    -module N = M where
    -
    -parameter
    -  x : [32]
    -
    -type n = 32
    -y      = helper
    -
    -helper = 12
    -
    -
    -

    In this case N has a single parameter x. The result of instantiating -N would result in instantiating M using the value of x and 12 -for the value of y.

    -
    -
    -

    Importing Parameterized Modules

    -

    It is also possible to import a parameterized module without using -a module instantiation:

    -
    module M where
    -
    -parameter
    -  x : [8]
    -  y : [8]
    -
    -f : [8]
    -f = x + y
    -
    -
    -
    module N where
    -
    -import `M
    -
    -g = f { x = 2, y = 3 }
    -
    -
    -

    A backtick at the start of the name of an imported module indicates -that we are importing a parameterized module. In this case, Cryptol -will import all definitions from the module as usual, however every -definition will have some additional parameters corresponding to -the parameters of a module. All value parameters are grouped in a record.

    -

    This is why in the example f is applied to a record of values, -even though its definition in M does not look like a function.

    +

    The declarations in the where block are treated as the +definition of an anonymous module which is passed as the argument +to parameterized module M.

    diff --git a/docs/RefMan/_build/html/RefMan.html b/docs/RefMan/_build/html/RefMan.html index 5877ec92..b774e943 100644 --- a/docs/RefMan/_build/html/RefMan.html +++ b/docs/RefMan/_build/html/RefMan.html @@ -133,10 +133,18 @@
  • Private Blocks
  • +
  • Nested Modules +
  • Parameterized Modules
  • diff --git a/docs/RefMan/_build/html/_sources/BasicSyntax.rst.txt b/docs/RefMan/_build/html/_sources/BasicSyntax.rst.txt index 6486da62..90e31090 100644 --- a/docs/RefMan/_build/html/_sources/BasicSyntax.rst.txt +++ b/docs/RefMan/_build/html/_sources/BasicSyntax.rst.txt @@ -94,6 +94,8 @@ not be used for programmer defined names: private include module + submodule + interface newtype pragma property @@ -117,11 +119,10 @@ not be used for programmer defined names: .. code-block:: none :caption: Keywords - else include property let infixl parameter - extern module then import infixr constraint - if newtype type as infix down - private pragma where hiding primitive by - + as extern include interface parameter property where + by hiding infix let pragma submodule else + constraint if infixl module primitive then + down import infixr newtype private type The following table contains Cryptol's operators and their associativity with lowest precedence operators first, and highest diff --git a/docs/RefMan/_build/html/_sources/Modules.rst.txt b/docs/RefMan/_build/html/_sources/Modules.rst.txt index 540e12bf..4d694e5e 100644 --- a/docs/RefMan/_build/html/_sources/Modules.rst.txt +++ b/docs/RefMan/_build/html/_sources/Modules.rst.txt @@ -196,7 +196,7 @@ It is good practice to place such declarations in *private blocks*: The private block only needs to be indented if it might be followed by additional public declarations. If all remaining declarations are to be -private then no additional indentation is needed as the `private` block will +private then no additional indentation is needed as the ``private`` block will extend to the end of the module. .. code-block:: cryptol @@ -238,139 +238,373 @@ is equivalent to the previous one: helper2 = 3 +Nested Modules +-------------- + +Module may be declared withing other modules, using the ``submodule`` keword. + +.. code-block:: cryptol + :caption: Declaring a nested module called N + + module M where + + x = 0x02 + + submodule N where + y = x + 2 + +Submodules may refer to names in their enclosing scope. +Declarations in a sub-module will shadow names in the outer scope. + +Declarations in a submdule may be imported with ``import submodule``, +which works just like an ordinary import except that ``X`` refers +to the name of a submodule. + + +.. code-block:: cryptol + :caption: Using declarations from a submodule. + + module M where + + x = 0x02 + + submodule N where + y = x + 2 + + import submodule N as P + + z = 2 * P::y + +Note that recursive definitions across modules are not allowed. +So, in the previous example, it would be an error if ``y`` was +to try to use ``z`` in its definition. + + + +Implicit Imports +~~~~~~~~~~~~~~~~ + +For convenience, we add an implicit qualified submodule import for +each locally defined submodules. + +.. code-block:: cryptol + :caption: Making use of the implicit import for a submodule. + + module M where + + x = 0x02 + + submodule N where + y = x + 2 + + z = 2 * N::y + +``N::y`` works in the previous example because Cryptol added +an implicit import ``import submoulde N as N``. + + +Managing Module Names +~~~~~~~~~~~~~~~~~~~~~ + +The names of nested modules are managed by the module system just +like the name of any other declaration in Cryptol. Thus, nested +modules may declared in the public or private sections of their +containing module, and need to be imported before they can be used. +Thus, to use a submodule defined in top-level module ``A`` into +another top-level module ``B`` requires two steps: + + 1. First we need to import ``A`` to bring the name of the submodule in scope + 2. Then we need to import the submodule to bring the names defined in it in scope. + +.. code-block:: cryptol + :caption: Using a nested module from a different top-level module. + + module A where + + x = 0x02 + + submodule N where + y = x + 2 + + module B where + import A // Brings `N` in scope + import submodule N // Brings `y` in scope + z = 2 * y + Parameterized Modules --------------------- -.. warning:: - This section documents the current design, but we are in the process of - redesigning some aspects of the parameterized modules mechanism. +Interface Modules +~~~~~~~~~~~~~~~~~ + +An *interface module* describes the content of a module +without providing a concrete implementation. .. code-block:: cryptol + :caption: An interface module. + + interface module I where + + type n : # // `n` is a numeric type + + type constraint (fin n, n >= 1) + // Assumptions about the declared numeric type + + x : [n] // A declarations of a constant + +Like other modules, interfaces modules may be nested in +other modules: + +.. code-block:: cryptol + :caption: A nested interface module module M where - parameter - type n : # // `n` is a numeric type parameter + interface submodule I where + type n : # // `n` is a numeric type + + type constraint (fin n, n >= 1) + // Assumptions about the declared numeric type + + x : [n] // A declarations of a constant + + +Importing an Interface Module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A module may be parameterized by importing an interface, +instead of a concrete module + +.. code-block:: cryptol + :caption: A parameterized module + + // The interface desribes the parmaeters + interface module I where + type n : # type constraint (fin n, n >= 1) - // Assumptions about the parameter - - x : [n] // A value parameter - - // This definition uses the parameters. - f : [n] - f = 1 + x + x : [n] -Named Module Instantiations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // This module is parameterized + module F where + import interface I -One way to use a parameterized module is through a named instantiation: + y : [n] + y = x + 1 + +To import a nested interface use ``import interface sumbodule I`` +and make sure that ``I`` is in scope. + +It is also possible to import multiple interface modules, +or the same interface module more than once. Each import +of an interface module maybe be linked to a different concrete +module, as described in :ref:`instantiating_modules`. + + +.. code-block:: cryptol + :caption: Multiple interface parameters + + interface module I where + type n : # + type constraint (fin n, n >= 1) + x : [n] + + + module F where + import interface I as I + import interface I as J + + y : [I::n] + y = I::x + 1 + + z : [J::n] + z = J::x + 1 + + +Interface Constraints +~~~~~~~~~~~~~~~~~~~~~ + +When working with multiple interfaces, it is to useful +to be able to impose additional constraints on the +types imported from the interface. + +.. code-block:: cryptol + :caption: Adding constraints to interface parameters + + interface module I where + type n : # + type constraint (fin n, n >= 1) + x : [n] + + + module F where + import interface I as I + import interface I as J + + interface constraint (I::n == J::n) + + y : [I::n] + y = I::x + J::x + +In this example we impose the constraint that ``n`` +(the width of ``x``) in both interfaces must be the +same. Note that, of course, the two instantiations +may provide different values for ``x``. + + +.. _instantiating_modules: + + +Instantiating a Parameterized Module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use a parameterized module we need to provide concrete +implementations for the interfaces that it uses, and provide +a name for the resulting module. This is done as follows: + +.. code-block:: cryptol + :caption: Instantiating a parameterized module using a single interface. + + interface module I where + type n : # + type constraint (fin n, n >= 1) + x : [n] + + module F where + import interface I + + y : [n] + y = x + 1 + + module Impl where + type n = 8 + x = 26 + + module MyF = F { Impl } + +Here we defined a new module called ``MyF`` which is +obtained by filling in module ``Impl`` for the interface +used by ``F``. + +If a module is parameterized my multiple interfaces +we need to provide an implementation module for each +interface, using a slight variation on the previous notation. + +.. code-block:: cryptol + :caption: Instantiating a parameterized module by name. + + // I is defined as above + + module F where + import interface I as I + import interface I as J + + interface constraint (I::n == J::n) + + y : [I::n] + y = I::x + J::x + + module Impl1 where + type n = 8 + x = 26 + + module Impl2 where + type n = 8 + x = 30 + + module MyF = F { I = Impl1, J = Impl 2 } + +Each interface import is identified by its name, +which is derived from the ``as`` clause on the +interface import. If there is no ``as`` clause, +then the name of the parameter is derived from +the name of the interface itself. + +Since interfaces are identified by name, the +order in which they are provided is not important. + +Modules defined by instantiation may be nested, +just like any other module: + +.. code-block:: cryptol + :caption: Nested module instantiation. + + module M where + + import Somewhere // defines G + + submodule F = submodule G { I } + +In this example, ``submodule F`` is defined +by instantiating some other parameterized +module ``G``, presumably imported from ``Somewhere``. +Note that in this case the argument to the instantiation +``I`` is a top-level module, because it is not +preceded by the ``submodule`` keyword. + + +Anonymous Interface Modules +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If we need to just parameterize a module by a couple of types/values, +it is quite cumbersome to have to define a whole separate interface module. +To make this more convenient we provide the following notation for defining +an anonymous interface and using it straight away: + +.. code-block:: cryptol + :caption: Simple parameterized module. + + module M where + + parameter + type n : # + type constraint (fin n, n >= 1) + x : [n] + + f : [n] + f = 1 + x + +The ``parameter`` block defines an interface module and uses it. +Note that the parameters may not use things defined in ``M`` as +the interface is declared outside of ``M``. + + +Anonymous Instantiation Arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes it is also a bit cumbersome to have to define a whole +separate module just to pass it as an argument to some parameterized +module. To make this more convenient we support the following notion +for instantiation a module: .. code-block:: cryptol // A parameterized module module M where - parameter - type n : # - x : [n] - y : [n] + parameter + type n : # + x : [n] + y : [n] - f : [n] - f = x + y + f : [n] + f = x + y // A module instantiation - module N = M where + module N = M + where + type n = 32 + x = 11 + y = helper - type n = 32 - x = 11 - y = helper - - helper = 12 - -The second module, ``N``, is computed by instantiating the parameterized -module ``M``. Module ``N`` will provide the exact same definitions as ``M``, -except that the parameters will be replaced by the values in the body -of ``N``. In this example, ``N`` provides just a single definition, ``f``. - -Note that the only purpose of the body of ``N`` (the declarations -after the ``where`` keyword) is to define the parameters for ``M``. - - -Parameterized Instantiations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is possible for a module instantiation to be itself parameterized. -This could be useful if we need to define some of a module's parameters -but not others. - -.. code-block:: cryptol - - // A parameterized module - module M where - - parameter - type n : # - x : [n] - y : [n] - - f : [n] - f = x + y - - - // A parameterized instantiation - module N = M where - - parameter - x : [32] - - type n = 32 - y = helper - - helper = 12 - -In this case ``N`` has a single parameter ``x``. The result of instantiating -``N`` would result in instantiating ``M`` using the value of ``x`` and ``12`` -for the value of ``y``. - - -Importing Parameterized Modules -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is also possible to import a parameterized module without using -a module instantiation: - -.. code-block:: cryptol - - module M where - - parameter - x : [8] - y : [8] - - f : [8] - f = x + y - -.. code-block:: cryptol - - module N where - - import `M - - g = f { x = 2, y = 3 } - -A *backtick* at the start of the name of an imported module indicates -that we are importing a parameterized module. In this case, Cryptol -will import all definitions from the module as usual, however every -definition will have some additional parameters corresponding to -the parameters of a module. All value parameters are grouped in a record. - -This is why in the example ``f`` is applied to a record of values, -even though its definition in ``M`` does not look like a function. + helper = 12 +The declarations in the ``where`` block are treated as the +definition of an anonymous module which is passed as the argument +to parameterized module ``M``. diff --git a/docs/RefMan/_build/html/objects.inv b/docs/RefMan/_build/html/objects.inv index 452662364bc711ac51075e6627b7a9a251704262..722ba416f917f767bb29bd02740a09fde6cc1c12 100644 GIT binary patch delta 280 zcmV+z0q6eU0)+#Rc7KwwPQx$|hIc=OrLqQzwPS&yLRBN$9UbwJSU7fMyQSvoiE|0D zLnOB3`|taeJ7ot>R;Qpn+_>{%D@?_U2fmx}edAk2fD>WE%QxBlTW8TZ zX>_I}n4E$gjJT-0ctq30@rqU%5GalvTJX!#wVd2J;d8`Z@qgn0I&C0A&Z7;TH!3o; zs4L`sbOFWUVoz8pSowryMpcpW6tfz&)B@@B3f@sgd!l6R<0F&WdC*?=qORZCuP*xd1#agg=(D{FM2m;%~_`p1Qm e^dGGZzA-wt9T9@9np`AC&WZ98YGgkHKnjFhFpgvZ delta 242 zcmVoCTk3xJSG$IE<#i*Wu<7I#d^X|ZM4cWY?M1}5xmd~(t1%*d0G zBz~hCYRDhs6>H=fCOUQM?U< saJ6co+ofg