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 literals sampling #1389

Draft
wants to merge 87 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
adb8bb9
lambdacase
rybla Jul 11, 2022
9cc13a9
ignore .vscode
rybla Jul 11, 2022
e3a96d3
make things trustworthy temporarily
rybla Jul 11, 2022
936d97a
annoated where numeric sampler will be invoked
rybla Jul 14, 2022
509e17e
added some dependencies for doing sized-vector stuff
rybla Jul 14, 2022
9799891
handling rationals
rybla Jul 14, 2022
82bca83
system of equations; solving via gaussian elimination
rybla Jul 14, 2022
d505eec
SamplingM monad for sampling computations
rybla Jul 14, 2022
b9db9b3
expressions are n-sized vectors of Nums
rybla Jul 14, 2022
4527ddb
outlined Preconstraints; will need to convert [Prop] to Preconstraints
rybla Jul 14, 2022
e649ccc
outlined Constraints; IR for sampling solutions
rybla Jul 14, 2022
db8515c
outlined sampling usage
rybla Jul 14, 2022
37f2073
instance Num Nat'
rybla Jul 14, 2022
5041fb1
formatting
rybla Jul 14, 2022
c07b8ca
outlined sampling algorithm
rybla Jul 14, 2022
180b522
todos
rybla Jul 15, 2022
b78dc02
[builds] checkpoin in cleaning up code to use normal vectors
rybla Jul 26, 2022
294f014
cleaned up the whole stack
rybla Jul 26, 2022
5ca126d
first pass impl of sampleLiterals
rybla Jul 27, 2022
3a9cac0
plugged in literal sampling using two new environment vars: literal-s…
rybla Jul 28, 2022
3fd938e
handling options correctly (I think)
rybla Jul 28, 2022
55427ad
working on converting from props to preconstraints to constraints
rybla Aug 1, 2022
2492d7f
[skip ci]
rybla Aug 1, 2022
9d662db
fixed types
rybla Aug 2, 2022
c4f5906
old comment
rybla Aug 2, 2022
6e619c2
checkpoint for Props -> Preconstraints -> Constraints
rybla Aug 2, 2022
0fa554c
comments and debugging checkpoint
rybla Aug 4, 2022
3095ee1
correct approach to eliminating denomenators
rybla Aug 23, 2022
26c9637
formatting
rybla Aug 23, 2022
3ff9b6c
formatting
rybla Aug 23, 2022
404564e
accounting for dependency order (depOrd)
rybla Aug 23, 2022
76a0786
removed comment
rybla Aug 23, 2022
641af0b
properly calculating upper bound
rybla Aug 23, 2022
793bc61
comment
rybla Aug 23, 2022
ac65606
works!
rybla Aug 23, 2022
ef3e5a8
handles type synonyms
rybla Aug 23, 2022
22c1a85
Merge branch 'master' into literal-sampling
rybla Aug 24, 2022
e491a4e
appropriately marking trustworthy modules as safe
rybla Aug 24, 2022
22704c1
works on test1-test5 in Test1
rybla Aug 24, 2022
3b9da4b
works on test6
rybla Aug 24, 2022
7b0034e
works on test8
rybla Aug 24, 2022
7040d6c
removed problematic GHC option
rybla Aug 24, 2022
c52cfda
Z', Q'
rybla Aug 24, 2022
85071d1
error msg
rybla Aug 24, 2022
3461e3e
better comments and error reporting
rybla Aug 24, 2022
003e94d
better error messages
rybla Aug 24, 2022
0f43f85
message formattign
rybla Aug 24, 2022
7d56f20
comment formatting
rybla Aug 24, 2022
6ba56a5
sampling error causes error message instead of panic
rybla Aug 25, 2022
7157688
comment
rybla Aug 29, 2022
ed9412d
checkpoint sampling over weighted ranges
rybla Aug 29, 2022
eff6b25
better sampling distributions
rybla Aug 29, 2022
1b72941
addressed warnings
rybla Aug 29, 2022
d5a33d5
not actually using Q' and Z' after all
rybla Aug 30, 2022
f3710ef
old comment
rybla Aug 30, 2022
62ef6e7
refactored giant qcCmd
rybla Aug 30, 2022
9a3e233
refactored and documented qcExpr
rybla Aug 30, 2022
0b2a86e
refactored out Q module
rybla Aug 30, 2022
82485bd
don't support literal sampling over constraints that reference `inf`
rybla Aug 30, 2022
f3547eb
fine-tuning exponentPowSkew, documentation
rybla Aug 30, 2022
387698d
old comment
rybla Aug 31, 2022
dfb5517
formatting
rybla Aug 31, 2022
535f060
formattin
rybla Aug 31, 2022
91393d2
comment
rybla Aug 31, 2022
2606b13
safe Num Nat'
rybla Aug 31, 2022
1cb0f19
use fromIntegral
rybla Aug 31, 2022
73dee71
High-level description of numeric literal sampling algorithm
rybla Aug 31, 2022
093508b
Properties docs
rybla Aug 31, 2022
835c418
better error reporting, which fixes test outputs
rybla Aug 31, 2022
8fe2165
old comments
rybla Aug 31, 2022
efdb0e8
comments
rybla Aug 31, 2022
eb3b328
removed instance Num (Exp a)
rybla Aug 31, 2022
99768cf
using isSolvable
rybla Sep 1, 2022
6632495
rename
rybla Sep 2, 2022
ff14a5c
PPNeq is not yet supported
rybla Sep 2, 2022
d7701a5
replaced `error`
rybla Sep 2, 2022
fc636fc
fix accidental negation during refactoring
rybla Sep 2, 2022
abf353c
fixed bug in PPExp normalization
rybla Sep 2, 2022
abf0dcf
sampling debug level = -1
rybla Sep 2, 2022
7f5a7ef
fixed redundant import warning
rybla Sep 2, 2022
64fdf04
removed debugs
rybla Sep 2, 2022
ee7b994
e/n = (1/n) * e
rybla Sep 2, 2022
8269475
fixed handling fresh vars
rybla Sep 2, 2022
bc6d01b
Examples work
rybla Sep 2, 2022
fc38301
actually using typeclass constraints for upper bounding
rybla Sep 2, 2022
701aab6
examples
rybla Sep 2, 2022
cbf521f
removed old test file
rybla Sep 2, 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
1 change: 1 addition & 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
10 changes: 10 additions & 0 deletions LiteralSampling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Literal Sampling



## TODO

- [x] remove use of vector-sized and related dependencies -- its not worth it now that I have a good idea of what I'm doing
- this will require explicit nVars included in some places probably
- [x] make sure to use the `SamplingM` monad basically everywhere -- so that you can reasonably throw errors without causing a crash
- [ ] where to call `sample` from, so I know what type exactly it should have?
13 changes: 12 additions & 1 deletion cryptol.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ library
mtl >= 2.2.1,
time >= 1.6.0.1,
panic >= 0.3,
what4 >= 1.3 && < 1.4
what4 >= 1.3 && < 1.4,
constraints,
vector

if impl(ghc >= 9.0)
build-depends: ghc-bignum >= 1.0 && < 1.3
Expand Down Expand Up @@ -176,6 +178,15 @@ library
Cryptol.Transform.Specialize,
Cryptol.Transform.AddModParams,

Cryptol.TypeCheck.Solver.Numeric.Sampling
Cryptol.TypeCheck.Solver.Numeric.Sampling.Base,
Cryptol.TypeCheck.Solver.Numeric.Sampling.Constraints,
Cryptol.TypeCheck.Solver.Numeric.Sampling.Exp,
Cryptol.TypeCheck.Solver.Numeric.Sampling.Preconstraints,
Cryptol.TypeCheck.Solver.Numeric.Sampling.Sampling,
Cryptol.TypeCheck.Solver.Numeric.Sampling.SolvedConstraints,
Cryptol.TypeCheck.Solver.Numeric.Sampling.System,

Cryptol.IR.FreeVars,

Cryptol.Backend,
Expand Down
182 changes: 182 additions & 0 deletions docs/RefMan/Properties.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@

Properties
==========

A _property_ is a Cryptol value of the form

.. code-block:: cryptol

{A1, ..., AL} (C1, ..., CM) => T1 -> ... -> TN -> Bit


where `L, M, N >= 0`.

The user can annotated a declaration as a property with the `property` keyword,
like so:

.. code-block:: cryptol

property reverseInvolution xs = reverse (reverse xs) == xs

There are several REPL commands that interact with declarations annotated as
properties, such as `:check`, `:prove`, and `:sat`. If the user runs one of
these commands without any arguments, then all such properties are used,
sequentially, as an argument.

For example, if the user loads the following module into the REPL,

.. code-block:: cryptol

module Sort where

sort : {n} (Ord n) => [n] -> [n]
sort xs = ...

isSorted : {n} (Ord n) => [n] -> Bit
isSorted xs = ...

isPermutation : {n} (Eq n) => [n] -> [n] -> Bit
isPermutation xs ys = ...

property isSorted_sort xs = isSorted (sort xs)

property isPermutation_sort = isPermutation (sort xs)

then they can run the REPL command

.. code:: sh

Sort> :check

To use random testing to check whether `isSorted_sort` and `isPermutation_sort`
hold. In other words, it is the same as running

.. code:: sh

Sort> :check isSorted_sort
Sort> :check isPermutation_sort


Testing
-------

To test a property `prop`, the user enters the following command into the
Cryptol REPL:

.. code-block::sh

Cryptol> :check prop

By default, this command performs the following:

#. Check the type of `prop`. For each type variable of kind `*`, choose a
default type that satisfies all its constraints. For the type numeric type
variables (of kind `#`), use numeric literal sampling to gather a collection
of type assignment, each of which is tested seperately. If numeric literal
sampling fails, then try to use a default assignment provided by the SMT
solver instead (this is likely to be a trivial solution).
#. If `prop` is a valid property, compute the size of its input space, otherwise
fail. If the size is at most equal to the environment variable `tests`, then
use exhaustive checking, otherwise use random testing.
#. If using exhaustive checking, then evaluate `prop` on every input. If using
random testing, evaluate `prop` on randomly sampled inputs.

The REPL command `:exhaust` will test using exhaustive testing.

Numeric Literal Sampling
^^^^^^^^^^^^^^^^^^^^^^^^

Numeric literal sampling attempts to find a well-distributed sampling of type
assignments that satisfy a set of numeric type constriants.

The subset of type constraints supported is defined by the following grammar:

.. code

<cnstr> ::= fin <var> | <exp> <rel> <exp>
<rel> ::= = | <=
<exp> ::= <exp> + <exp> | <exp> - <exp>
| <exp> * <con> | <exp> / <con> | <exp> % <con>
| <con> * <con> | <con> / <con> | <con> % <con> | <con> ^^ <con>

<var> ::= <numeric type variable>
<con> ::= <numeric constant>

Note that type constraint synonyms are expanded, e.g. `x <= y` is expanded to `y
>= x`.

The following is a high-level description of the sampling algorithm:

#. Check that the user's constraints fall into the domain of constraints handled
by this algorithm. Relations and operations handled by this algorithm are:

#. Convert the constraints into a system of linear equations and a set of
typeclass constraints (such as `fin`).
- `e1 <= e2` converts to `e1 + n = e2` where `n` is a fresh numeric type
variable.
- `... e % n ...` converts to `(... m ..., n*l + m = e)` where `l` and `n` are
fresh numeric type variable.
#. Solve the system using gaussian elimination.
#. Eliminate the denomenators of coefficients in the system.
- If the denomenators of the coefficients of variable `n` have least common
multiple `d`, then replace each appearance of `a*n` with `a*d*n'` and
introduce a new variable `n'` to the system, and replace the solution for
`n` in the system with the equation `n = d*n`. If `n` was not free but was
solved for by `n = e`, then add the equation `n' = e/d`.
- The denomenators of variables are eliminated in order of dependency, which
is guaranteed to be acyclic by gaussian elimination.
#. Sample values of free variables in the system.
- First, collect the upper bounds on variables.
- If a variable is constrained by `fin n`, then the upper bound is the
largest finite value to test.
- For an equation such as `n = 1*m + 2*l - 3*k - 4*j + 10`, the following
upper bounds are inferred: `m <= inf`, `l <= inf`, `k <= (1*m + 2*l)/3`, `j
<= (1*m + 2*l - 3*k + 10)/4`.
- Sample each variable: if a variale is upper-bounded by `inf` then sample
along an exponential distribution up to the maximum value to test and
additionally with some probability `inf`, if a variable is upper-bounded by
a finite value `c` then sample uniformly over the interval `[0, c]`.


Configuration
^^^^^^^^^^^^^

The following environment variables configure testing:

- `tests`: the total number of tests to do for a single `:check`
- `literalSampling`: whether to try to use literal sampling
- `literalSamplingBinSize`: number of tests to run for each sampling


Proving
-------

The user can try to prove that a property holds by querying an SMT solver with
the corresponding proposition. To try to prove a property `prop`, the user
enters the following command into the Cryptol REPL:

.. code:: sh

Cryptol> :prove prop

To try to check that `prop` is at least satisfiable, with a similar query to an
SMT solver, the user enters the following command into the Cryptol REPL:

.. code:: sh

Cryptol> :sat prop

Alternatively, the user can run

Configuration
^^^^^^^^^^^^^

The following environment variables configure testing:

- `prover`: name of SMT solver to use
- `smtFile`: where to dump SMT output when using an offline solver; set to "-"
to ignore
- `showExamples`: whether or not to print counterexamples
- `ignoreSafety`: tell the prover to ignore safety
- `hashConsing`: use hash caching
- `warnUninterp`: warn when lifting uninterpreted functions
1 change: 1 addition & 0 deletions docs/RefMan/RefMan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ Cryptol Reference Manual
OverloadedOperations
TypeDeclarations
Modules
Properties
FFI

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 added docs/RefMan/_build/doctrees/Properties.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.
Loading