// 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.
|
|
//
|
|
#ifndef FST_TEST_COMPACTORS_H_
|
|
#define FST_TEST_COMPACTORS_H_
|
|
|
|
// See www.openfst.org for extensive documentation on this weighted
|
|
// finite-state transducer library.
|
|
//
|
|
// Compactors for use in tests. See compact-fst.h.
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <istream>
|
|
#include <memory>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
#include <fst/arc.h>
|
|
#include <fst/expanded-fst.h>
|
|
#include <fst/fst.h>
|
|
#include <fst/properties.h>
|
|
#include <fst/util.h>
|
|
#include <fst/vector-fst.h>
|
|
|
|
namespace fst {
|
|
|
|
// A user-defined compactor for test FST.
|
|
// Stores all Arc components as a tuple.
|
|
template <class A>
|
|
class TrivialArcCompactor {
|
|
public:
|
|
using Arc = A;
|
|
using Label = typename A::Label;
|
|
using StateId = typename A::StateId;
|
|
using Weight = typename A::Weight;
|
|
// We use ArcTpl, which is trivially copyable if Weight is.
|
|
static_assert(std::is_trivially_copyable_v<Weight>,
|
|
"Weight must be trivially copyable.");
|
|
using Element = ArcTpl<Weight>;
|
|
static_assert(std::is_trivially_copyable_v<Element>,
|
|
"ArcTpl should be trivially copyable; someone broke it.");
|
|
|
|
Element Compact(StateId s, const A &arc) const {
|
|
return Element(arc.ilabel, arc.olabel, arc.weight, arc.nextstate);
|
|
}
|
|
|
|
Arc Expand(StateId s, const Element &e, uint32_t f = kArcValueFlags) const {
|
|
return Arc(e.ilabel, e.olabel, e.weight, e.nextstate);
|
|
}
|
|
|
|
ssize_t Size() const { return -1; }
|
|
|
|
uint64_t Properties() const { return 0ULL; }
|
|
|
|
bool Compatible(const Fst<A> &fst) const { return true; }
|
|
|
|
static const std::string &Type() {
|
|
static const std::string *const type =
|
|
new std::string("trival_arc_compactor_" + Arc::Type());
|
|
return *type;
|
|
}
|
|
|
|
bool Write(std::ostream &strm) const { return true; }
|
|
|
|
static TrivialArcCompactor *Read(std::istream &strm) {
|
|
return new TrivialArcCompactor;
|
|
}
|
|
};
|
|
|
|
// A user-defined arc compactor for test FST.
|
|
// Doesn't actually do any compacting, but exercises the Compactor interface.
|
|
template <class A>
|
|
class TrivialCompactor {
|
|
public:
|
|
using Arc = A;
|
|
using StateId = typename Arc::StateId;
|
|
using Weight = typename Arc::Weight;
|
|
|
|
// Any empty FST is OK.
|
|
TrivialCompactor() : fst_(new VectorFst<Arc>) {}
|
|
|
|
// Constructor from the Fst to be compacted. If compactor is present,
|
|
// only optional state should be copied from it.
|
|
explicit TrivialCompactor(const Fst<Arc> &fst,
|
|
std::shared_ptr<TrivialCompactor> = nullptr)
|
|
: fst_(fst.Copy()) {}
|
|
|
|
// Copy constructor. Must make a thread-safe copy suitable for use by
|
|
// by Fst::Copy(/*safe=*/true).
|
|
TrivialCompactor(const TrivialCompactor &compactor)
|
|
: fst_(compactor.fst_->Copy(/*safe=*/true)) {}
|
|
|
|
StateId Start() const { return fst_->Start(); }
|
|
StateId NumStates() const { return CountStates(*fst_); }
|
|
size_t NumArcs() const { return CountArcs(*fst_); }
|
|
|
|
// Accessor class for state attributes.
|
|
class State {
|
|
public:
|
|
State() = default;
|
|
State(const TrivialCompactor *c, StateId s)
|
|
: c_(c),
|
|
s_(s),
|
|
i_(std::make_unique<ArcIterator<Fst<Arc>>>(*c->fst_, s)) {}
|
|
StateId GetStateId() const { return s_; }
|
|
Weight Final() const { return c_->fst_->Final(s_); }
|
|
size_t NumArcs() const { return c_->fst_->NumArcs(s_); }
|
|
Arc GetArc(size_t i, uint32_t f) const {
|
|
i_->Seek(i);
|
|
return i_->Value();
|
|
}
|
|
|
|
private:
|
|
const TrivialCompactor *c_ = nullptr;
|
|
StateId s_ = kNoStateId;
|
|
std::unique_ptr<ArcIterator<Fst<Arc>>> i_;
|
|
};
|
|
|
|
void SetState(StateId s, State *state) { *state = State(this, s); }
|
|
|
|
template <typename Arc>
|
|
bool IsCompatible(const Fst<Arc> &fst) const {
|
|
return std::is_same_v<Arc, A>;
|
|
}
|
|
|
|
uint64_t Properties(uint64_t props) const { return props; }
|
|
|
|
static const std::string &Type() {
|
|
static const std::string *const type =
|
|
new std::string("trivial_compactor_" + Arc::Type());
|
|
return *type;
|
|
}
|
|
|
|
bool Error() const { return fst_->Properties(kError, /*test=*/false); }
|
|
|
|
bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
|
|
WriteType(strm, Type());
|
|
// Write as a VectorFst.
|
|
return VectorFst<Arc>::WriteFst(*fst_, strm, opts);
|
|
}
|
|
|
|
static TrivialCompactor *Read(std::istream &strm, FstReadOptions opts,
|
|
const FstHeader &hdr) {
|
|
std::string type;
|
|
ReadType(strm, &type);
|
|
if (type != Type()) return nullptr;
|
|
opts.header = nullptr;
|
|
auto fst = fst::WrapUnique(VectorFst<Arc>::Read(strm, opts));
|
|
if (fst == nullptr) return nullptr;
|
|
return new TrivialCompactor(*fst);
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<Fst<Arc>> fst_;
|
|
};
|
|
|
|
} // namespace fst
|
|
|
|
#endif // FST_TEST_COMPACTORS_H_
|