A lattice library.
#include <algorithm>
#include <any>
#include <cassert>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <boost/stl_interfaces/iterator_interface.hpp>
namespace usage_tetengo::lattice
{
std::unique_ptr<tetengo::lattice::vocabulary> build_vocabulary();
void viterbi()
{
const auto p_vocabulary = build_vocabulary();
lattice_.
push_back(std::make_unique<tetengo::lattice::string_input>(
"a"));
lattice_.push_back(std::make_unique<tetengo::lattice::string_input>("b"));
const auto eos_and_preceding_costs = lattice_.settle();
eos_and_preceding_costs.first,
std::make_unique<tetengo::lattice::constraint>() };
std::vector<std::string> paths{};
std::for_each(
paths.push_back(to_string(path_));
});
static const std::vector<std::string> expected{
"[BOS]-[Alice]-[Bravo]-[EOS] (12)",
"[BOS]-[AwaBizan]-[EOS] (17)",
"[BOS]-[Alpha]-[Bravo]-[EOS] (18)",
"[BOS]-[Alpha]-[Bob]-[EOS] (24)",
"[BOS]-[Alice]-[Bob]-[EOS] (25)",
};
assert(paths == expected);
}
{
return entry.
value()->has_value() ? std::any_cast<std::string>(*entry.
value()) : std::string{};
}
std::unique_ptr<tetengo::lattice::vocabulary> build_vocabulary()
{
static const std::vector<tetengo::lattice::entry> entries{
{ std::make_unique<tetengo::lattice::string_input>("a"), std::string{ "Alpha" }, 2 },
{ std::make_unique<tetengo::lattice::string_input>("b"), std::string{ "Bravo" }, 7 },
{ std::make_unique<tetengo::lattice::string_input>("a"), std::string{ "Alice" }, 1 },
{ std::make_unique<tetengo::lattice::string_input>("b"), std::string{ "Bob" }, 8 },
{ std::make_unique<tetengo::lattice::string_input>("ab"), std::string{ "AwaBizan" }, 9 },
};
std::vector<std::pair<std::string, std::vector<tetengo::lattice::entry>>> entry_mappings{
{ "a", { entries[0], entries[2] } },
{ "b", { entries[1], entries[3] } },
{ "ab", { entries[4] }},
};
std::vector<std::pair<std::pair<tetengo::lattice::entry, tetengo::lattice::entry>, int>> connections{
{ { entries[0], entries[1] }, 4 },
{ { entries[2], entries[1] }, 1 },
{ { entries[0], entries[3] }, 5 },
{ { entries[2], entries[3] }, 9 },
};
return std::make_unique<tetengo::lattice::unordered_map_vocabulary>(
std::move(entry_mappings),
std::move(connections),
return (entry.
p_key() ? entry.
p_key()->
hash_value() : 0) ^ std::hash<std::string>{}(value_of(entry));
},
return ((!entry1.
p_key() && !entry2.p_key()) ||
(entry1.
p_key() && entry2.p_key() && *entry1.
p_key() == *entry2.p_key())) &&
(value_of(entry1) == value_of(entry2));
});
}
{
if (node_.
value().has_value())
{
return std::any_cast<std::string>(node_.
value());
}
else if (first)
{
return "BOS";
}
else
{
return "EOS";
}
}
{
std::string result{};
for (const auto& node: path_.nodes())
{
if (!std::empty(result))
{
result += "-";
}
result += "[" + value_of(node, std::empty(result)) + "]";
}
result +=
" (" + std::to_string(path_.
cost()) +
")";
return result;
}
}
An entry view.
Definition entry.hpp:110
constexpr const std::any * value() const
Returns the value.
Definition entry.hpp:162
constexpr const input * p_key() const
Returns the pointer to the key.
Definition entry.hpp:152
static const entry & bos_eos()
Returns the BOS/EOS (Beginning/End of Sequence) entry.
A lattice.
Definition lattice.hpp:29
void push_back(std::unique_ptr< input > &&p_input)
Pushes back an input.
An N-best lattice path iterator.
Definition n_best_iterator.hpp:99
A node.
Definition node.hpp:27
constexpr const std::any & value() const
Returns the value.
Definition node.hpp:153
A path.
Definition path.hpp:21
int cost() const
Returns the cost.
An N-best lattice path iterator.
An unordered map vocabulary.
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
tetengo_lattice_vocabulary_t* build_vocabulary();
const char* to_string(const tetengo_lattice_path_t* p_path);
void usage_tetengo_lattice_viterbi()
{
const tetengo_lattice_vocabulary_t* const p_vocabulary = build_vocabulary();
if (eos_preceding_count == 0)
{
return;
}
int* const p_eos_preceding_costs = (int*)malloc(eos_preceding_count * sizeof(int));
tetengo_lattice_nBestIterator_t* const p_iterator =
char paths[256] = { 0 };
{
strcat(paths, to_string(p_path));
}
static const char* const expected =
"[BOS]-[Alice]-[Bravo]-[EOS] (12)\n"
"[BOS]-[AwaBizan]-[EOS] (17)\n"
"[BOS]-[Alpha]-[Bravo]-[EOS] (18)\n"
"[BOS]-[Alpha]-[Bob]-[EOS] (24)\n"
"[BOS]-[Alice]-[Bob]-[EOS] (25)\n";
assert(strcmp(paths, expected) == 0);
free((void*)p_eos_preceding_costs);
}
static size_t hash(const char* const string, const size_t length)
{
size_t value = 0;
for (size_t i = 0; i < length; ++i)
{
value ^= string[i];
}
return value;
}
{
const size_t value_hash = value ? hash(value, strlen(value)) : 0;
return key_hash ^ value_hash;
}
static int
{
int equality = 1;
equality = equality && ((!p_entry_key1 && !p_entry_key2) ||
equality = equality && ((!value1 && !value2) || (value1 && value2 && strcmp(value1, value2) == 0));
return equality;
}
tetengo_lattice_vocabulary_t* build_vocabulary()
{
const tetengo_lattice_input_t* const p_bos_eos_key =
connections[0].
p_from = &bos_eos;
connections[0].
p_to = &entries[0];
connections[1].
p_from = &bos_eos;
connections[1].
p_to = &entries[1];
connections[2].
p_from = &entries[0];
connections[2].
p_to = &entries[2];
connections[3].
p_from = &entries[1];
connections[3].
p_to = &entries[2];
connections[4].
p_from = &entries[0];
connections[4].
p_to = &entries[3];
connections[5].
p_from = &entries[1];
connections[5].
p_to = &entries[3];
connections[6].
p_from = &entries[2];
connections[6].
p_to = &bos_eos;
connections[7].
p_from = &entries[3];
connections[7].
p_to = &bos_eos;
connections[8].
p_from = &bos_eos;
connections[8].
p_to = &entries[4];
connections[9].
p_from = &entries[4];
connections[9].
p_to = &bos_eos;
entry_mappings,
connections,
entry_hash,
entry_equal_to);
return p_vocabulary;
}
{
if (value)
{
return value;
}
else if (first)
{
return "BOS";
}
else
{
return "EOS";
}
}
const char* to_string(const tetengo_lattice_path_t* const p_path)
{
static char result[48] = { 0 };
result[0] = '\0';
{
if (!p_nodes)
{
return result;
}
for (size_t i = 0; i < node_count; ++i)
{
if (i > 0)
{
strncat(result, "-", sizeof(result) - strlen(result) - 1);
}
strncat(result, "[", sizeof(result) - strlen(result) - 1);
strncat(result, value_of(&p_nodes[i], i == 0), sizeof(result) - strlen(result) - 1);
strncat(result, "]", sizeof(result) - strlen(result) - 1);
}
strncat(result, " (", sizeof(result) - strlen(result) - 1);
strncat(result, ")", sizeof(result) - strlen(result) - 1);
free(p_nodes);
}
strncat(result, "\n", sizeof(result) - strlen(result) - 1);
return result;
}
tetengo_lattice_constraint_t * tetengo_lattice_constraint_createEmpty()
Creates an empty constraint.
const tetengo_lattice_entryView_t * tetengo_lattice_entryView_bosEos()
Returns the pointer to the BOS/EOS (Beginning/End of Sequence) entry.
tetengo_lattice_entry_keyHandle_t tetengo_lattice_entry_toKeyHandle(const tetengo_lattice_input_t *p_content)
Returns the entry key handle.
const void * tetengo_lattice_entryView_valueOf(tetengo_lattice_entryView_valueHandle_t handle)
Returns the entry view value by a handle.
const struct tetengo_lattice_entry_keyHandle_tag * tetengo_lattice_entry_keyHandle_t
An entry key handle.
Definition entry.h:23
const tetengo_lattice_input_t * tetengo_lattice_entryView_createKeyOf(tetengo_lattice_entryView_keyHandle_t handle)
Creates an entry view key by a handle.
bool tetengo_lattice_lattice_pushBack(tetengo_lattice_lattice_t *p_lattice, tetengo_lattice_input_t *p_input)
Pushes back an input.
size_t tetengo_lattice_lattice_settle(tetengo_lattice_lattice_t *p_lattice, tetengo_lattice_node_t *p_eos_node, int *p_preceding_edge_costs)
Settles this lattice.
tetengo_lattice_lattice_t * tetengo_lattice_lattice_create(const tetengo_lattice_vocabulary_t *p_vocabulary)
Creates a lattice.
void tetengo_lattice_lattice_destroy(const tetengo_lattice_lattice_t *p_lattice)
Destroys a lattice.
An N-best lattice path iterator.
tetengo_lattice_nBestIterator_t * tetengo_lattice_nBestIterator_create(const tetengo_lattice_lattice_t *p_lattice, const tetengo_lattice_node_t *p_eos_node, tetengo_lattice_constraint_t *p_constraint)
Creates an iterator.
void tetengo_lattice_nBestIterator_next(tetengo_lattice_nBestIterator_t *p_iterator)
Increments the iterator.
bool tetengo_lattice_nBestIterator_hasNext(const tetengo_lattice_nBestIterator_t *p_iterator)
Returns true when the iterator will return more elements.
void tetengo_lattice_nBestIterator_destroy(const tetengo_lattice_nBestIterator_t *p_iterator)
Destroys an iterator.
tetengo_lattice_path_t * tetengo_lattice_nBestIterator_createPath(const tetengo_lattice_nBestIterator_t *p_iterator)
Dereferences the iterator.
int tetengo_lattice_path_cost(const tetengo_lattice_path_t *p_path)
Returns the cost.
size_t tetengo_lattice_path_pNodes(const tetengo_lattice_path_t *p_path, tetengo_lattice_node_t *p_nodes)
Returns the nodes.
void tetengo_lattice_path_destroy(const tetengo_lattice_path_t *p_path)
Destroys a path.
A pair of entries and a connection cost.
Definition connection.h:33
int cost
Definition connection.h:41
const tetengo_lattice_entry_t * p_to
Definition connection.h:38
const tetengo_lattice_entry_t * p_from
Definition connection.h:35
An entry view.
Definition entry.h:57
int cost
Definition entry.h:65
tetengo_lattice_entryView_keyHandle_t key_handle
Definition entry.h:59
tetengo_lattice_entryView_valueHandle_t value_handle
Definition entry.h:62
An entry.
Definition entry.h:40
int cost
Definition entry.h:48
const void * p_value
Definition entry.h:45
tetengo_lattice_entry_keyHandle_t key_handle
Definition entry.h:42
A pair of a key and entries.
Definition entry.h:74
tetengo_lattice_stringView_t key
Definition entry.h:76
const tetengo_lattice_entry_t * p_entries
Definition entry.h:79
size_t entry_count
Definition entry.h:82
A node.
Definition node.h:25
tetengo_lattice_entryView_valueHandle_t value_handle
Definition node.h:30
size_t length
Definition stringView.h:26
const char * p_head
Definition stringView.h:23
tetengo_lattice_vocabulary_t * tetengo_lattice_vocabulary_createUnorderedMapVocabulary(const tetengo_lattice_keyEntriesPair_t *p_entries, size_t entry_count, const tetengo_lattice_entriesConnectionCostPair_t *p_connections, size_t connection_count, size_t(*p_entry_hash)(const tetengo_lattice_entryView_t *), int(*p_entry_equal_to)(const tetengo_lattice_entryView_t *, const tetengo_lattice_entryView_t *))
Creates an unordered map vocabulary.
void tetengo_lattice_vocabulary_destroy(const tetengo_lattice_vocabulary_t *p_vocabulary)
Destroys a vocabulary.