protected static void read_header_and_symbols(IGenericFst fst, BinaryReader reader) { if (read_int32_LE(reader) != OPENFST_MAGIC) throw new Exception("invalid magic number"); read_magic_string(reader, "vector"); read_magic_string(reader, "standard"); int version = read_int32_LE(reader); if (version < MIN_VERSION) throw new Exception("file has too old version"); int flags = read_int32_LE(reader); read_int64_LE(reader); // properties Int64 start = read_int64_LE(reader); Int64 nstates = read_int64_LE(reader); if (nstates < 0) return; // to prevent creating 2^31 nodes in case of sudden EOF fst.Clear(); for (int i = 0; i < nstates; i++) fst.NewState(); fst.SetStart((int)start); read_int64_LE(reader); // narcs if ((flags & FLAG_HAS_ISYMBOLS) > 0) skip_symbol_table(reader); if ((flags & FLAG_HAS_OSYMBOLS) > 0) skip_symbol_table(reader); }
/// <summary> /// Copy one FST to another, preserving only lowest-cost arcs. /// This is useful for visualization. /// </summary> /// <param name="dst">The destination. Will be cleared before copying.</param> /// <param name="src">The FST to copy.</param> public static void fst_copy_best_arcs_only(IGenericFst dst, IGenericFst src) { dst.Clear(); int n = src.nStates(); for (int i = 0; i < n; i++) dst.NewState(); dst.SetStart(src.GetStart()); for(int i = 0; i < n; i++) { dst.SetAccept(i, src.GetAcceptCost(i)); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); int inlen = inputs.Length(); if (inlen != targets.Length()) throw new Exception("ASSERT: inputs.length() == targets.length()"); if (inlen != outputs.Length()) throw new Exception("ASSERT: inputs.length() == outputs.length()"); if (inlen != costs.Length()) throw new Exception("ASSERT: inputs.length() == costs.length()"); Dictionary< int, int > hash = new Dictionary<int,int>(); for(int j = 0; j < n; j++) { int t = targets[j]; int best_so_far = -1; if (hash.ContainsKey(t)) best_so_far = hash[t]; if(best_so_far == -1 || costs[j] < costs[best_so_far]) hash[t] = j; } Intarray keys = new Intarray(); //hash.keys(keys); keys.Clear(); foreach (int key in hash.Keys) { keys.Push(key); } for(int k = 0; k < keys.Length(); k++) { int j = hash[keys[k]]; dst.AddTransition(i, targets[j], outputs[j], costs[j], inputs[j]); } } }
/// <summary> /// Copy one FST to another. /// </summary> /// <param name="dst">The destination. Will be cleared before copying.</param> /// <param name="src">The FST to copy.</param> public static void fst_copy(IGenericFst dst, IGenericFst src) { dst.Clear(); int n = src.nStates(); for (int i = 0; i < n; i++) dst.NewState(); dst.SetStart(src.GetStart()); for (int i = 0; i < n; i++) { dst.SetAccept(i, src.GetAcceptCost(i)); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); int inlen = inputs.Length(); if (inlen != targets.Length()) throw new Exception("ASSERT: inputs.length() == targets.length()"); if (inlen != outputs.Length()) throw new Exception("ASSERT: inputs.length() == outputs.length()"); if (inlen != costs.Length()) throw new Exception("ASSERT: inputs.length() == costs.length()"); for (int j = 0; j < inputs.Length(); j++) dst.AddTransition(i, targets.At1d(j), outputs.At1d(j), costs.At1d(j), inputs.At1d(j)); } }
/// <summary> /// Reverse the FST's arcs, adding a new start vertex (former accept). /// </summary> public static void fst_copy_reverse(IGenericFst dst, IGenericFst src, bool no_accept = false) { dst.Clear(); int n = src.nStates(); for (int i = 0; i <= n; i++) dst.NewState(); if (!no_accept) dst.SetAccept(src.GetStart()); dst.SetStart(n); for (int i = 0; i < n; i++) { dst.AddTransition(n, i, 0, src.GetAcceptCost(i), 0); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); if (inputs.Length() != targets.Length()) throw new Exception("ASSERT: inputs.length() == targets.length()"); if (inputs.Length() != outputs.Length()) throw new Exception("ASSERT: inputs.length() == outputs.length()"); if (inputs.Length() != costs.Length()) throw new Exception("ASSERT: inputs.length() == costs.length()"); for (int j = 0; j < inputs.Length(); j++) dst.AddTransition(targets.At1d(j), i, outputs.At1d(j), costs.At1d(j), inputs.At1d(j)); } }