// Copyright 2005-2024 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the 'License');
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an 'AS IS' BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
// See www.openfst.org for extensive documentation on this weighted
|
|
// finite-state transducer library.
|
|
//
|
|
// Commonly used FST arc types.
|
|
|
|
#ifndef FST_ARC_H_
|
|
#define FST_ARC_H_
|
|
|
|
#include <climits>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
#include <fst/error-weight.h>
|
|
#include <fst/expectation-weight.h>
|
|
#include <fst/float-weight.h>
|
|
#include <fst/fst-decl.h> // For optional argument declarations
|
|
#include <fst/lexicographic-weight.h>
|
|
#include <fst/power-weight.h>
|
|
#include <fst/product-weight.h>
|
|
#include <fst/signed-log-weight.h>
|
|
#include <fst/sparse-power-weight.h>
|
|
#include <fst/string-weight.h>
|
|
|
|
namespace fst {
|
|
|
|
template <class W, class L /* = int */, class S /* = int */>
|
|
struct ArcTpl {
|
|
public:
|
|
using Weight = W;
|
|
using Label = L;
|
|
using StateId = S;
|
|
|
|
Label ilabel;
|
|
Label olabel;
|
|
Weight weight;
|
|
StateId nextstate;
|
|
|
|
ArcTpl() noexcept(std::is_nothrow_default_constructible_v<Weight>) = default;
|
|
|
|
template <class T>
|
|
ArcTpl(Label ilabel, Label olabel, T &&weight, StateId nextstate)
|
|
: ilabel(ilabel),
|
|
olabel(olabel),
|
|
weight(std::forward<T>(weight)),
|
|
nextstate(nextstate) {}
|
|
|
|
// Arc with weight One.
|
|
ArcTpl(Label ilabel, Label olabel, StateId nextstate)
|
|
: ArcTpl(ilabel, olabel, Weight::One(), nextstate) {}
|
|
|
|
static const std::string &Type() {
|
|
static const auto *const type = new std::string(
|
|
Weight::Type() == "tropical" ? "standard" : Weight::Type());
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
using StdArc = ArcTpl<TropicalWeight>;
|
|
using LogArc = ArcTpl<LogWeight>;
|
|
using Log64Arc = ArcTpl<Log64Weight>;
|
|
using RealArc = ArcTpl<RealWeight>;
|
|
using Real64Arc = ArcTpl<Real64Weight>;
|
|
using SignedLogArc = ArcTpl<SignedLogWeight>;
|
|
using SignedLog64Arc = ArcTpl<SignedLog64Weight>;
|
|
using ErrorArc = ArcTpl<ErrorWeight>;
|
|
using MinMaxArc = ArcTpl<MinMaxWeight>;
|
|
|
|
// Arc with integer labels and state IDs and string weights.
|
|
template <StringType S = STRING_LEFT>
|
|
struct StringArc : public ArcTpl<StringWeight<int, S>> {
|
|
public:
|
|
using Base = ArcTpl<StringWeight<int, S>>;
|
|
|
|
using Base::Base;
|
|
|
|
static const std::string &Type() {
|
|
static const auto *const type = new std::string(
|
|
S == STRING_LEFT ? "left_standard_string"
|
|
: (S == STRING_RIGHT ? "right_standard_string"
|
|
: "restricted_standard_string"));
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
// Arc with label and state Id type the same as template arg and with
|
|
// weights over the Gallic semiring w.r.t the output labels and weights of A.
|
|
template <class A, GallicType G = GALLIC_LEFT>
|
|
struct GallicArc : public ArcTpl<GallicWeight<int, typename A::Weight, G>,
|
|
typename A::Label, typename A::StateId> {
|
|
using Base = ArcTpl<GallicWeight<int, typename A::Weight, G>,
|
|
typename A::Label, typename A::StateId>;
|
|
using Arc = A;
|
|
|
|
using Base::Base;
|
|
|
|
explicit GallicArc(const Arc &arc)
|
|
: Base(arc.ilabel, arc.ilabel, Weight(arc.olabel, arc.weight),
|
|
arc.nextstate) {}
|
|
|
|
static const std::string &Type() {
|
|
static const auto *const type = new std::string(
|
|
(G == GALLIC_LEFT
|
|
? "left_gallic_"
|
|
: (G == GALLIC_RIGHT
|
|
? "right_gallic_"
|
|
: (G == GALLIC_RESTRICT
|
|
? "restricted_gallic_"
|
|
: (G == GALLIC_MIN ? "min_gallic_" : "gallic_")))) +
|
|
Arc::Type());
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
// Arc with the reverse of the weight found in its template arg.
|
|
template <class A>
|
|
struct ReverseArc : public ArcTpl<typename A::Weight::ReverseWeight,
|
|
typename A::Label, typename A::StateId> {
|
|
using Base = ArcTpl<typename A::Weight::ReverseWeight, typename A::Label,
|
|
typename A::StateId>;
|
|
using Arc = A;
|
|
|
|
using Base::Base;
|
|
|
|
static const std::string &Type() {
|
|
static const auto *const type = new std::string("reverse_" + Arc::Type());
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
// Arc with integer labels and state IDs and lexicographic weights.
|
|
template <class Weight1, class Weight2>
|
|
using LexicographicArc = ArcTpl<LexicographicWeight<Weight1, Weight2>>;
|
|
|
|
// Arc with integer labels and state IDs and product weights.
|
|
template <class Weight1, class Weight2>
|
|
using ProductArc = ArcTpl<ProductWeight<Weight1, Weight2>>;
|
|
|
|
// Arc with label and state ID type the same as first template argument and with
|
|
// weights over the n-th Cartesian power of the weight type of the template
|
|
// argument.
|
|
template <class A, size_t n>
|
|
struct PowerArc : public ArcTpl<PowerWeight<typename A::Weight, n>,
|
|
typename A::Label, typename A::StateId> {
|
|
using Base = ArcTpl<PowerWeight<typename A::Weight, n>, typename A::Label,
|
|
typename A::StateId>;
|
|
using Arc = A;
|
|
|
|
using Base::Base;
|
|
|
|
static const std::string &Type() {
|
|
static const auto *const type =
|
|
new std::string(Arc::Type() + "_^" + std::to_string(n));
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
// Arc with label and state ID type the same as first template argument and with
|
|
// weights over the arbitrary Cartesian power of the weight type.
|
|
template <class A, class K = int>
|
|
struct SparsePowerArc : public ArcTpl<SparsePowerWeight<typename A::Weight, K>,
|
|
typename A::Label, typename A::StateId> {
|
|
using Base = ArcTpl<SparsePowerWeight<typename A::Weight, K>,
|
|
typename A::Label, typename A::StateId>;
|
|
using Arc = A;
|
|
|
|
using Base::Base;
|
|
|
|
static const std::string &Type() {
|
|
static const std::string *const type = [] {
|
|
std::string type = Arc::Type() + "_^n";
|
|
if (sizeof(K) != sizeof(uint32_t)) {
|
|
type += "_" + std::to_string(CHAR_BIT * sizeof(K));
|
|
}
|
|
return new std::string(type);
|
|
}();
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
// Arc with label and state ID type the same as first template argument and with
|
|
// expectation weight over the first template argument's weight type and the
|
|
// second template argument.
|
|
template <class A, class X2>
|
|
struct ExpectationArc : public ArcTpl<ExpectationWeight<typename A::Weight, X2>,
|
|
typename A::Label, typename A::StateId> {
|
|
using Base = ArcTpl<ExpectationWeight<typename A::Weight, X2>,
|
|
typename A::Label, typename A::StateId>;
|
|
using Arc = A;
|
|
using X1 = typename Arc::Weight;
|
|
|
|
using Base::Base;
|
|
|
|
static const std::string &Type() {
|
|
static const auto *const type =
|
|
new std::string("expectation_" + Arc::Type() + "_" + X2::Type());
|
|
return *type;
|
|
}
|
|
};
|
|
|
|
} // namespace fst
|
|
|
|
#endif // FST_ARC_H_
|