]> git.cworth.org Git - mnemon/blob - mnemon.h
Further separation of mnemon main program from mnemon library.
[mnemon] / mnemon.h
1 /* mnemon - A memory training library
2  *
3  * Copyright © 2006,2011 Carl Worth
4  *
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)
8  * any later version.
9  *
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.
14  *
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."
18  */
19
20 #ifndef MNEMON_H_INCLUDED
21 #define MNEMON_H_INCLUDED
22
23 #define unused(foo) foo __attribute__((unused))
24
25 typedef int bool_t;
26
27 typedef struct _item {
28     int score;
29     char *challenge;
30     char *response;
31 } item_t;
32
33 typedef struct _bin {
34     int score;
35     int items_size;
36     int num_items;
37     item_t **items;
38 } bin_t;
39
40 typedef enum {
41     CATEGORY_ORDER_RANDOM,
42     CATEGORY_ORDER_SEQUENTIAL
43 } category_order_t;
44
45 typedef enum {
46     CHALLENGE_TYPE_TEXT,
47     CHALLENGE_TYPE_IMAGE,
48     CHALLENGE_TYPE_AUDIO,
49     CHALLENGE_TYPE_MIDI,
50     CHALLENGE_TYPE_TEXT_TO_SPEECH
51 } challenge_type_t;
52
53 typedef struct _category {
54     char *name;
55     int items_size;
56     int num_items;
57     item_t *items;
58
59     /* Support sequential introduction of items from bin 0 */
60     category_order_t order;
61     /* Support categories where responses are timed (0.0 == disable). */
62     double time_limit;
63     int bin_zero_head;
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) */
67     bool_t repeat;
68 } category_t;
69
70 typedef struct _mnemon {
71     char *dir_name;
72
73     int categories_size;
74     int num_categories;
75     category_t *categories;
76
77     int bins_size;
78     int num_bins;
79     bin_t *bins;
80 } mnemon_t;
81
82 /* Initialize a new mnemon object. This function must be called before
83  * any other mnemon functions are used. */
84 void
85 mnemon_init (mnemon_t *mnemon);
86
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). */
91 void
92 mnemon_fini (mnemon_t *mnemon);
93
94 /* Load a specific category of mnemon challenges. The name should
95  * indicate the name of a file within the user's .mnemon directory. */
96 void
97 mnemon_load_category (mnemon_t          *mnemon,
98                       const char        *name);
99
100 /* Load all categories of mnemon challenges.
101  *
102  * This is equivalent to calling mnemon_load_category for all files
103  * found within the user's .mnemon directory. */
104 void
105 mnemon_load (mnemon_t *mnemon);
106
107 /* Select the next (weighted) random item to challenge the user.
108  *
109  * This function provides four return values (and yes, that's
110  * exceedingly awkward and a simpler interface should be designed to
111  * replace this):
112  *
113  *      bin:            The bin from which the item was selected
114  *
115  *      item_index:     The index within the bin of the slected item
116  *
117  *      category:       The name of the category for this item
118  *
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.
124  *
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.
129  *
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.
133  *
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
137  * negative number.
138  *
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
143  * previous bin.
144  */
145 void
146 mnemon_select_item (mnemon_t     *mnemon,
147                     bin_t       **bin_ret,
148                     int          *item_index_ret,
149                     category_t  **category_ret,
150                     int          *introduced_ret);
151
152 /* Update an item based on a user's answer (correct or incorrect).
153  *
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).
158  *
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
161  * as follows:
162  *
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)
166  *
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
170  *
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.
173  */
174 void
175 mnemon_score_item (mnemon_t *mnemon,
176                    bin_t *bin,
177                    unsigned int item_index,
178                    bool_t correct);
179
180 /* Save the user's progress by updating the category files in the
181  * users .mnemon directory. */
182 void
183 mnemon_save (mnemon_t *mnemon);
184
185 /* Remove a bin of a particular number.
186  *
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,
190  * for example.
191  */
192 void
193 mnemon_remove_bin (mnemon_t *mnemon, int bin_number);
194
195 /* Find the category to which an item belongs. */
196 category_t *
197 mnemon_item_category (mnemon_t  *mnemon,
198                       item_t    *item);
199
200 /* Get a category by name if it exists */
201 category_t *
202 mnemon_get_category_if_exists (mnemon_t     *mnemon,
203                                const char   *name);
204
205
206 #endif