Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numeric Constraint Guards #1380

Merged
merged 133 commits into from
Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
133 commits
Select commit Hold shift + click to select a range
def6b28
spec
rybla Jul 5, 2022
2dd322f
syntax
rybla Jul 5, 2022
759befd
first pass impl of checkSigB for DPropGuards
rybla Jul 5, 2022
ea8e312
checkPropGuard TODO
rybla Jul 5, 2022
b30ee07
Rename DPropGuards
rybla Jul 5, 2022
6000ce9
new module: Cryptol.Parser.PropGuards
rybla Jul 5, 2022
a4c5d8a
ExpandPropGuards pass
rybla Jul 6, 2022
f3c2f58
expandpropguards
rybla Jul 6, 2022
0902f12
simple parsing
rybla Jul 6, 2022
72cccb1
parsing
rybla Jul 7, 2022
b4b956b
no more ExpandPropGuards Name Pass
rybla Jul 7, 2022
568ab61
ExpandPropGuards pass
rybla Jul 7, 2022
9b61327
do ExpandPropGuards pass
rybla Jul 7, 2022
3c1f25b
typechecking for PropGuards; factored out checkBindDefExpr
rybla Jul 7, 2022
d1d903d
fixed shadowing of checkPropGuard
rybla Jul 7, 2022
1bdde41
make things Safe
rybla Jul 7, 2022
6078a3f
ignore .vscode
rybla Jul 7, 2022
6b59c65
organize
rybla Jul 7, 2022
1f2c82c
test: parsing
rybla Jul 7, 2022
5ae355e
formatting
rybla Jul 7, 2022
fe30062
Safe
rybla Jul 7, 2022
fba4f14
first impl of evaluation
rybla Jul 8, 2022
d9c9a56
removed unsafePeroformIO debugging
rybla Jul 8, 2022
f578222
implemented simple evaluation over Props for checking prop guards
rybla Jul 18, 2022
764442a
removed old coment
rybla Jul 18, 2022
4fc59a3
builds: before removing old code (in comments)
rybla Jul 22, 2022
e640aa2
[builds] after removing old code (in comments)
rybla Jul 22, 2022
005c7da
some tests
rybla Jul 22, 2022
09f6087
cleanup, better errors
rybla Jul 22, 2022
16b1582
Merge branch 'master' into conditional-constraints
rybla Jul 22, 2022
fc1a42a
cleaned; Trustworthy->Safe
rybla Jul 22, 2022
1cb8ef2
note about prepending inferred well-formedness goals to guarding cons…
rybla Jul 22, 2022
fefcf56
proper handling of evaluating with inferred well-formedness constraints
rybla Jul 23, 2022
a3bfb1c
updated syntax to not use 'propguards' keyword
rybla Aug 1, 2022
22fb6d8
test [ci skip]
rybla Aug 1, 2022
9f0d72a
formatting
rybla Aug 10, 2022
ed6ade6
supports type aliases in prop guards
rybla Aug 10, 2022
b5b92c0
comment about anticipated change in new module system
rybla Aug 10, 2022
c1812df
shouldn't commit this
rybla Aug 10, 2022
d58d1cd
gitignore src/Cryptol/Parser.hs
rybla Aug 10, 2022
823d1e4
[ci skip]
rybla Aug 10, 2022
9508fe9
Merge pull request #1393 from GaloisInc/master
rybla Aug 11, 2022
2ecee7b
docs for constraint guards
rybla Aug 11, 2022
840449a
[ci skip]
rybla Aug 11, 2022
5e0d8a8
updated docs: constraint guads exhaustivity requirement
rybla Aug 11, 2022
b7f6137
[ci skip]
rybla Aug 11, 2022
eca8366
rest of the docs stuff
rybla Aug 11, 2022
369ebfb
tryProveImplication
rybla Aug 11, 2022
795eb28
warnings for non-exhaustive constraint guards
rybla Aug 11, 2022
e08fc8f
only check exhaustive constraint guards if user option is on
rybla Aug 11, 2022
3cdb703
properly handle censoring warnings
rybla Aug 13, 2022
722ca3f
exhaustive constraints guards checking
rybla Aug 13, 2022
fb39dc9
constraint guards example: inits
rybla Aug 13, 2022
fcce470
updated docs to reflect new warning
rybla Aug 13, 2022
0b28062
fastSchemaOf for EPropGuards
rybla Aug 13, 2022
3698ed0
Inst Expr case for EPropGuards
rybla Aug 13, 2022
19d4724
showParseable EPropGuards
rybla Aug 13, 2022
dbd7a66
exprSchema EPropGuards shouldn't happen
rybla Aug 13, 2022
3de78ab
freeVars EPropGuards
rybla Aug 13, 2022
57cb59a
Merge branch 'master' into conditional-constraints
rybla Aug 13, 2022
c33c3fd
updated docs [ci skip]
rybla Aug 13, 2022
961cb00
cryptolError for ExpandPropGuardsError
rybla Aug 13, 2022
98e944e
added Mergesort, removed old tests
rybla Aug 15, 2022
38c72b2
type in filename [ci skip]
rybla Aug 15, 2022
2954247
new test: insert
rybla Aug 15, 2022
556e12f
[ci skip]
rybla Aug 15, 2022
cc15341
removed comment
rybla Aug 17, 2022
a78e6a3
added field Schema of EPropGuards
rybla Aug 17, 2022
fd0df8b
making use of EPropGuards' schema
rybla Aug 17, 2022
e4e242b
dont need LambdaCase
rybla Aug 17, 2022
03f6b4c
no need to panic
rybla Aug 17, 2022
11e943d
remove old comments
rybla Aug 17, 2022
3115270
redundant import
rybla Aug 17, 2022
70ca677
specializeExpr EPropGuards
rybla Aug 17, 2022
929cf7f
added range
rybla Aug 17, 2022
8a1af2b
cleaned up syntax
rybla Aug 17, 2022
26e54a9
better parsing propguards
rybla Aug 17, 2022
cb9ce9c
comment
rybla Aug 17, 2022
fb16152
clean up syntax
rybla Aug 17, 2022
0f3e898
evalExpr EPropGuards
rybla Aug 17, 2022
cb87c4f
Prop ~~> Type
rybla Aug 17, 2022
111684b
made evalProp more readable
rybla Aug 17, 2022
f54225e
applied same simplification to Reference's evalProp
rybla Aug 17, 2022
17a2968
cleaned up syntax
rybla Aug 17, 2022
d2d92ea
Uncons
rybla Aug 19, 2022
908ceac
delete debug comments
rybla Aug 19, 2022
f7dcfe7
added proper Safe and Trustworthy pragmas
rybla Aug 19, 2022
f08ddf7
refactored checkSigB case P.DPropGuards
rybla Aug 19, 2022
5b6cd2a
refactor
rybla Aug 19, 2022
537b3d9
safe
rybla Aug 19, 2022
d3b79ac
EPropGuards has a Type instead of a Schema
rybla Aug 19, 2022
76ff13e
refactored out checkExhaustive
rybla Aug 19, 2022
5dcdbe0
readability
rybla Aug 22, 2022
8b4381b
rename
rybla Aug 22, 2022
c1f5d0c
comment
rybla Aug 22, 2022
b52ad96
more efficient checkExhaustive
rybla Aug 22, 2022
1cfad8a
updated to master
rybla Aug 22, 2022
9986a61
Merge pull request #1418 from GaloisInc/master
rybla Aug 26, 2022
ee2db7c
properly set up test suite
rybla Aug 26, 2022
01ed76b
proper uncapitalized names
rybla Aug 29, 2022
28f34df
can be -> are
rybla Aug 30, 2022
5a68193
redundant import
rybla Aug 30, 2022
efa149d
removed obscenity
rybla Aug 30, 2022
418e575
better error message
rybla Aug 30, 2022
e8e9fbf
TODO: emit expression `error`
rybla Aug 30, 2022
79a2f62
better local helper names
rybla Aug 30, 2022
d5b7c2f
better pp
rybla Aug 30, 2022
0a6fb8b
If no constraint guard is satisfied, specialization yields error term
rybla Aug 30, 2022
1ec956c
rename
rybla Aug 30, 2022
3c9bc24
properly apply type args to funs gen'ed during ExpandPropGuards
rybla Aug 30, 2022
1514db5
better error message on NoMatchingPropGuardCase
rybla Aug 30, 2022
f61f002
allow constant declarations to use constraint guards
rybla Aug 30, 2022
5df322e
formatting
rybla Aug 30, 2022
9cd2aea
formatting
rybla Aug 30, 2022
97e7c05
formatting
rybla Aug 30, 2022
88b26ea
constant tests for constraint guards
rybla Aug 30, 2022
415c6da
using `eError` properly
rybla Aug 31, 2022
a40d19c
EPropGuards ... schema ~~> EPropGuards ... ty
rybla Aug 31, 2022
9a4f48d
Merge pull request #1424 from GaloisInc/master
rybla Aug 31, 2022
4a2ac67
Merge remote-tracking branch 'origin/master' into conditional-constra…
yav Sep 3, 2022
b86825b
Update text in the "Numeric Constraint Guards" section
yav Sep 3, 2022
9d63190
Update the CHANGES files
yav Sep 3, 2022
6642023
Remove commented out imports
yav Sep 5, 2022
fb3935f
* Introduce a separate type for a property guarded alternative
yav Sep 6, 2022
d211e52
Remove "currently" from error message
yav Sep 6, 2022
4f82466
Simplify type checking of constraint guards
yav Sep 12, 2022
16e7d4f
Fixes to exhaustivness checking
yav Sep 12, 2022
3dc6c01
Clean up translation, and support for nested modules
yav Sep 12, 2022
4ef8000
Another test
yav Sep 12, 2022
44685f0
Fix test
yav Sep 12, 2022
6971952
Merge branch 'master' into conditional-constraints
yav Sep 13, 2022
61ad252
Fix pretty printer for propguards
yav Sep 13, 2022
2be867e
Report an error if we find unsupported constraints
yav Sep 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dist-newstyle
.ghc.environment.*
cabal.project.freeze
cabal.project.local*
.vscode/

# don't check in generated documentation
#docs/CryptolPrims.pdf
Expand Down Expand Up @@ -38,3 +39,6 @@ allfiles.wxs
cryptol.msi
cryptol.wixobj
cryptol.wixpdb

# happy-generated files
src/Cryptol/Parser.hs
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Language changes

* Declarations may now use *numeric constraint guards*. This is a feature
that allows a function to behave differently depending on its numeric
type parameters. See the [manual section](https://galoisinc.github.io/cryptol/RefMan/_build/html/BasicSyntax.html#numeric-constraint-guards))
for more information.

* The foreign function interface (FFI) has been added, which allows Cryptol to
call functions written in C. See the [manual section](https://galoisinc.github.io/cryptol/RefMan/_build/html/FFI.html)
for more information.
Expand Down
55 changes: 55 additions & 0 deletions ConditionalConstraints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Conditional Constraints

## Syntax

The front-end AST has a new constructor:

```hs
data BindDef name = DPropGuards [([Prop name], Expr name)] | ...
```

which is parsed from the following syntax:

```
<name> : <signature>
<name> <pats>
[ | <props> => <expr> ]
```

## Expanding PropGuards

- Before renaming, a `Bind` with a `bDef = DPropGuards ...` will be expanded into several `Bind`s, one for each guard case.
- The generated `Bind`s will have fresh names, but the names will have the same location as the original function's name.
- These generated `Bind`'s will have the same type as the original function, except that the list of type constraints will also include the `Prop name`s that appeared on the LHS of the originating ase of `DPropGuards`.
- The original function will have the `Expr name` in each of the `DPropGuards` cases replaced with a function call the appropriate, generated function.

## Renaming

The new constructor of `BindDef` is traversed as normal during renaming. This ensures that a function with `DPropGuards` ends up in the same mutual-recursion group as the generated functions that it calls.

## Typechecking

The back-end AST has a new constructor:

```hs
data Expr = EPropGuards [([Prop], Expr)] | ...
```

During typechecking, a `BindDef` of the form

```
DPropGuards [(props1, f1 x y), (prop2, f2 x y)]
```

is processed into a `Decl` of the form

```
Decl
{ dDefinition =
DExpr (EPropGuards
[ (props1, f1 x y)
, (props2, f2 x y) ])
}
```

Each case of an `EPropGuards` is typechecked by first asssuming the `props` and then typechecking the expression. However, this typechecking isn't really that important because by construction the expression is just a simple application that is ensured to be well-typed. But we can use this structure for more general purposes.
5 changes: 5 additions & 0 deletions cryptol-remote-api/src/CryptolServer/Exceptions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ cryptolError modErr warns =
(20710, [ ("source", jsonPretty src)
, ("errors", jsonList (map jsonPretty errs))
])
ExpandPropGuardsError src err ->
(20711, [ ("source", jsonPretty src)
, ("errors", jsonPretty err)
])

NoIncludeErrors src errs ->
-- TODO: structured error here
(20720, [ ("source", jsonPretty src)
Expand Down
1 change: 1 addition & 0 deletions cryptol.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ library
Cryptol.Parser.Names,
Cryptol.Parser.Name,
Cryptol.Parser.NoPat,
Cryptol.Parser.ExpandPropGuards,
Cryptol.Parser.NoInclude,
Cryptol.Parser.Selector,
Cryptol.Parser.Utils,
Expand Down
48 changes: 48 additions & 0 deletions docs/RefMan/BasicSyntax.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,54 @@ Type Signatures
f,g : {a,b} (fin a) => [a] b


Numeric Constraint Guards
-------------------------

A declaration with a signature can use *numeric constraint guards*,
which are used to change the behavior of a functoin depending on its
numeric type parameters. For example:

.. code-block:: cryptol

len : {n} (fin n) => [n]a -> Integer
len xs | n == 0 => 0
| n > 0 => 1 + len (drop `{1} xs)

Each behavior starts with ``|`` and lists some constraints on the numeric
parameters to a declaration. When applied, the function will use the first
definition that satisfies the provided numeric parameters.

Numeric constraint guards are quite similar to an ``if`` expression,
except that decisions are based on *types* rather than values. There
is also an important difference to simply using demotion and an
actual ``if`` statement:

.. code-block:: cryptol

len' : {n} (fin n) => [n]a -> Integer
len' xs = if `n == 0 => 0
| `n > 0 => 1 + len (drop `{1} xs)

The definition of ``len'`` is rejected, because the *value based* ``if``
expression does provide the *type based* fact ``n >= 1`` which is
required by ``drop `{1} xs``, while in ``len``, the type-checker
locally-assumes the constraint ``n > 0`` in that constraint-guarded branch
and so it can in fact determine that ``n >= 1``.

Requirements:
- Numeric constraint guards only support constraints over numeric literals,
such as ``fin``, ``<=``, ``==``, etc.
Type constraint aliases can also be used as long as they only constrain
numeric literals.
- The numeric constraint guards of a declaration should be exhaustive. The
type-checker will attempt to prove that the set of constraint guards is
exhaustive, but if it can't then it will issue a non-exhaustive constraint
guards warning. This warning is controlled by the environmental option
``warnNonExhaustiveConstraintGuards``.
- Each constraint guard is checked *independently* of the others, and there
are no implict assumptions that the previous behaviors do not match---
instead the programmer needs to specify all constraints explicitly
in the guard.

Layout
------
Expand Down
Binary file modified docs/RefMan/_build/doctrees/BasicSyntax.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/BasicTypes.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/Expressions.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/FFI.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/Modules.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/OverloadedOperations.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/RefMan.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/TypeDeclarations.doctree
Binary file not shown.
Binary file modified docs/RefMan/_build/doctrees/environment.pickle
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/RefMan/_build/html/.buildinfo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 12febdda05646d6655d93ce350355f10
config: 41758cdb8fafe65367e2aa727ac7d826
tags: 645f666f9bcd5a90fca523b33c5a78b7
66 changes: 56 additions & 10 deletions docs/RefMan/_build/html/BasicSyntax.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
Expand Down Expand Up @@ -43,6 +42,7 @@
<li class="toctree-l1 current"><a class="current reference internal" href="#">Basic Syntax</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#declarations">Declarations</a></li>
<li class="toctree-l2"><a class="reference internal" href="#type-signatures">Type Signatures</a></li>
<li class="toctree-l2"><a class="reference internal" href="#numeric-constraint-guards">Numeric Constraint Guards</a></li>
<li class="toctree-l2"><a class="reference internal" href="#layout">Layout</a></li>
<li class="toctree-l2"><a class="reference internal" href="#comments">Comments</a></li>
<li class="toctree-l2"><a class="reference internal" href="#identifiers">Identifiers</a></li>
Expand Down Expand Up @@ -84,21 +84,67 @@
<div itemprop="articleBody">

<section id="basic-syntax">
<h1>Basic Syntax<a class="headerlink" href="#basic-syntax" title="Permalink to this heading"></a></h1>
<h1>Basic Syntax<a class="headerlink" href="#basic-syntax" title="Permalink to this headline"></a></h1>
<section id="declarations">
<h2>Declarations<a class="headerlink" href="#declarations" title="Permalink to this heading"></a></h2>
<h2>Declarations<a class="headerlink" href="#declarations" title="Permalink to this headline"></a></h2>
<div class="highlight-cryptol notranslate"><div class="highlight"><pre><span></span><span class="nf">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="ow">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">z</span><span class="w"></span>
</pre></div>
</div>
</section>
<section id="type-signatures">
<h2>Type Signatures<a class="headerlink" href="#type-signatures" title="Permalink to this heading"></a></h2>
<h2>Type Signatures<a class="headerlink" href="#type-signatures" title="Permalink to this headline"></a></h2>
<div class="highlight-cryptol notranslate"><div class="highlight"><pre><span></span><span class="nf">f</span><span class="p">,</span><span class="n">g</span><span class="w"> </span><span class="kt">:</span><span class="w"> </span><span class="p">{</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">}</span><span class="w"> </span><span class="p">(</span><span class="kr">fin</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="n">b</span><span class="w"></span>
</pre></div>
</div>
</section>
<section id="numeric-constraint-guards">
<h2>Numeric Constraint Guards<a class="headerlink" href="#numeric-constraint-guards" title="Permalink to this headline"></a></h2>
<p>A declaration with a signature can use <em>numeric constraint guards</em>,
which are used to change the behavior of a functoin depending on its
numeric type parameters. For example:</p>
<div class="highlight-cryptol notranslate"><div class="highlight"><pre><span></span><span class="nf">len</span><span class="w"> </span><span class="kt">:</span><span class="w"> </span><span class="p">{</span><span class="n">n</span><span class="p">}</span><span class="w"> </span><span class="p">(</span><span class="kr">fin</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="p">[</span><span class="n">n</span><span class="p">]</span><span class="n">a</span><span class="w"> </span><span class="ow">-&gt;</span><span class="w"> </span><span class="kt">Integer</span><span class="w"></span>
<span class="nf">len</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="p">(</span><span class="n">drop</span><span class="w"> </span><span class="p">`{</span><span class="mi">1</span><span class="p">}</span><span class="w"> </span><span class="n">xs</span><span class="p">)</span><span class="w"></span>
</pre></div>
</div>
<p>Each behavior starts with <code class="docutils literal notranslate"><span class="pre">|</span></code> and lists some constraints on the numeric
parameters to a declaration. When applied, the function will use the first
definition that satisfies the provided numeric parameters.</p>
<p>Numeric constraint guards are quite similar to an <code class="docutils literal notranslate"><span class="pre">if</span></code> expression,
except that decisions are based on <em>types</em> rather than values. There
is also an important difference to simply using demotion and an
actual <code class="docutils literal notranslate"><span class="pre">if</span></code> statement:</p>
<div class="highlight-cryptol notranslate"><div class="highlight"><pre><span></span><span class="nf">len&#39;</span><span class="w"> </span><span class="kt">:</span><span class="w"> </span><span class="p">{</span><span class="n">n</span><span class="p">}</span><span class="w"> </span><span class="p">(</span><span class="kr">fin</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="p">[</span><span class="n">n</span><span class="p">]</span><span class="n">a</span><span class="w"> </span><span class="ow">-&gt;</span><span class="w"> </span><span class="kt">Integer</span><span class="w"></span>
<span class="nf">len&#39;</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="ow">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="p">`</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="p">`</span><span class="n">n</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="ow">=&gt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="p">(</span><span class="n">drop</span><span class="w"> </span><span class="p">`{</span><span class="mi">1</span><span class="p">}</span><span class="w"> </span><span class="n">xs</span><span class="p">)</span><span class="w"></span>
</pre></div>
</div>
<p>The definition of <code class="docutils literal notranslate"><span class="pre">len'</span></code> is rejected, because the <em>value based</em> <code class="docutils literal notranslate"><span class="pre">if</span></code>
expression does provide the <em>type based</em> fact <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">&gt;=</span> <span class="pre">1</span></code> which is
required by <code class="docutils literal notranslate"><span class="pre">drop</span> <span class="pre">`{1}</span> <span class="pre">xs</span></code>, while in <code class="docutils literal notranslate"><span class="pre">len</span></code>, the type-checker
locally-assumes the constraint <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> in that constraint-guarded branch
and so it can in fact determine that <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">&gt;=</span> <span class="pre">1</span></code>.</p>
<dl class="simple">
<dt>Requirements:</dt><dd><ul class="simple">
<li><p>Numeric constraint guards only support constraints over numeric literals,
such as <code class="docutils literal notranslate"><span class="pre">fin</span></code>, <code class="docutils literal notranslate"><span class="pre">&lt;=</span></code>, <code class="docutils literal notranslate"><span class="pre">==</span></code>, etc.
Type constraint aliases can also be used as long as they only constrain
numeric literals.</p></li>
<li><p>The numeric constraint guards of a declaration should be exhaustive. The
type-checker will attempt to prove that the set of constraint guards is
exhaustive, but if it can’t then it will issue a non-exhaustive constraint
guards warning. This warning is controlled by the environmental option
<code class="docutils literal notranslate"><span class="pre">warnNonExhaustiveConstraintGuards</span></code>.</p></li>
<li><p>Each constraint guard is checked <em>independently</em> of the others, and there
are no implict assumptions that the previous behaviors do not match—
instead the programmer needs to specify all constraints explicitly
in the guard.</p></li>
</ul>
</dd>
</dl>
</section>
<section id="layout">
<h2>Layout<a class="headerlink" href="#layout" title="Permalink to this heading"></a></h2>
<h2>Layout<a class="headerlink" href="#layout" title="Permalink to this headline"></a></h2>
<p>Groups of declarations are organized based on indentation.
Declarations with the same indentation belong to the same group.
Lines of text that are indented more than the beginning of a
Expand All @@ -119,7 +165,7 @@ <h2>Layout<a class="headerlink" href="#layout" title="Permalink to this heading"
of <cite>f</cite>, which defines two more local names, <cite>y</cite> and <cite>z</cite>.</p>
</section>
<section id="comments">
<h2>Comments<a class="headerlink" href="#comments" title="Permalink to this heading"></a></h2>
<h2>Comments<a class="headerlink" href="#comments" title="Permalink to this headline"></a></h2>
<p>Cryptol supports block comments, which start with <code class="docutils literal notranslate"><span class="pre">/*</span></code> and end with
<code class="docutils literal notranslate"><span class="pre">*/</span></code>, and line comments, which start with <code class="docutils literal notranslate"><span class="pre">//</span></code> and terminate at the
end of the line. Block comments may be nested arbitrarily.</p>
Expand All @@ -134,7 +180,7 @@ <h2>Comments<a class="headerlink" href="#comments" title="Permalink to this head
</div>
</section>
<section id="identifiers">
<h2>Identifiers<a class="headerlink" href="#identifiers" title="Permalink to this heading"></a></h2>
<h2>Identifiers<a class="headerlink" href="#identifiers" title="Permalink to this headline"></a></h2>
<p>Cryptol identifiers consist of one or more characters. The first
character must be either an English letter or underscore (<code class="docutils literal notranslate"><span class="pre">_</span></code>). The
following characters may be an English letter, a decimal digit,
Expand All @@ -150,7 +196,7 @@ <h2>Identifiers<a class="headerlink" href="#identifiers" title="Permalink to thi
</div>
</section>
<section id="keywords-and-built-in-operators">
<h2>Keywords and Built-in Operators<a class="headerlink" href="#keywords-and-built-in-operators" title="Permalink to this heading"></a></h2>
<h2>Keywords and Built-in Operators<a class="headerlink" href="#keywords-and-built-in-operators" title="Permalink to this headline"></a></h2>
<p>The following identifiers have special meanings in Cryptol, and may
not be used for programmer defined names:</p>
<div class="literal-block-wrapper docutils container" id="id3">
Expand Down Expand Up @@ -227,7 +273,7 @@ <h2>Keywords and Built-in Operators<a class="headerlink" href="#keywords-and-bui
</table>
</section>
<section id="built-in-type-level-operators">
<h2>Built-in Type-level Operators<a class="headerlink" href="#built-in-type-level-operators" title="Permalink to this heading"></a></h2>
<h2>Built-in Type-level Operators<a class="headerlink" href="#built-in-type-level-operators" title="Permalink to this headline"></a></h2>
<p>Cryptol includes a variety of operators that allow computations on
the numeric types used to specify the sizes of sequences.</p>
<table class="docutils align-default" id="id5">
Expand Down Expand Up @@ -282,7 +328,7 @@ <h2>Built-in Type-level Operators<a class="headerlink" href="#built-in-type-leve
</table>
</section>
<section id="numeric-literals">
<h2>Numeric Literals<a class="headerlink" href="#numeric-literals" title="Permalink to this heading"></a></h2>
<h2>Numeric Literals<a class="headerlink" href="#numeric-literals" title="Permalink to this headline"></a></h2>
<p>Numeric literals may be written in binary, octal, decimal, or
hexadecimal notation. The base of a literal is determined by its prefix:
<code class="docutils literal notranslate"><span class="pre">0b</span></code> for binary, <code class="docutils literal notranslate"><span class="pre">0o</span></code> for octal, no special prefix for
Expand Down
Loading