public void TestRegularLookaheadComposition1()
{
Z3Provider Z = new Z3Provider();
var A = (Z.TT.MkRankedAlphabet("A", Z.IntSort, new string[] { "zeroA", "oneA", "twoA" }, new int[] { 0, 1, 2 }));
var B = (Z.TT.MkRankedAlphabet("B", Z.IntSort, new string[] { "zeroB", "oneB", "twoB" }, new int[] { 0, 1, 2 }));
var C = (Z.TT.MkRankedAlphabet("C", Z.IntSort, new string[] { "zeroC", "oneC", "twoC" }, new int[] { 0, 1, 2 }));
//(two (plus 1 x0) (one (plus 1 x0) (q x1)) (one (plus 2 x0) (q x2)))
var b = Z.MkApp(B["twoB"],
Z.MkAdd(Z.MkInt(1), A.AttrVar),
B.MkTree("oneB", Z.MkAdd(Z.MkInt(1), A.AttrVar), A.MkTrans(B, 0, 1)),
B.MkTree("oneB", Z.MkAdd(Z.MkInt(2), A.AttrVar), A.MkTrans(B, 0, 2)));
//(two (plus 1 x0) (zero x0) (one (plus 100 x0) (q x2)))
var b2 = Z.MkApp(B["twoB"],
Z.MkAdd(Z.MkInt(1), A.AttrVar),
B.MkTree("zeroB", A.AttrVar),
B.MkTree("oneB", Z.MkAdd(Z.MkInt(9), A.AttrVar), A.MkTrans(B, 0, 2)));
var rule0 = Z.TT.MkTreeRule(A, B, 0, "zeroA", Z.True, B.MkTree("zeroB", A.AttrVar));
var rule1 = Z.TT.MkTreeRule(A, B, 0, "twoA", Z.MkGt(A.AttrVar, Z.MkInt(0)), b);
var rule2 = Z.TT.MkTreeRule(A, B, 0, "twoA", Z.MkGt(A.AttrVar, Z.MkInt(0)), b2);
var rule3 = Z.TT.MkTreeRule(A, B, 0, "oneA", Z.MkGt(A.AttrVar, Z.MkInt(0)), B.MkTree("oneB", A.AttrVar, A.MkTrans(B, 0, 1)));
var trans1 = Z.TT.MkTreeAutomaton(0, A, B, new TreeRule[] { rule0, rule1, rule2, rule3 });
//(two x0 (one (plus 1 x0) (p x1)) (one (plus 2 x0) (p x2)))
var a = A.MkTree("twoA", C.AttrVar,
A.MkTree("oneA", Z.MkAdd(Z.MkInt(1), C.AttrVar), C.MkTrans(A, 1, 1)),
A.MkTree("oneA", Z.MkAdd(Z.MkInt(2), C.AttrVar), C.MkTrans(A, 1, 2)));
var a2 = A.MkTree("zeroA", C.AttrVar);
var rule4 = Z.TT.MkTreeRule(C, A, 1, "twoC", Z.MkGt(C.AttrVar, Z.MkInt(-2)), a);
var rule5 = Z.TT.MkTreeRule(C, A, 1, "zeroC", Z.MkGt(C.AttrVar, Z.MkInt(-3)), a2);
var trans2 = Z.TT.MkTreeAutomaton(1, C, A, new TreeRule[] { rule4, rule5 });
var trans12 = TreeTransducer.ComposeR(trans2, trans1);
var rulesOut = trans12.GetRules(trans12.Root, C["twoC"]);
Assert.AreEqual<int>(2, rulesOut.Count);
var rulesOut2 = trans12.GetRules(trans12.Root, C["zeroC"]);
Assert.AreEqual<int>(1, rulesOut2.Count);
var tin = C.MkTree("twoC", Z.MkInt(55), C.MkTree("zeroC", Z.MkInt(66)), C.MkTree("zeroC", Z.MkInt(77)));
var res = trans12[tin];
Assert.AreEqual<int>(2, res.Length);
Assert.AreEqual<int>(3, trans12.RuleCount);
}