]> git.cworth.org Git - mnemon/blobdiff - mnemon.h
Yet more "signed vs. unsigned" warning fixes.
[mnemon] / mnemon.h
index d33cb742ac000cb2b461c9ac99bbc83142208c61..27e02a075b52db8b352db442e3211c1bac68486d 100644 (file)
--- a/mnemon.h
+++ b/mnemon.h
 #ifndef MNEMON_H_INCLUDED
 #define MNEMON_H_INCLUDED
 
-typedef struct _bin bin_t;
-typedef struct _category category_t;
+#define unused(foo) foo __attribute__((unused))
+
+typedef int bool_t;
+
+typedef struct _item {
+    int score;
+    char *challenge;
+    char *response;
+} item_t;
+
+typedef struct _bin {
+    int score;
+    unsigned int items_size;
+    unsigned int num_items;
+    item_t **items;
+} bin_t;
+
+typedef enum {
+    CATEGORY_ORDER_RANDOM,
+    CATEGORY_ORDER_SEQUENTIAL
+} category_order_t;
+
+typedef struct _category {
+    char *name;
+    unsigned int items_size;
+    unsigned int num_items;
+    item_t *items;
+
+    /* Support sequential introduction of items from bin 0 */
+    category_order_t order;
+    /* Support categories where responses are timed (0.0 == disable). */
+    double time_limit;
+    unsigned int bin_zero_head;
+    /* Support challenges of non-text types (image, audio, etc.) */
+    char *challenge_type;
+    /* Whether to repeat afterwards (for a little extra reinforcement) */
+    bool_t repeat;
+} category_t;
 
 typedef struct _mnemon {
     char *dir_name;
 
-    int categories_size;
-    int num_categories;
+    unsigned int categories_size;
+    unsigned int num_categories;
     category_t *categories;
 
-    int bins_size;
-    int num_bins;
+    unsigned int bins_size;
+    unsigned int num_bins;
     bin_t *bins;
-
-    int to_introduce;
-    int to_master;
-    int unlearned;
-    int mastered;
 } mnemon_t;
 
 /* Initialize a new mnemon object. This function must be called before
@@ -65,13 +96,28 @@ mnemon_load_category (mnemon_t              *mnemon,
 void
 mnemon_load (mnemon_t *mnemon);
 
-/* Run a series of memory challenges acoording to the to_introduce and
- * to_master counters as set on the given mnemon object.
+/* Select the next (weighted) random item to challenge the user.
  *
- * The challenge system is designed to rapidly reinforce items needing
+ * This function provides four return values (and yes, that's
+ * exceedingly awkward and a simpler interface should be designed to
+ * replace this):
+ *
+ *     bin:            The bin from which the item was selected
+ *
+ *     item_index:     The index within the bin of the slected item
+ *
+ *     category:       The name of the category for this item
+ *
+ *     introduced:     A flag indicating whether this is a newly
+ *                     introduced item. Items from bin 0 always count
+ *                     as newly introduced. If there is no bin 0,
+ *                     then items from the lowest non-negative bin
+ *                     will be flagged as introduced.
+ *
+ * The selection system is designed to rapidly reinforce items needing
  * to be learned and provide exponentially less reinforcement for
  * items as mastery is displayed. This is achieved by storing the
- * items in a series of numberred bins.
+ * items in a series of numbered bins.
  *
  * Items start in bin 0 indicating that they have never been presented
  * to a user. When an item is presented to the user and answered
@@ -87,85 +133,66 @@ mnemon_load (mnemon_t *mnemon);
  * number is the most likely to be chosen, while each succesively-
  * higher-numbered bin has a probability one-half of that of the
  * previous bin.
+ */
+void
+mnemon_select_item (mnemon_t    *mnemon,
+                   bin_t       **bin_ret,
+                   int          *item_index_ret,
+                   category_t  **category_ret,
+                   int          *introduced_ret);
+
+/* Update an item based on a user's answer (correct or incorrect).
+ *
+ * The bin and item_index should be exactly as returned by
+ * mnemon_select_item.  The correct flag should indicate whether the
+ * user answered the challenge correctly or not, (and should only
+ * count as correct if the answer was within the time limit, if any).
+ *
+ * The item will be moved from its current bin to a new bin based on
+ * whether the challenge was answered correctly. The bin updates are
+ * as follows:
+ *
+ * If the answer was correct:
+ *     Increase the bin number by 1
+ *     If the new bin number is 0, set it to 1 (0 bin is for new items)
+ *
+ * If the answer was incorrect:
+ *     If the old bin was positive, move to bin -2 (for extra training)
+ *     Otherwise decrease the bin number by 1
  *
- * A session of challenges consists of three phases, some of which may
- * be entirely empty, as follows:
- *    
- * 1. The introduction phase
- *  
- *     This phase is controlled by the to_introduce counter which is
- *     by default set to 10. It is decremented every time an item is
- *     introduced from the bin with score 0, or (if there is no bin
- *     with score 0), every time an item is introduced from the bin
- *     with the lowest non-negative score of any bin.
- *
- * 2. The mastering phase
- *  
- *     This phase is controlled by the to_master counter which is
- *     initially set to 10. It begins at the beginning of the session
- *     so can run concurrently with the introduction phase. The
- *     to_master counter is decremented every time an item with a
- *     positive (non-zero) score is answered correctly. It is also
- *     incremented every time an item with a positive (non-zero) score
- *     is answered incorrectly during the introduction phase. If
- *     perfect mastery is demonstrated, the mastering phase is likely
- *     to be complete simultaneous with the introduction stage. If the
- *     user is really struggling with mastery, the mastering phase
- *     will extend long after the introduction phase is over. But
- *     since we never incremeent to_master after the introduction
- *     phase is over, the user cannot build an infinite snowball of
- *     to_master items and have to give up in despair.
- *
- * 3. The solidifying phase
- *  
- *     This final phase continues after the mastering phase for as
- *     long as any items with a negative score remain. The idea here
- *     is that we want to quickly give the reinforcement from a missed
- *     item in the current session. Also, there's a bit of a challenge
- *     to the user to demonstrate good mastery of any non-negative
- *     items presented so that the phase actually terminates. It's
- *     possible for this phase to extend for an arbitrary amount of
- *     time, but not very likely, (since the negative items are chosen
- *     preferentially and the user will continue to see the correct
- *     answers to them over and over).
- *
- * This function returns after all three phases are complete.
- *
- * The user's progress (the movement of items to various new bins) is
- * kept only in memory. In order to save this progress to disk, the
- * caller must call mnemon_save.
+ * Note: All item and bin movement is kept only in memory. In order to
+ * save this progress to disk, the caller must call mnemon_save.
  */
 void
-mnemon_do_challenges (mnemon_t *mnemon);
+mnemon_score_item (mnemon_t *mnemon,
+                  bin_t *bin,
+                  unsigned int item_index,
+                  bool_t correct);
 
 /* Save the user's progress by updating the category files in the
  * users .mnemon directory. */
 void
 mnemon_save (mnemon_t *mnemon);
 
-/* Print a histogram showing the number of items in each bin.
+/* Remove a bin of a particular number.
  *
- * If category_name is not NULL, then only the items from the given
- * category (matching a particular filename within the user's .mnemon
- * directory) will be shown.
- *
- * If length is non zero, then only items with a challenge string of
- * 'length' characters will be shown. (This is only useful for
- * particular types of challenges, such as for showing anagram
- * challenges of a given length).
- *
- * To see a histogram of all currently-loaded items, pass NULL for
- * category and 0 for length.
- *
- * Note: Some bins may be removed entirely by (a misfeature side
- * effect of) the mnemon_do_challenges function, (such as bin 0 being
- * removed after the introduction phase is complete). An accurate
- * histogram can be guaranteed by calling menmon_print_histogram
- * immediately after calling mnemon_load.
+ * This can be useful in situations such as wanting to practice
+ * mastery of learned items without mixing in new items that the user
+ * has never seen before. This could be achieved by removing bin 0,
+ * for example.
  */
 void
-mnemon_print_histogram (mnemon_t    *mnemon,
-                       const char  *category_name,
-                       int          length);
+mnemon_remove_bin (mnemon_t *mnemon, int bin_number);
+
+/* Find the category to which an item belongs. */
+category_t *
+mnemon_item_category (mnemon_t *mnemon,
+                     item_t    *item);
+
+/* Get a category by name if it exists */
+category_t *
+mnemon_get_category_if_exists (mnemon_t            *mnemon,
+                              const char   *name);
+
 
 #endif