#include #include "../core/char.h" #include "../core/index.h" #include "../sequence/sequence.h" #include "../error/error.h" #include "knowledge.h" static int weighted_random_pick ( const struct JH_knowledge_sequence_collection sc [const restrict static 1], const JH_index sum, JH_index result [const restrict static 1] ) { JH_index accumulator, random_number; accumulator = 0; if (sum == 0) { return -1; } random_number = JH_index_random_up_to(sum); /*@ ensures (0 <= random_number <= weights_sum); @*/ *result = 0; for (;;) { accumulator += sc->sequences_ref[*result].occurrences; if (accumulator < random_number) { *result += 1; } else { *result = sc->sequences_ref[*result].id; return 0; } } } int JH_knowledge_copy_random_swt_sequence ( struct JH_knowledge k [const static 1], JH_index sequence [const restrict static 1], const JH_index word_id, const JH_index markov_order, FILE io [const restrict static 1] ) { JH_index sequence_id; JH_knowledge_readlock_word(k, word_id, io); if ( weighted_random_pick ( &(k->words[word_id].swt), k->words[word_id].occurrences, &sequence_id ) < 0 ) { JH_S_PROG_ERROR ( io, "Knowledge inconsistency; there are no acceptable markov sequences " "linked to a word that has been picked as being an acceptable pillar." ); JH_knowledge_readunlock_word(k, word_id, io); return -1; } JH_knowledge_readunlock_word(k, word_id, io); JH_knowledge_readlock_sequences(k, io); memcpy ( (void *) sequence, (const void *) k->sequences[sequence_id], (((size_t) (markov_order - 1)) * sizeof(JH_index)) ); JH_knowledge_readunlock_sequences(k, io); return 0; }