Sure, here's the gist of how it works.
- When Trane is asked for a batch of exercises, it performs a depth-first search of every branch in the dependency graph. It picks up exercises as it goes along, and stops exploring a branch when the dependencies of the last node are not met.
- Each exercise is given a 1-5 score by the student and those scores are used to produce a combined score, rather than compute a date on which the exercise should be reviewed. Two reasons:
- Trane is also meant to be used to learn skills, which do not fit the assumptions made by the SuperMemo algorithm.
- I believe most of the gains come from regularly being reminded to perform an exercise, so even a simple scoring algorithm should get most of the gains. Eventually, I want to replace the existing scoring with something more complicated that also makes a distinction between memorization and skill exercises to get better results. But based on my testing, this works for the most part as is and the gains to be made from more complicated algorithms are marginal.
- Once you get exercises from performing the search, you reduce that number into the final batch by grouping exercises based on difficulty and selecting a percentage from each bucket. This is done to make sure not too many very difficult or easy exercises are included in each batch.
There's also some elements of randomness added to prevent the same exercises from appearing all the time. For example, the branches are explored in random order and the elements from each difficulty bucket are selected at random. But that is the gist of it.