/* SPDX-License-Identifier: AGPL-3.0-or-later */ /* Copyright (C) 2026 David (Corey) Herrera */ /* * rosa.h — Suffix automaton for ROSA (Rapid Online Suffix Automaton) * * Module prefix: sa_ (suffix automaton) * * Two variants: * 1. sa_automaton — binary alphabet {0,1} * 2. sa_token_automaton — large alphabet (vocab-sized), hash-map transitions * * Properties: * - Online: O(1) amortized per symbol * - At most 2*N states for sequence of length N * - Longest suffix match query: O(1) amortized per step * * Reference: Blumer et al. (1985), cp-algorithms.com/string/suffix-automaton */ #ifndef FOUNDRY_ROSA_H #define FOUNDRY_ROSA_H #include #include #ifdef __cplusplus extern "C" { #endif /* ================================================================ * Binary suffix automaton (alphabet = {0, 1}) * ================================================================ */ typedef struct { int len; int link; int endpos; int next[2]; } sa_state; typedef struct { sa_state *states; int n_states; int capacity; int last; int seq_len; } sa_automaton; sa_automaton* sa_new(int initial_cap); void sa_free(sa_automaton *sa); void sa_reset(sa_automaton *sa); void sa_extend(sa_automaton *sa, int symbol, int position); int sa_query_step(sa_automaton *sa, int symbol, int *state, int *match_len); /* ================================================================ * Token-level suffix automaton (large alphabet, hash-map transitions) * ================================================================ */ typedef struct { int key; int value; } sa_trans_entry; typedef struct { int len; int link; int endpos; sa_trans_entry *trans; int trans_cap; int trans_count; } sa_token_state; typedef struct { sa_token_state *states; int n_states; int capacity; int last; int seq_len; int alphabet_size; } sa_token_automaton; sa_token_automaton* sa_token_new(int initial_cap, int alphabet_size); void sa_token_free(sa_token_automaton *sa); void sa_token_reset(sa_token_automaton *sa); void sa_token_extend(sa_token_automaton *sa, int token, int position); int sa_token_query_step(sa_token_automaton *sa, int token, int *state, int *match_len); /* ================================================================ * Position map (SA position -> source location) * ================================================================ */ typedef struct { int conv_idx; int msg_idx; int token_offset; } sa_position_info; typedef struct { sa_position_info *entries; int count; int capacity; } sa_position_map; sa_position_map* sa_position_map_new(int initial_cap); void sa_position_map_free(sa_position_map *map); int sa_position_map_append(sa_position_map *map, int conv_idx, int msg_idx, int token_offset); const sa_position_info* sa_position_map_get(const sa_position_map *map, int position); #ifdef __cplusplus } #endif #endif /* FOUNDRY_ROSA_H */