1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// weight-tester.h
2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License");
4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License.
5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at
6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//     http://www.apache.org/licenses/LICENSE-2.0
8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software
10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS,
11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and
13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License.
14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc.
16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: riley@google.com (Michael Riley)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Utility class for regression testing of Fst weights.
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_TEST_WEIGHT_TESTER_H_
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_TEST_WEIGHT_TESTER_H_
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <iostream>
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <sstream>
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/random-weight.h>
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This class tests a variety of identities and properties that must
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// hold for the Weight class to be well-defined. It calls function object
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WEIGHT_GENERATOR to select weights that are used in the tests.
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class Weight, class WeightGenerator>
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass WeightTester {
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WeightTester(WeightGenerator generator) : weight_generator_(generator) {}
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Test(int iterations, bool test_division = true) {
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (int i = 0; i < iterations; ++i) {
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // Selects the test weights.
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight w1 = weight_generator_();
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight w2 = weight_generator_();
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight w3 = weight_generator_();
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      VLOG(1) << "weight type = " << Weight::Type();
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      VLOG(1) << "w1 = " << w1;
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      VLOG(1) << "w2 = " << w2;
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      VLOG(1) << "w3 = " << w3;
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      TestSemiring(w1, w2, w3);
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (test_division)
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        TestDivision(w1, w2);
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      TestReverse(w1, w2);
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      TestEquality(w1, w2, w3);
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      TestIO(w1);
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      TestCopy(w1);
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Note in the tests below we use ApproxEqual rather than == and add
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // kDelta to inequalities where the weights might be inexact.
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Tests (Plus, Times, Zero, One) defines a commutative semiring.
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void TestSemiring(Weight w1, Weight w2, Weight w3) {
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks that the operations are closed.
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Plus(w1, w2).Member());
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Times(w1, w2).Member());
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks that the operations are associative.
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(ApproxEqual(Plus(w1, Plus(w2, w3)), Plus(Plus(w1, w2), w3)));
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(ApproxEqual(Times(w1, Times(w2, w3)), Times(Times(w1, w2), w3)));
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks the identity elements.
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Plus(w1, Weight::Zero()) == w1);
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Plus(Weight::Zero(), w1) == w1);
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Times(w1, Weight::One()) == w1);
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Times(Weight::One(), w1) == w1);
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Check the no weight element.
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(!Weight::NoWeight().Member());
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(!Plus(w1, Weight::NoWeight()).Member());
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(!Plus(Weight::NoWeight(), w1).Member());
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(!Times(w1, Weight::NoWeight()).Member());
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(!Times(Weight::NoWeight(), w1).Member());
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks that the operations commute.
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(ApproxEqual(Plus(w1, w2), Plus(w2, w1)));
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kCommutative)
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(ApproxEqual(Times(w1, w2), Times(w2, w1)));
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks Zero() is the annihilator.
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Times(w1, Weight::Zero()) == Weight::Zero());
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Times(Weight::Zero(), w1) == Weight::Zero());
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Check Power(w, 0) is Weight::One()
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Power(w1, 0) == Weight::One());
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Check Power(w, 1) is w
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Power(w1, 1) == w1);
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Check Power(w, 3) is Times(w, Times(w, w))
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Power(w1, 3) == Times(w1, Times(w1, w1)));
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks distributivity.
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kLeftSemiring)
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(ApproxEqual(Times(w1, Plus(w2, w3)),
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                        Plus(Times(w1, w2), Times(w1, w3))));
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kRightSemiring)
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(ApproxEqual(Times(Plus(w1, w2), w3),
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                        Plus(Times(w1, w3), Times(w2, w3))));
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kIdempotent)
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(Plus(w1, w1) == w1);
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kPath)
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(Plus(w1, w2) == w1 || Plus(w1, w2) == w2);
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Ensure weights form a left or right semiring.
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Weight::Properties() & (kLeftSemiring | kRightSemiring));
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Check when Times() is commutative that it is marked as a semiring.
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kCommutative)
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(Weight::Properties() & kSemiring);
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Tests division operation.
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void TestDivision(Weight w1, Weight w2) {
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight p = Times(w1, w2);
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kLeftSemiring) {
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight d = Divide(p, w1, DIVIDE_LEFT);
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (d.Member())
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        CHECK(ApproxEqual(p, Times(w1, d)));
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(!Divide(w1, Weight::NoWeight(), DIVIDE_LEFT).Member());
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(!Divide(Weight::NoWeight(), w1, DIVIDE_LEFT).Member());
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kRightSemiring) {
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight d = Divide(p, w2, DIVIDE_RIGHT);
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (d.Member())
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        CHECK(ApproxEqual(p, Times(d, w2)));
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(!Divide(w1, Weight::NoWeight(), DIVIDE_RIGHT).Member());
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(!Divide(Weight::NoWeight(), w1, DIVIDE_RIGHT).Member());
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Weight::Properties() & kCommutative) {
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight d = Divide(p, w1, DIVIDE_RIGHT);
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (d.Member())
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        CHECK(ApproxEqual(p, Times(d, w1)));
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Tests reverse operation.
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void TestReverse(Weight w1, Weight w2) {
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typedef typename Weight::ReverseWeight ReverseWeight;
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReverseWeight rw1 = w1.Reverse();
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReverseWeight rw2 = w2.Reverse();
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(rw1.Reverse() == w1);
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Plus(w1, w2).Reverse() == Plus(rw1, rw2));
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(Times(w1, w2).Reverse() == Times(rw2, rw1));
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Tests == is an equivalence relation.
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void TestEquality(Weight w1, Weight w2, Weight w3) {
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks reflexivity.
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(w1 == w1);
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks symmetry.
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK((w1 == w2) == (w2 == w1));
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Checks transitivity.
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (w1 == w2 && w2 == w3)
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(w1 == w3);
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Tests binary serialization and textual I/O.
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void TestIO(Weight w) {
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Tests binary I/O
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    {
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ostringstream os;
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    w.Write(os);
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    os.flush();
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    istringstream is(os.str());
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight v;
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    v.Read(is);
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK_EQ(w, v);
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Tests textual I/O.
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    {
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ostringstream os;
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os << w;
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      istringstream is(os.str());
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Weight v(Weight::One());
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      is >> v;
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CHECK(ApproxEqual(w, v));
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Tests copy constructor and assignment operator
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void TestCopy(Weight w) {
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight x = w;
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(w == x);
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    x = Weight(w);
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(w == x);
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    x.operator=(x);
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CHECK(w == x);
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Generates weights used in testing.
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WeightGenerator weight_generator_;
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(WeightTester);
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_TEST_WEIGHT_TESTER_H_
226