public void TestSTranRestr()
{
STBuilderZ3 stb = new STBuilderZ3(new Z3Provider(BitWidth.BV16));
string regex1 = @"^[^a]+$";
string regex2 = @"^($|abc){0,2}$";
string regex = @"^($){1,2}$";
var sfa1 = stb.CreateFromRegex("SFA1", regex1).EliminateEpsilons();
var sfa2 = stb.CreateFromRegex("SFA2", regex2).EliminateEpsilons();
var sfa = (sfa1 * sfa2).Minimize().NormalizeLabels();
sfa.Name = "SFA";
var SMT = sfa.Solver;
//sfa.ShowGraph();
sfa.AssertTheory();
Sort strSort = SMT.MkListSort(sfa.InputSort);
Expr y = SMT.MkConst("y", strSort);
Expr acc_y = SMT.MkApp(sfa.Acceptor, y);
var y_val = SMT.MainSolver.GetModel(acc_y, y)[y].GetStringValue(false);
Assert.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(y_val, regex1));
Assert.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(y_val, regex2));
Assert.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(y_val, regex));
Assert.IsTrue(y_val.StartsWith("$"));
STz3 st = MkDecodeWithFinalOutputs(stb, sfa.InputSort);
st.AssertTheory();
Expr x = SMT.MkConst("x", st.InputListSort);
Expr x2 = SMT.MkConst("x2", st.InputListSort);
Expr decode_x_to_y = SMT.MkApp(st.Acceptor, x, y);
Expr decode_x2_to_y = SMT.MkApp(st.Acceptor, x2, y);
//note that acc_y is a range-restriction on y and x,x2 are input lists
var model = SMT.MainSolver.GetModel(SMT.MkAnd(new Expr[] { acc_y, decode_x_to_y, decode_x2_to_y, SMT.MkNeq(x, x2) }), x, x2, y);
var x_val = model[x].GetStringValue(false);
var x2_val = model[x2].GetStringValue(false);
y_val = model[y].GetStringValue(false);
Assert.IsTrue(y_val.StartsWith("$"));
Assert.IsFalse(x_val.StartsWith("$"));
Assert.IsFalse(x2_val.StartsWith("$"));
Assert.AreNotEqual(x_val, x2_val);
string y_expected1 = System.Net.WebUtility.HtmlDecode(x_val);
string y_expected2 = System.Net.WebUtility.HtmlDecode(x2_val);
Assert.AreEqual(y_expected1, y_val);
Assert.AreEqual(y_expected2, y_val);
}