335 Commits

Author SHA1 Message Date
fd74290d39 Clean up the handling of codelet arguments. NFC.
Just make all argument-passing explicit; which means the coderack
no longer cares about `oldCodelet` (which was being used only to
get the implicit arguments to the new codelet).
2017-04-18 01:12:27 -07:00
f08c57fac3 Fix some flake8 spam. NFC. 2017-04-18 01:12:27 -07:00
7388eaec54 Teach Context to be self-sufficient. NFC.
You can now create and run a Copycat instance by just saying
`Context().run('abc', 'abd', 'efg', 100)`!
2017-04-18 01:12:27 -07:00
12283b0836 Move some harmless imports to file scope. NFC. 2017-04-18 01:12:27 -07:00
30f8c623e5 Demagic workspaceFormulas.py. NFC. 2017-04-18 01:12:26 -07:00
3732ae8475 Major overhaul of "randomness" throughout.
- Nobody does `import random` anymore.

- Random numbers are gotten from `ctx.random`, which is an object
of type `Randomness` with all the convenience methods that used to
be obnoxious functions in the `formulas` module.

- Every place that was using `random.random()` to implement the
equivalent of Python3 `random.choices(seq, weights)` has been updated
to use `ctx.random.weighted_choice(seq, weights)`.

This has a functional effect, since the details of random number
generation have changed. The *statistical* effect should be small.
I do observe that Copycat is having trouble inventing the "mrrjjjj"
solution right now (even in 1000 test runs), so maybe something is
slightly broken.
2017-04-18 01:12:26 -07:00
8fdb9d06e6 Demagic everything in formulas.py. NFC.
Only one file left to go!
2017-04-18 01:12:26 -07:00
6165f77d3c Move a couple single-use helpers from formulas to codeletMethods. NFC. 2017-04-18 01:12:26 -07:00
ff389bd653 Move temperatureAdjustedFoo into the Temperature class. NFC.
And demagic all the callers of this function. Notice that with this
move, it becomes *harder* for these "getAdjustedFoo" functions to
access other contextual state, such as the state of the coderack
and the state of the workspace. This is a good thing for modularity
but possibly a misfeature in terms of flexibility-re-logic-changes.
2017-04-18 01:12:26 -07:00
99dc05f829 Demagic everything except the formulas and workspaceFormulas. NFC. 2017-04-18 01:12:26 -07:00
7581a328f7 Give WorkspaceString a self.ctx. Demagic all WorkspaceObjects. NFC. 2017-04-18 01:12:26 -07:00
bd4790a3f1 Kill all the globals (except context)! NFC. 2017-04-18 01:12:25 -07:00
22b15c3866 Demagic all the WorkspaceStructure children who aren't WorkspaceObjects. NFC. 2017-04-18 01:12:25 -07:00
b16666e4d7 Demagic WorkspaceStructure. NFC. 2017-04-18 01:12:25 -07:00
482c374886 Give every WorkspaceStructure a self.ctx member variable.
...which is currently initialized "by magic"; but removing that magic
will be the next step.
2017-04-18 01:12:25 -07:00
25ba9bfe93 (Almost) contextualize all the things! NFC.
The only top-level imports now are needed for inheritance relationships.

The only function-level imports are HACKS that I need to FIXME; they
all `from context import context as ctx` and then fetch whatever they
actually need from the `ctx` just as if `ctx` had been passed in by the
caller instead of fetched from this magical global storage.
2017-04-18 01:12:25 -07:00
3096c49fb9 This is working! 2017-04-18 01:12:24 -07:00
e6cbb347de testing 2017-04-18 01:12:24 -07:00
965bd13298 Disentangle another reference to slipnet. 2017-04-18 01:12:24 -07:00
6871d7a86c Disentangle one reference to slipnet. 2017-04-18 01:12:24 -07:00
cc288161a4 Major overhaul of temperature logic. Behavioral change.
I think the reason the temperature logic was so confused in the old code
is because the Java code has a class `Temperature` that is used for
graphical display *and* two variables in `formulas` that are used for
most of the actual math. But somewhere along the line, some of the code
in `formulas.java` started reading from `Temperature.value` as well.
So the Python code was just faithfully copying that confusion.

The actual abstraction here is a very simple "temperature" object
with a stored value. It can be "clamped" to 100.0 for a given period.
The only complication is that one of the codelets (the rule-transformer
codelet) wants to get access to the "actual value" of the temperature
even when it is clamped.

The Python rule-transformer codelet also had a bug: it was accidentally
setting `temperature.value` on the `temperature` module instead of on
the `temperature.temperature` object! This turned some of its behavior
into a no-op, for whatever that's worth.

Lastly, the calculation of `finalTemperature` in the main program can
now report 100.0 if the answer is found while the temperature is clamped.
I don't fully understand why this didn't happen in the old code.
I've hacked around it with `temperature.last_unclamped_value` for now,
but I should TODO FIXME.
2017-04-18 01:12:24 -07:00
6a56fdd898 Bikeshed some time-related names. 2017-04-18 01:12:23 -07:00
e5d44ae75c Bah! Remove CoderackPressures as it's not hooked up to anything. 2017-04-18 01:12:23 -07:00
44e5a8c59f Decouple Coderack from Slipnet. 2017-04-18 01:12:23 -07:00
e17dc2aa45 Untangle some initialization code. Assert invariants. NFC. 2017-04-18 01:12:23 -07:00
fa2142efaa Replace the coderack->workspaceFormulas coupling with coderack->workspace.
This feels slightly less tangled. Still needs work.
2017-04-18 01:12:23 -07:00
63b3fd4999 Decouple Slipnode from the global slipnet. 2017-04-18 01:12:23 -07:00
10f65fcf55 Inline the constant slipnet.timeStepLength. NFC. 2017-04-18 01:12:23 -07:00
d2436601ba Decouple coderack: remove global variable coderack.
Or at least, hide it upstairs in `copycat.py`.
`copycat.py` will eventually become a class, I'm guessing,
but let's pull everything into it first.
2017-04-18 01:12:22 -07:00
f2e28c0e19 Clean some dead code in __calculateIntraStringHappiness.
Indeed, it's dead in the Java version too.
2017-04-18 01:12:22 -07:00
ae0434d910 codeletMethods.py: Replace some random.random()s with coinFlip().
There is a bugfix in here as well: one of the probabilities was
being taken the wrong way around. The result should have been to
make single-letter groups very often, I guess? Fixing this bug
doesn't show any change in Copycat's macro behavior, except that
it seems like average temperatures have gotten hotter.
2017-04-18 01:12:22 -07:00
a3b122b75c Massive overhaul of "codelet methods" and the coderack.
Should be no functional change, but this gets rid of one circular
import (some codelet methods need a pointer to the coderack, but
they should be getting that pointer from their caller, not from
the global scope) and a lot of reflection-magic.
2017-04-18 01:12:22 -07:00
f37b88d032 random.seed(42) for testing; TODO revert me 2017-04-18 01:12:22 -07:00
3d630ba389 Decouple temperature from coderack. 2017-04-18 01:12:21 -07:00
51178c049d Inline trivial function Bond.get_source(). NFC. 2017-04-18 01:12:21 -07:00
a41b639487 Remove global variable coderackPressures (bugfix?)
Before this patch, `coderackPressures.updatePressures()` was always
a no-op, as evidenced by the until-now-harmless misspelling of Python's
list `remove` operation as `removeElement`.

I can't tell if this broke anything; my tests still pass.
2017-04-18 01:12:21 -07:00
5423d078e8 Move updateTemperature() from workspaceFormulas to workspace.
And remove dead and/or logging code to simplify the logic.
2017-04-18 01:12:21 -07:00
8171b68cbe Remove some unused global variables. NFC. 2017-04-18 01:12:20 -07:00
6fcf2f3350 git rm grouprun.py 2017-04-18 01:12:20 -07:00
d60ba5277c Remove a crash-causing line in slipnet.py.
Without this patch, `python main.py abc aabbcc milk` will reliably crash.
I believe what happens here is that we initialize all the slipnodes and
everything, and then `slipnet.predecessor` becomes `None`, which means
that if that concept ever arises on its own (vs. arising as the "opposite"
of "successor"), we'll be passing around `None` instead of a proper `Slipnode`
and everything goes sideways.

This line doesn't correspond obviously to anything in the Java code,
so I think it's just bogus --- an experiment in "brain damage" that was
accidentally committed?
2017-04-18 01:07:51 -07:00
0ff9d49111 Further Pythonicity and flake8 cleanup. NFC. 2017-04-16 18:22:57 -07:00
31323cd2bc Add some end-to-end tests!
These tests are intended to protect against regressions in the high-level
behavior of Copycat. They're not super precise, and they're VERY slow.
2017-04-16 18:22:57 -07:00
8e10814802 Further Pythonicity; and remove a bunch of logging from the inner loop. 2017-04-16 01:19:36 -07:00
77bfaaf5a7 Further refactor the main harness. Print average time for each solution. 2017-04-16 00:55:18 -07:00
3103f54ada Untie some loopy logic in addCodelet. (Functional change!) 2017-04-15 23:08:12 -07:00
e094160dcd More Pythonic cleanups. NFC. 2017-04-15 23:07:28 -07:00
a2260cdaf6 Run multiple iterations. Print final temperatures. Reduce stdout spew.
This makes the output of the program more closely resemble that of the
original Copycat described in "FCCA" page 236:

> [T]he average final temperature of an answer can be thought of as
> the program's own assessment of that answer's quality, with lower
> temperatures meaning higher quality.

For example, running `python main.py abc abd ijk 100` produced the
following output:

    ijl: 98 (avg temp 16.0)
    jjk: 1 (avg temp 56.3)
    ijk: 1 (avg temp 57.9)

And for `python main.py abc abd ijkk 100`:

    ijkkk: 2 (avg temp 19.8)
    ijkl: 51 (avg temp 28.1)
    ijll: 46 (avg temp 28.9)
    djkk: 1 (avg temp 77.4)
2017-04-15 22:29:46 -07:00
ed1d95896e More Pythonic idioms in coderackPressure.py.
No functional change.
2017-04-15 22:29:46 -07:00
88ee2ddd8d Spelling: neighbour -> neighbor.
The old code mixed both spellings; we might as well be consistent.
2017-04-15 22:29:46 -07:00
5735888d02 Minor Pythonicity cleanups.
No functional change.
2017-04-14 11:37:43 -07:00