There are two major changes in this patch. The first is that sequence maps
now have special representations for point updates, of the sort produced by
the 'update' and 'updateEnd' primtives. These updates are stored in a
finite map, rather than as a functional-update thunk using lambdas; this
reduces memory usage and improves time efficecy of sequences defined by
sequences of updates.
The second change is that the caching policy for sequences is changed
to retain all previously-calculated values. This is a change from the
previous LRU policy, which retained only a small finite number of previous
values. Benchmarking showed that unbounded memoization was better for
performance in essentially all cases over both an LRU and an adaptive
caching strategy. The potential downside is that we may retain values
longer than necessary. If this becomes a problem, we may need to revisit
this decision.
This greatly increases mutator productivity, and thus provides
significant speedups on some examples. The tradeoff with
larger nurseries is the potential for long GC pause times.
This is probably acceptable tradeoff for a tool like Cryptol,
despite the potential for unresponsiveness at the REPL.
Fix some minor conflicts in the test suite.
Conflicts:
tests/issues/issue002.icry.fails
tests/issues/issue148.icry.stdout
tests/issues/issue198.icry.stdout
tests/issues/issue214.icry.stdout
tests/issues/issue290v2.icry.stdout
tests/issues/issue312.icry.fails
The major change in this patch is to add a new type of 'WordValue'
which is always used to represent finite sequences of bits. A word
value is either a packed word, or a sequence of lazy bits. The 'VSeq'
constructor, in constrast, is now never used for a finite sequence of
bits.
This avoids certain thorny problems that arise when trying to faithfully
implement the lazy semantics of Cryptol. We now do not have to commit
to a value at type '[n]' being represented as a packed word or as an
unpacked word until relatively late. This allows us to perform type-directed
eta-expansion at every recursive call before we know how words will be represented.
This patch fixes all the outstanding strictness bugs that I know of.
Unfortunately, we seem to lose some ground on performance. The new evaluator
is now about 5% slower than the old one on the AES benchmark, and quite a bit
slower on the SHA1 benchmark. Fortunately, the use if LRU caches for memoization
of sequences seems to keep heap usage to manageable levels; so programs generally
complete, even if they take a long time.
The definitions added in #299 cause a regression in Prelude typechecking
performance. Until we sort out the performance, we'll keep these
definitions in the module `Cryptol::Extras`.
We're only using this package for 7.8 compatibility, which will end when
GHC 8.0 is released soon. For now, just limit to the older version to
avoid import errors.
This is to set up improvements to the cryptol-server, and therefore
pycryptol interface.
This patch also fixes a regression in pretty-printing output caused by a
previous error in fixity of the `<>` operator
This notably adds a `MonadBaseControl` instance for the `REPL` monad so
that we can catch asynchronous exceptions in the middle of `REPL`
computations. Since this is a generalization of Haskeline's exception
support, that orphan instance for the console executable is now in terms
of this new instance.
This removes the `self-contained` flag, since it is fine for all builds
to have the baked-in prelude as a last resort. Tinkerers can still
change the prelude as long as it's in the search path.
Also removes some unnecessary extra prelude loading by the Cryptol
server by means of a new command
The benchmark suite no longer uses the `iteSolver` option.
Added a dependency on `deepseq-generics` so that the `NFData` instances
work correctly in Stackage LTS 2. Versions of `deepseq` before 1.4 have
a default instance that amounts to WHNF rather than NF, so benchmarks
were being measured incorrectly.
Attempt to normalize equality constraints involving a single unification
variable into a form where that variable is alone on one side of the equation.
Applying this normalization before attempting to simplify goals seems to clean
up some cases that the solver wasn't able to deal with.
By moving `build-depends` under the `if flag(server)` check. The diff
is a little hard to read, because I did not change the indentation of
the dependencies. Thanks @elliottt for the fix!
once merged, we'll disable the build by default so we don't incur the
zeromq dependency, but it would be nice to eventually make the server
the core of all our clients
The intent here is to allow users to write expressions to disk without
copy and pasting the ASCII representation into some other system (ex: a
Haskell script) to perform the actual file write.
Use:
```
Cryptol> :write /tmp/foo "hello Cryptol!\n"
Cryptol> :!cat /tmp/foo
hello Cryptol!
Cryptol> let var = "Complex computation\n"
Cryptol> :write /tmp/foo var
Cryptol> :!cat /tmp/foo
Complex computation
Cryptol> let var = 32 : [32]
Cryptol> :write /tmp/foo var
Can not write expression of types other than [n][8]. Type was: [32]
```
Also: Tab completion for FileExprArg commands.
This is rather half-done. The actual completion should depend on if
the user is inputting the 1st or 2nd argument, but we can't really
determine that without live parsing which is probably a largish change.
Instead, we just assume the completion is wrt the expr, since the file
will likely be new and not be able to tab-complete in real uses.
- Move the stackage file so it's not on by default (will test with it on
Jenkins instead of all the time)
- Use CPP to remove unnecessary import warnings in 7.10
We accidentally forgot to merge the 2.2.2 changes back into master, but
since they were mostly temporary fixes pending SBV updates, this didn't
cause any problems. This commit is just to be tidy :)
- Move the stackage file so it's not on by default (will test with it on
Jenkins instead of all the time)
- Use CPP to remove unnecessary import warnings in 7.10
This helps with #18 and should also reduce the number of unnecessary
recompiles that were triggered by the Makefile and/or cabal. The cabal
build type is now Simple.
Most of the complication in the TH.hs module is due to the various
places the current git hash might be stored:
1. Detached HEAD: the hash is in `.git/HEAD`
2. On a branch or tag: the hash is in a file pointed to by `.git/HEAD`
in a location like `.git/refs/heads`
3. On a branch or tag but in a repository with packed refs: the hash is
in `.git/packed-refs`
These situations all arise under normal development workflows and on the
Jenkins build machines, but there might be further scenarios that cause
problems. The tradeoff seems worthwhile though as now projects that
build Cryptol as a dependency wind up having to rebuild Cryptol far less
frequently.
Many of our projects that depend on Cryptol break because we forgot to
drag along `Cryptol.cry` or it just can't work out where it is from the
perspective of the other executable.
There's now a new flag `self-contained` in `cryptol.cabal` that is on by
default that bakes the contents of the Prelude into the library, so that
it can be reproduced on demand.
This is really a hack at this point because the module system bakes in
the assumption that a module has an associated file path, so we actually
have to write the contents to a tmp file before reading them back
in. Let's do better than this in the future.
This option is disabled for targets in the Makefile because we want the
standalone interpreter to be using the distribution's `Cryptol.cry`.
Makefile now has two modes depending on whether PREFIX is set. If it's
not, we try to make the distribution as relocatable as possible, meaning
we don't rely on the baked-in-by-cabal data directory. If it is set, we
do use that path.