1 /* mnemon - A memory training library
3 * Copyright © 2006,2011 Carl Worth
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
20 #ifndef MNEMON_H_INCLUDED
21 #define MNEMON_H_INCLUDED
23 #define unused(foo) foo __attribute__((unused))
27 typedef struct _item {
35 unsigned int items_size;
36 unsigned int num_items;
41 CATEGORY_ORDER_RANDOM,
42 CATEGORY_ORDER_SEQUENTIAL
45 typedef struct _category {
47 unsigned int items_size;
48 unsigned int num_items;
51 /* Support sequential introduction of items from bin 0 */
52 category_order_t order;
53 /* Support categories where responses are timed (0.0 == disable). */
55 unsigned int bin_zero_head;
56 /* Support challenges of non-text types (image, audio, etc.) */
58 /* Whether to repeat afterwards (for a little extra reinforcement) */
62 typedef struct _mnemon {
65 unsigned int categories_size;
66 unsigned int num_categories;
67 category_t *categories;
69 unsigned int bins_size;
70 unsigned int num_bins;
74 /* Initialize a new mnemon object. This function must be called before
75 * any other mnemon functions are used. */
77 mnemon_init (mnemon_t *mnemon);
79 /* Inidicate the caller is finished with a mnemon object. Free all
80 * resources associated with this object. After this call, the given
81 * mnemon object should not be passed to any other menmon function,
82 * (except mnemon_init to start over). */
84 mnemon_fini (mnemon_t *mnemon);
86 /* Load a specific category of mnemon challenges. The name should
87 * indicate the name of a file within the user's .mnemon directory. */
89 mnemon_load_category (mnemon_t *mnemon,
92 /* Load all categories of mnemon challenges.
94 * This is equivalent to calling mnemon_load_category for all files
95 * found within the user's .mnemon directory. */
97 mnemon_load (mnemon_t *mnemon);
99 /* Select the next (weighted) random item to challenge the user.
101 * This function provides four return values (and yes, that's
102 * exceedingly awkward and a simpler interface should be designed to
105 * bin: The bin from which the item was selected
107 * item_index: The index within the bin of the slected item
109 * category: The name of the category for this item
111 * introduced: A flag indicating whether this is a newly
112 * introduced item. Items from bin 0 always count
113 * as newly introduced. If there is no bin 0,
114 * then items from the lowest non-negative bin
115 * will be flagged as introduced.
117 * The selection system is designed to rapidly reinforce items needing
118 * to be learned and provide exponentially less reinforcement for
119 * items as mastery is displayed. This is achieved by storing the
120 * items in a series of numbered bins.
122 * Items start in bin 0 indicating that they have never been presented
123 * to a user. When an item is presented to the user and answered
124 * correctly, it is moved into the bin of the next higher number.
126 * However, when an item is answered incorrectly, it is moved directly
127 * to bin -2 (if coming from a bin of a positive number), or the bin
128 * of the next lower integer (more negative) if coming from a bin of a
131 * When selecting a new item to challenge, first a bin is chosen
132 * (considering only the non-empty bins). The bin with the lowest
133 * number is the most likely to be chosen, while each succesively-
134 * higher-numbered bin has a probability one-half of that of the
138 mnemon_select_item (mnemon_t *mnemon,
141 category_t **category_ret,
142 int *introduced_ret);
144 /* Update an item based on a user's answer (correct or incorrect).
146 * The bin and item_index should be exactly as returned by
147 * mnemon_select_item. The correct flag should indicate whether the
148 * user answered the challenge correctly or not, (and should only
149 * count as correct if the answer was within the time limit, if any).
151 * The item will be moved from its current bin to a new bin based on
152 * whether the challenge was answered correctly. The bin updates are
155 * If the answer was correct:
156 * Increase the bin number by 1
157 * If the new bin number is 0, set it to 1 (0 bin is for new items)
159 * If the answer was incorrect:
160 * If the old bin was positive, move to bin -2 (for extra training)
161 * Otherwise decrease the bin number by 1
163 * Note: All item and bin movement is kept only in memory. In order to
164 * save this progress to disk, the caller must call mnemon_save.
167 mnemon_score_item (mnemon_t *mnemon,
169 unsigned int item_index,
172 /* Save the user's progress by updating the category files in the
173 * users .mnemon directory. */
175 mnemon_save (mnemon_t *mnemon);
177 /* Remove a bin of a particular number.
179 * This can be useful in situations such as wanting to practice
180 * mastery of learned items without mixing in new items that the user
181 * has never seen before. This could be achieved by removing bin 0,
185 mnemon_remove_bin (mnemon_t *mnemon, int bin_number);
187 /* Find the category to which an item belongs. */
189 mnemon_item_category (mnemon_t *mnemon,
192 /* Get a category by name if it exists */
194 mnemon_get_category_if_exists (mnemon_t *mnemon,