public void TestComplement()
{
#region copied from above: creates the tree acceptor D
Z3Provider Z = new Z3Provider();
var A = (Z.TT.MkRankedAlphabet("A", Z.IntSort, new string[] { "zero", "one", "two" }, new int[] { 0, 1, 2 }));
var B = (Z.TT.MkRankedAlphabet("B", Z.IntSort, new string[] { "nolla", "yksi", "kaksi" }, new int[] { 0, 1, 2 }));
var C = (Z.TT.MkRankedAlphabet("C", Z.IntSort, new string[] { "noll", "ett", "tva" }, new int[] { 0, 1, 2 }));
Expr _0 = A.TT.Z.MkInt(0);
Expr _1 = A.TT.Z.MkInt(1);
Expr _11 = A.TT.Z.MkInt(11);
Expr _22 = A.TT.Z.MkInt(22);
Expr _33 = A.TT.Z.MkInt(33);
Expr _111 = A.TT.Z.MkInt(111);
Expr _222 = A.TT.Z.MkInt(222);
Expr _333 = A.TT.Z.MkInt(333);
Func<Expr, Expr> one = t => A.MkTree("one", _11, t);
Func<Expr, Expr, Expr> two = (t1, t2) => A.MkTree("two", _22, t1, t2);
Expr zero = A.MkTree("zero", _33);
Func<int, int, Expr> q = (state, var) => { return A.MkTrans(B, state, var); };
Func<Expr, Expr> yksi = t => B.MkTree("yksi", _111, t);
Func<Expr, Expr, Expr> kaksi = (t1, t2) => B.MkTree("kaksi", _222, t1, t2);
Expr nolla = B.MkTree("nolla", _333);
var AB_rule0 = Z.TT.MkTreeRule(A, B, 0, "zero", Z.True, nolla);
var AB_rule1 = Z.TT.MkTreeRule(A, B, 0, "two", Z.True, yksi(q(0, 1)), new int[] { 0 }, new int[] { 1 });
var AB_rule2 = A.MkAcceptorRule(1, "zero");
var AB_rule3 = A.MkAcceptorRule(1, "one", 1);
var AB_rule4 = Z.TT.MkTreeRule(A, B, 0, "one", Z.True, yksi(q(0, 1)), new int[] { 0 });
var AB = Z.TT.MkTreeAutomaton(0, A, B, new TreeRule[] { AB_rule0, AB_rule1, AB_rule2, AB_rule3, AB_rule4 });
var D_rule1 = A.MkAcceptorRule(1, "zero");
var D_rule2 = A.MkAcceptorRule(1, "two", 1, 1);
var D = Z.TT.MkTreeAutomaton(1, A, A, new TreeRule[] { D_rule1, D_rule2 });
var AB_D = AB.RestrictDomain(D);
Assert.AreEqual<int>(3, AB_D.RuleCount);
var inp1 = two(two(two(zero, zero), zero), zero);
var inp2 = two(two(two(zero, zero), zero), one(one(zero)));
var out1_actual = AB[inp1];
var out2_actual = AB[inp2];
var out_expected = yksi(yksi(yksi(nolla)));
Assert.AreEqual<int>(1, out1_actual.Length);
Assert.AreEqual<int>(1, out2_actual.Length);
Assert.AreEqual<Expr>(out_expected, out1_actual[0]);
Assert.AreEqual<Expr>(out_expected, out2_actual[0]);
var out1_actual2 = AB_D[inp1];
var out2_actual2 = AB_D[inp2];
bool acc = AB_D.Accepts(inp2);
var out_expected2 = yksi(yksi(yksi(nolla)));
Assert.AreEqual<int>(1, out1_actual2.Length);
Assert.AreEqual<int>(0, out2_actual2.Length);
Assert.IsFalse(acc);
Assert.AreEqual<Expr>(out_expected, out1_actual2[0]);
#endregion
var dta = D.Determinize();
var cdta = dta.Complement();
Assert.AreEqual(2, cdta.StateCount);
Assert.AreEqual(7, cdta.RuleCount);
}