You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[`tox`](https://tox.readthedocs.io/en/latest/) is used to run the tests and linters. After installing it, run:
6
6
7
-
-`tox -e py3`
8
-
- Set notation for Internal nodes (rather than lists)
9
-
- Use of `@memoize`
10
-
- Use of Typing / mypy
7
+
```
8
+
tox
9
+
```
10
+
11
+
This will install and run all the tooling.
12
+
13
+
`tox` aborts early if one of the steps fails. To run just the tests (for example if you can't get `mypy` to work), install and run [`pytest`](https://docs.pytest.org/en/latest/getting-started.html). To run just one particular test, run `pytest -k <name of test>`.
14
+
15
+
## Mypy
16
+
17
+
[Mypy](https://mypy.readthedocs.io/en/stable/) is used for static typing. This is also managed by `tox`.
18
+
19
+
You can look at the existing code for cues. If you can't figure it out, just leave it be and we'll look at it during code review.
20
+
21
+
## Hypothesis
22
+
23
+
[Hypothesis](https://hypothesis.readthedocs.io/en/latest/) is used for property-based testing: it generates random sentences for tests to use. See the existing tests for examples.
24
+
25
+
It's ideal for a feature to have both tests that do use Hypothesis and tests that don't.
26
+
27
+
## Memoization
28
+
29
+
[Memoization](https://en.wikipedia.org/wiki/Memoization) is used in various places to avoid computing the same thing multiple times. A memoized function remembers past calls so it can return the same return value again in the future.
30
+
31
+
A downside of memoization is that it increases memory usage.
32
+
33
+
It's used in two patterns throughout the codebase:
34
+
35
+
### Temporary internal memoization with `@memoize`
36
+
37
+
This is used for functions that run on individual nodes of sentences, within a method. For example:
38
+
39
+
```python
40
+
defheight(self) -> int:
41
+
"""The number of edges between here and the furthest leaf."""
42
+
@memoize
43
+
defheight(node: NNF) -> int:
44
+
ifisinstance(node, Internal) and node.children:
45
+
return1+max(height(child) for child in node.children)
46
+
return0
47
+
48
+
return height(self)
49
+
```
50
+
51
+
Because the function is defined inside the method, it's garbage collected along with its cache when the method returns. This makes sure we don't keep all the individual node heights in memory indefinitely.
52
+
53
+
### Memoizing sentence properties with `@weakref_memoize`
54
+
55
+
This is used for commonly used methods that run on whole sentences. For example:
56
+
57
+
```python
58
+
@weakref_memoize
59
+
defvars(self) -> t.FrozenSet[Name]:
60
+
"""The names of all variables that appear in the sentence."""
61
+
returnfrozenset(node.name
62
+
for node inself.walk()
63
+
ifisinstance(node, Var))
64
+
```
65
+
66
+
This lets us call `.vars()` often without worrying about performance.
67
+
68
+
Unlike the other decorator, this one uses `weakref`, so it doesn't interfere with garbage collection. It's slightly less efficient though, so the temporary functions from the previous section are better off with `@memoize`.
69
+
70
+
## Documentation
71
+
72
+
Methods are documented with reStructuredText inside docstrings. This looks a little like markdown, but it's different, so take care and look at other docstrings for examples.
73
+
74
+
Documentation is automatically generated and ends up at [Read the Docs](https://python-nnf.readthedocs.io/en/latest/).
75
+
76
+
To build the documentation locally, run `make html` inside the `docs/` directory. This generates a manual in `docs/_build/html/`.
77
+
78
+
New modules have to be added to `docs/nnf.rst` to be documented.
79
+
80
+
## Style/miscellaneous
81
+
82
+
- Prefer sets over lists where it make sense. For example, `Or({~c for c in children} | {aux})` instead of `Or([~c for c in children] + [aux])`.
Copy file name to clipboardExpand all lines: docs/caveats.rst
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,11 +44,11 @@ Decomposability and determinism
44
44
45
45
A lot of methods are much faster to perform on sentences that are decomposable or deterministic, such as model enumeration.
46
46
47
-
Decomposability is automatically detected. However, you can skip the check if you already know whether the sentence is decomposable or not, by passing ``decomposable=True`` or ``decomposable=False`` as a keyword argument.
47
+
Decomposability is automatically detected.
48
48
49
-
Determinism is too expensive to automatically detect, but it can give a huge speedup. If you know a sentence to be deterministic, pass ``deterministic=True`` as a keyword argument to take advantage.
49
+
Determinism is too expensive to automatically detect, but it can give a huge speedup. If you know a sentence to be deterministic, run ``.mark_deterministic()`` to enable the relevant optimizations.
50
50
51
-
A compiler like `DSHARP <https://github.com/QuMuLab/dsharp>`_ may be able to convert some sentences into equivalent deterministic decomposable sentences. The output of DSHARP can be loaded using the :mod:`nnf.dsharp` module.
51
+
A compiler like `DSHARP <https://github.com/QuMuLab/dsharp>`_ may be able to convert some sentences into equivalent deterministic decomposable sentences. The output of DSHARP can be loaded using the :mod:`nnf.dsharp` module. Sentences returned by :func:`nnf.dsharp.compile` are automatically marked as deterministic.
0 commit comments