summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/assimilate.c2
-rw-r--r--src/core/create_sentences.c116
-rw-r--r--src/core/knowledge.c48
-rw-r--r--src/core/knowledge.h38
-rw-r--r--src/core/main.c68
5 files changed, 211 insertions, 61 deletions
diff --git a/src/core/assimilate.c b/src/core/assimilate.c
index eb6aa17..28f4dd4 100644
--- a/src/core/assimilate.c
+++ b/src/core/assimilate.c
@@ -5,6 +5,8 @@
#include "knowledge.h"
+/** Functions to assimilate sentences using a ZoO_knowledge structure *********/
+
static int link_to
(
ZoO_index links_count [const restrict static 1],
diff --git a/src/core/create_sentences.c b/src/core/create_sentences.c
index bc410e5..e999199 100644
--- a/src/core/create_sentences.c
+++ b/src/core/create_sentences.c
@@ -7,6 +7,17 @@
#include "knowledge.h"
+/** Functions to create sentences using a ZoO_knowledge structure *************/
+
+/*
+ * Returns the index of a element in {links} chosen randomly according
+ * to the distribution in {links_occurrences}.
+ * Pre:
+ * (!= occurrences 0).
+ * (== (length links_occurrences) (length links)).
+ * (== (sum links_occurrences) occurrences).
+ * (can_store ZoO_index (length links)).
+ */
static ZoO_index pick_an_index
(
ZoO_index const occurrences,
@@ -17,29 +28,40 @@ static ZoO_index pick_an_index
ZoO_index result, accumulator, random_number;
result = 0;
+
+ /*
+ * Safe:
+ * (> (length links_occurrences) 0).
+ */
accumulator = links_occurrences[0];
+
random_number = (((ZoO_index) rand()) % occurrences);
while (accumulator < random_number)
{
-
/*
- * Should be safe:
- * result overflowing <-> sum('links_occurrences') > 'occurrences'
- * and sum('links_occurrences') == 'occurrences'
+ * Safe:
+ * (->
+ * (and
+ * (== accumulator (sum links_occurrences[0:result]))
+ * (< accumulator random_number)
+ * (< random_number occurrences)
+ * (== occurrences (sum links_occurrences))
+ * (can_store ZoO_index (length links))
+ * (== (length links_occurrences) (length links))
+ * )
+ * (and
+ * (< result' (length links_occurrences))
+ * (can_store ZoO_index result')
+ * (=< accumulator' occurrences)
+ * )
+ * )
*/
result += 1;
-
- /*
- * Should be safe:
- * - sum('links_occurrences') == 'occurrences'.
- * - 'occurrences' is safe.
- * ----
- * 'accumulator' is safe.
- */
accumulator += links_occurrences[result];
}
+ /* Safe: (< result (length links)) */
return links[result];
}
@@ -330,7 +352,7 @@ static unsigned char * extend_right
int ZoO_knowledge_extend
(
struct ZoO_knowledge k [const static 1],
- const struct ZoO_strings string [const static 1],
+ const struct ZoO_strings string [const],
int const ignore_first_word,
ZoO_char * result [const static 1]
)
@@ -339,48 +361,56 @@ int ZoO_knowledge_extend
size_t sentence_size;
ZoO_index i, word_id, word_min_score, word_min_id, credits;
- word_found = 0;
credits = ZoO_MAX_REPLY_WORDS;
- if (ignore_first_word)
- {
- i = 1;
- }
- else
+ if (string != (struct ZoO_strings *) NULL)
{
- i = 0;
- }
+ word_found = 0;
- for (; i < string->words_count; ++i)
- {
- /* prevents k [restrict] */
- if (ZoO_knowledge_find(k, string->words[i], &word_min_id) == 0)
+ if (ignore_first_word)
{
- word_found = 1;
- word_min_score = k->words[word_min_id].occurrences;
+ i = 1;
+ }
+ else
+ {
+ i = 0;
+ }
- break;
+ for (; i < string->words_count; ++i)
+ {
+ /* prevents k [restrict] */
+ if (ZoO_knowledge_find(k, string->words[i], &word_min_id) == 0)
+ {
+ word_found = 1;
+ word_min_score = k->words[word_min_id].occurrences;
+
+ break;
+ }
}
- }
- if (word_found == 0)
- {
- word_min_id = (rand() % k->words_count);
- word_min_score = k->words[word_min_id].occurrences;
- }
+ if (word_found == 0)
+ {
+ word_min_id = (rand() % k->words_count);
+ word_min_score = k->words[word_min_id].occurrences;
+ }
- for (; i < string->words_count; ++i)
- {
- if
- (
- (ZoO_knowledge_find(k, string->words[i], &word_id) == 0)
- && (k->words[word_id].occurrences < word_min_score)
- )
+ for (; i < string->words_count; ++i)
{
- word_min_score = k->words[word_id].occurrences;
- word_min_id = word_id;
+ if
+ (
+ (ZoO_knowledge_find(k, string->words[i], &word_id) == 0)
+ && (k->words[word_id].occurrences < word_min_score)
+ )
+ {
+ word_min_score = k->words[word_id].occurrences;
+ word_min_id = word_id;
+ }
}
}
+ else
+ {
+ word_min_id = (rand() % k->words_count);
+ }
/* 3: 2 spaces + '\0' */
/* FIXME: not overflow-safe */
diff --git a/src/core/knowledge.c b/src/core/knowledge.c
index 31ccb97..9b4e250 100644
--- a/src/core/knowledge.c
+++ b/src/core/knowledge.c
@@ -6,6 +6,8 @@
#include "knowledge.h"
+/** Basic functions of the ZoO_knowledge structure ****************************/
+
/* XXX: are we as close to immutable as we want to be? */
unsigned int const ZoO_knowledge_punctuation_chars_count = 7;
const ZoO_char const ZoO_knowledge_punctuation_chars[7] =
@@ -33,6 +35,7 @@ const ZoO_char const ZoO_knowledge_forbidden_chars[8]=
'>'
};
+/* See "knowledge.h". */
int ZoO_knowledge_find
(
const struct ZoO_knowledge k [const restrict static 1],
@@ -54,7 +57,7 @@ int ZoO_knowledge_find
current_min = 0;
- /* overflow-safe: k->words_count >= 1 */
+ /* Safe: (>= k->words_count 1) */
current_max = (k->words_count - 1);
for (;;)
@@ -124,6 +127,18 @@ static void word_init (struct ZoO_knowledge_word w [const restrict static 1])
w->backward_links = (ZoO_index *) NULL;
}
+/*
+ * When returning 0:
+ * All punctuation symbols were added to {k}.
+ * When returning -1:
+ * The mandatory punctuation symbols have been added to {k}, but some of the
+ * additional ones did not. This does not prevent ZoO from working, but
+ * will result in some punctuation symbols to be handled exactly like
+ * common words.
+ * When returning -2:
+ * The mandatory punctuation symbols have not added to {k}. ZoO will not be
+ * able to work.
+ */
static int add_punctuation_nodes
(
struct ZoO_knowledge k [const static 1]
@@ -177,6 +192,7 @@ static int add_punctuation_nodes
return error;
}
+/* See "knowledge.h" */
int ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1])
{
k->words_count = 0;
@@ -193,6 +209,10 @@ int ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1])
return 0;
}
+/*
+ * Frees all the memory used by {w}, but not {w} itself.
+ * The values of {w}'s members are set to reflect the changes.
+ */
static void finalize_word
(
struct ZoO_knowledge_word w [const restrict static 1]
@@ -237,13 +257,13 @@ static void finalize_word
w->backward_links_count = 0;
}
+/* See "knowledge.h" */
void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1])
{
ZoO_index i;
for (i = 0; i < k->words_count; ++i)
{
- /* prevents k [restrict] */
finalize_word(k->words + i);
}
@@ -264,6 +284,7 @@ void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1])
}
}
+/* See "knowledge.h" */
int ZoO_knowledge_learn
(
struct ZoO_knowledge k [const static 1],
@@ -291,7 +312,7 @@ int ZoO_knowledge_learn
return -1;
}
- /* overflow-safe */
+ /* overflow-safe: (< k->words[*result].occurrences ZoO_INDEX_MAX) */
k->words[*result].occurrences += 1;
return 0;
@@ -310,7 +331,7 @@ int ZoO_knowledge_learn
(void *) k->words,
(
(
- /* overflow-safe: k->words_count < ZoO_INDEX_MAX */
+ /* overflow-safe: (< k->words_count ZoO_INDEX_MAX) */
(size_t) (k->words_count + 1)
)
* sizeof(struct ZoO_knowledge_word)
@@ -336,7 +357,7 @@ int ZoO_knowledge_learn
(void *) k->sorted_indices,
(
(
- /* overflow-safe: k->words_count < ZoO_INDEX_MAX */
+ /* overflow-safe: (< k->words_count ZoO_INDEX_MAX) */
(size_t) (k->words_count + 1)
)
* sizeof(ZoO_index)
@@ -359,22 +380,27 @@ int ZoO_knowledge_learn
k->sorted_indices = new_sorted_indices;
/* We can only move indices right of *result if they exist. */
- if (*result != k->words_count)
+ if (*result < k->words_count)
{
/* TODO: check if correct. */
memmove
(
/*
- * overflow-safe:
- * - k->words_count < ZoO_INDEX_MAX
- * - (k->sorted_indices + *result + 1) =< k->words_count
+ * Safe:
+ * (->
+ * (and
+ * (== (length k->sorted_indices) (+ k->words_count 1))
+ * (< *result k->words_count)
+ * )
+ * (< (+ *result 1) (length k->sorted_indices))
+ * )
*/
(void *) (k->sorted_indices + *result + 1),
- /* overflow-safe: see above */
+ /* Safe: see above */
(const void *) (k->sorted_indices + *result),
(
(
- /* overflow-safe: *result < k->words_count */
+ /* Safe: (< *result k->words_count) */
(size_t) (k->words_count - *result)
)
* sizeof(ZoO_index)
diff --git a/src/core/knowledge.h b/src/core/knowledge.h
index f20cb16..c9ea342 100644
--- a/src/core/knowledge.h
+++ b/src/core/knowledge.h
@@ -5,10 +5,35 @@
#include "knowledge_types.h"
+/*
+ * Initializes all of {k}'s members to sane values.
+ *
+ * When returning 0:
+ * Initial punctuation nodes (including the mandatory "START OF LINE" and
+ * "END OF LINE" ones) have successfully been added to {k}.
+ *
+ * When return -1:
+ * Something went wrong, leading to {k} not being safe for use.
+ * {k} has been finalized.
+ */
int ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1]);
+/*
+ * Frees all the memory used by {k}, but not {k} itself.
+ * The values of {k}'s members are set to reflect the changes.
+ */
void ZoO_knowledge_finalize (struct ZoO_knowledge k [const static 1]);
+/*
+ * When returning 0:
+ * {word} is in {k}.
+ * {word} is located at {k->words[*result]}.
+ *
+ * When returning -1:
+ * {word} is not in {k}.
+ * {*result} is where {word} was expected to be found in
+ * {k->sorted_indices}.
+ */
int ZoO_knowledge_find
(
const struct ZoO_knowledge k [const restrict static 1],
@@ -16,6 +41,17 @@ int ZoO_knowledge_find
ZoO_index result [const restrict static 1]
);
+/*
+ * When returning 0:
+ * {word} was either added to {k} or its representation in {k} has its
+ * occurrences count increased.
+ * {*result} indicates where {word} is in {k->words}.
+ *
+ * When returning -1:
+ * Something went wrong when adding the occurrence of {word} to {k}.
+ * {k} remains semantically unchanged.
+ * {*result} may or may not have been altered.
+ */
int ZoO_knowledge_learn
(
struct ZoO_knowledge k [const static 1],
@@ -34,7 +70,7 @@ int ZoO_knowledge_assimilate
int ZoO_knowledge_extend
(
struct ZoO_knowledge k [const static 1],
- const struct ZoO_strings string [const static 1],
+ const struct ZoO_strings string [const],
int const ignore_first_word,
ZoO_char * result [const static 1]
);
diff --git a/src/core/main.c b/src/core/main.c
index 40b3705..1a8a40f 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -150,6 +150,43 @@ static int should_reply
return (param->reply_rate >= (rand() % 100));
}
+static void handle_user_join
+(
+ struct ZoO_state s [const static 1]
+)
+{
+ ZoO_char * line;
+
+ if
+ (
+ (s->param.reply_rate >= (rand() % 100))
+ &&
+ (
+ ZoO_knowledge_extend
+ (
+ &(s->knowledge),
+ (struct ZoO_strings *) NULL,
+ 0,
+ &line
+ ) == 0
+ )
+ )
+ {
+ if (line[0] == ' ')
+ {
+ strcpy((s->network.out), (line + 1));
+ }
+ else
+ {
+ strcpy((s->network.out), line);
+ }
+
+ free((void *) line);
+
+ ZoO_network_send(&(s->network));
+ }
+}
+
static void handle_message
(
struct ZoO_state s [const static 1],
@@ -167,7 +204,7 @@ static void handle_message
(
string,
(size_t) msg_size,
- (s->network.msg + msg_offset),
+ (s->network.in + msg_offset),
ZoO_knowledge_punctuation_chars_count,
ZoO_knowledge_punctuation_chars
) < 0
@@ -202,11 +239,11 @@ static void handle_message
{
if (line[0] == ' ')
{
- strcpy((s->network.msg), (line + 1));
+ strcpy((s->network.out), (line + 1));
}
else
{
- strcpy((s->network.msg), line);
+ strcpy((s->network.out), line);
}
free((void *) line);
@@ -226,10 +263,11 @@ static void handle_message
}
}
-static int main_loop (struct ZoO_state s [const static 1])
+static int main_loop (struct ZoO_state s [const static 1])
{
struct ZoO_strings string;
ssize_t msg_offset, msg_size;
+ enum ZoO_msg_type msg_type;
msg_offset = 0;
msg_size = 0;
@@ -238,9 +276,27 @@ static int main_loop (struct ZoO_state s [const static 1])
while (run)
{
- if (ZoO_network_receive(&(s->network), &msg_offset, &msg_size) == 0)
+ if
+ (
+ ZoO_network_receive
+ (
+ &(s->network),
+ &msg_offset,
+ &msg_size,
+ &msg_type
+ ) == 0
+ )
{
- handle_message(s, &string, msg_offset, msg_size);
+ switch (msg_type)
+ {
+ case ZoO_JOIN:
+ handle_user_join(s);
+ break;
+
+ case ZoO_PRIVMSG:
+ handle_message(s, &string, msg_offset, msg_size);
+ break;
+ }
}
}