| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/core/assimilate.c')
| -rw-r--r-- | src/core/assimilate.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/core/assimilate.c b/src/core/assimilate.c new file mode 100644 index 0000000..eb6aa17 --- /dev/null +++ b/src/core/assimilate.c @@ -0,0 +1,232 @@ +#include <stdlib.h> +#include <string.h> + +#include "../io/error.h" + +#include "knowledge.h" + +static int link_to +( + ZoO_index links_count [const restrict static 1], + ZoO_index * links_occurrences [const restrict static 1], + ZoO_index * links [const restrict static 1], + ZoO_index const target +) +{ + ZoO_index i, * new_p; + + for (i = 0; i < *links_count; ++i) + { + if ((*links)[i] == target) + { + if ((*links_occurrences)[i] == ZoO_INDEX_MAX) + { + ZoO_S_WARNING + ( + "Maximum link occurrences count has been reached." + ); + + return -1; + } + + (*links_occurrences)[i] += 1; + + return 0; + } + } + + if (*links_count == ZoO_INDEX_MAX) + { + ZoO_S_WARNING("Maximum links count has been reached."); + + return -1; + } + + new_p = + (ZoO_index *) realloc + ( + *links_occurrences, + ( + ( + /* Safe: *links_count < ZoO_INDEX_MAX */ + (size_t) (*links_count + 1) + ) + * sizeof(ZoO_index) + ) + ); + + if (new_p == (ZoO_index *) NULL) + { + ZoO_S_ERROR("Could not reallocate a link occurrences list."); + + return -1; + } + + new_p[*links_count] = 1; + + *links_occurrences = new_p; + + new_p = + (ZoO_index *) realloc + ( + *links, + ( + ( + /* Safe: *links_count < ZoO_INDEX_MAX */ + (size_t) (*links_count + 1) + ) * sizeof(ZoO_index) + ) + ); + + if (new_p == (ZoO_index *) NULL) + { + ZoO_S_ERROR("Could not reallocate a link list."); + + return -1; + } + + new_p[*links_count] = target; + + *links = new_p; + + *links_count += 1; + + return 0; +} + +static int link_words +( + struct ZoO_knowledge k [const restrict static 1], + ZoO_index const a, + ZoO_index const b +) +{ + int error; + + error = + link_to + ( + &(k->words[a].forward_links_count), + &(k->words[a].forward_links_occurrences), + &(k->words[a].forward_links), + b + ); + + error = + ( + link_to + ( + &(k->words[b].backward_links_count), + &(k->words[b].backward_links_occurrences), + &(k->words[b].backward_links), + a + ) + | error + ); + + return error; +} + +int ZoO_knowledge_assimilate +( + struct ZoO_knowledge k [const static 1], + struct ZoO_strings string [const restrict static 1], + ZoO_index const aliases_count, + const char * restrict aliases [const restrict static aliases_count] +) +{ + int error; + ZoO_index curr_word, next_word; + ZoO_index curr_word_id, next_word_id; + + curr_word = 0; + + if (string->words_count == 0) + { + return 0; + } + + for (curr_word = 0; curr_word < aliases_count; ++curr_word) + { + if (ZoO_IS_PREFIX(aliases[curr_word], string->words[0])) + { + return 0; + } + } + + curr_word = 0; + + if (ZoO_knowledge_learn(k, string->words[curr_word], &curr_word_id) < 0) + { + return -1; + } + + if (link_words(k, ZoO_WORD_START_OF_LINE, curr_word_id) < 0) + { + error = -1; + + ZoO_WARNING + ( + "Could not indicate that '" + ZoO_CHAR_STRING_SYMBOL + "' was the first word of the sentence.", + string->words[0] + ); + } + + next_word = 1; + + error = 0; + + while (next_word < string->words_count) + { + /* prevents words [restrict], k [restrict] */ + if (ZoO_knowledge_learn(k, string->words[next_word], &next_word_id) < 0) + { + return -1; + } + + if (link_words(k, curr_word_id, next_word_id) < 0) + { + error = -1; + + ZoO_WARNING + ( + "Could not add a link between words '" + ZoO_CHAR_STRING_SYMBOL + "' and '" + ZoO_CHAR_STRING_SYMBOL + "'.", + string->words[curr_word], + string->words[next_word] + ); + } + + curr_word = next_word; + curr_word_id = next_word_id; + /* + * Safe: + * - next_word < words_count + * - words_count =< ZoO_INDEX_MAX + * ---- + * next_word < ZoO_INDEX_MAX + */ + next_word += 1; + } + + if (link_words(k, curr_word_id, ZoO_WORD_END_OF_LINE) < 0) + { + error = -1; + + ZoO_WARNING + ( + "Could not indicate that '" + ZoO_CHAR_STRING_SYMBOL + "' was the last word of the sentence.", + string->words[curr_word_id] + ); + } + + return error; +} + |


