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 {
41 CATEGORY_ORDER_RANDOM,
42 CATEGORY_ORDER_SEQUENTIAL
50 CHALLENGE_TYPE_TEXT_TO_SPEECH
53 typedef struct _category {
59 /* Support sequential introduction of items from bin 0 */
60 category_order_t order;
61 /* Support categories where responses are timed (0.0 == disable). */
64 /* Support challenges of non-text types (image, audio, etc.) */
65 challenge_type_t challenge_type;
66 /* Whether to repeat afterwards (for a little extra reinforcement) */
70 typedef struct _mnemon {
75 category_t *categories;
82 /* Initialize a new mnemon object. This function must be called before
83 * any other mnemon functions are used. */
85 mnemon_init (mnemon_t *mnemon);
87 /* Inidicate the caller is finished with a mnemon object. Free all
88 * resources associated with this object. After this call, the given
89 * mnemon object should not be passed to any other menmon function,
90 * (except mnemon_init to start over). */
92 mnemon_fini (mnemon_t *mnemon);
94 /* Load a specific category of mnemon challenges. The name should
95 * indicate the name of a file within the user's .mnemon directory. */
97 mnemon_load_category (mnemon_t *mnemon,
100 /* Load all categories of mnemon challenges.
102 * This is equivalent to calling mnemon_load_category for all files
103 * found within the user's .mnemon directory. */
105 mnemon_load (mnemon_t *mnemon);
107 /* Select the next (weighted) random item to challenge the user.
109 * This function provides four return values (and yes, that's
110 * exceedingly awkward and a simpler interface should be designed to
113 * bin: The bin from which the item was selected
115 * item_index: The index within the bin of the slected item
117 * category: The name of the category for this item
119 * introduced: A flag indicating whether this is a newly
120 * introduced item. Items from bin 0 always count
121 * as newly introduced. If there is no bin 0,
122 * then items from the lowest non-negative bin
123 * will be flagged as introduced.
125 * The selection system is designed to rapidly reinforce items needing
126 * to be learned and provide exponentially less reinforcement for
127 * items as mastery is displayed. This is achieved by storing the
128 * items in a series of numbered bins.
130 * Items start in bin 0 indicating that they have never been presented
131 * to a user. When an item is presented to the user and answered
132 * correctly, it is moved into the bin of the next higher number.
134 * However, when an item is answered incorrectly, it is moved directly
135 * to bin -2 (if coming from a bin of a positive number), or the bin
136 * of the next lower integer (more negative) if coming from a bin of a
139 * When selecting a new item to challenge, first a bin is chosen
140 * (considering only the non-empty bins). The bin with the lowest
141 * number is the most likely to be chosen, while each succesively-
142 * higher-numbered bin has a probability one-half of that of the
146 mnemon_select_item (mnemon_t *mnemon,
149 category_t **category_ret,
150 int *introduced_ret);
152 /* Update an item based on a user's answer (correct or incorrect).
154 * The bin and item_index should be exactly as returned by
155 * mnemon_select_item. The correct flag should indicate whether the
156 * user answered the challenge correctly or not, (and should only
157 * count as correct if the answer was within the time limit, if any).
159 * The item will be moved from its current bin to a new bin based on
160 * whether the challenge was answered correctly. The bin updates are
163 * If the answer was correct:
164 * Increase the bin number by 1
165 * If the new bin number is 0, set it to 1 (0 bin is for new items)
167 * If the answer was incorrect:
168 * If the old bin was positive, move to bin -2 (for extra training)
169 * Otherwise decrease the bin number by 1
171 * Note: All item and bin movement is kept only in memory. In order to
172 * save this progress to disk, the caller must call mnemon_save.
175 mnemon_score_item (mnemon_t *mnemon,
177 unsigned int item_index,
180 /* Save the user's progress by updating the category files in the
181 * users .mnemon directory. */
183 mnemon_save (mnemon_t *mnemon);
185 /* Remove a bin of a particular number.
187 * This can be useful in situations such as wanting to practice
188 * mastery of learned items without mixing in new items that the user
189 * has never seen before. This could be achieved by removing bin 0,
193 mnemon_remove_bin (mnemon_t *mnemon, int bin_number);
195 /* Find the category to which an item belongs. */
197 mnemon_item_category (mnemon_t *mnemon,
200 /* Get a category by name if it exists */
202 mnemon_get_category_if_exists (mnemon_t *mnemon,