TRAINING: MAKING A HYPO FROM AN EXAMPLES. As mentioned above, some learners (e.g. naive nearest neighbor) may require no training. But any learner that does require training must implement two functions: mk_xxx_hypo and free_xxx_hypo, where xxx is the name of the learner. char *mk_xxx_hypo(examples *exams, ivec *in_att_nums, ivec *out_att_nums, char *params, ivec *train_rows, ivec *holdout_rows, expo **r_error_expo); mk_xxx_hypo trains the learner on the data in examples, considering just the specified input and output attributes (the data may have additional attributes not included in either in_att_nums or out_att_nums). If xxx is a learner that needs an internal holdout-set, this holdout-set is defined by holdout_rows. The rows that may be used for training are specified by train_rows. If the learner uses internal parameters, these will be specified by the params argument. mk_xxx_hypo should return a pointer to the result of training (called a "hypo"). This lump of memory will have been AM_MALLOCKED, and will eventually be freed with free_xxx_hypo. If the learner is unable to learn using the given set of att_nums, params, and rows, it returns NULL and sets *r_error_expo to a non-NULL error message explaining the problem. If the learner is able to learn, *r_error_expo should be returned as NULL.