private void ToHTMLColoredEnglishStringInt(HashSet<PDL> renamed, HashSet<PDL> deleted, PDL term, string delColor, string renColor, TreeEditScript editScript, StringBuilder sb, string varName)
        {
            bool negate = false;
            var notterm = term as PDLNot;
            if (notterm != null)
            {
                term = notterm.phi;
                negate = true;
            }

            Pattern.Match(term).
                Case<PDLAllPos>(() => TermCase(renamed, deleted, term, delColor, renColor, "the set of all positions", sb)).

                Case<PDLAtPos, char, PDLPos>((label, pos) =>
                {
                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos, delColor, renColor, editScript, sb, varName);
                    if (negate)
                        TermCase(renamed, deleted, term, "", delColor, renColor, " doesn't have label ", editScript, sb);
                    else
                        TermCase(renamed, deleted, term, "", delColor, renColor, " has label ", editScript, sb);
                    TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                }).

                Case<PDLAtSet, char, PDLSet>((label, set) =>
                {
                    Pattern.Match(set).
                        Case<PDLAllPos>(() =>
                        {
                            if (negate)
                                TermCase(renamed, deleted, set, delColor, renColor, string.Format("not every symbol in <i>{0}</i>", varName), sb);
                            else
                                TermCase(renamed, deleted, set, delColor, renColor, string.Format("every symbol in <i>{0}</i>", varName), sb);
                            TermCase(renamed, deleted, term, "", delColor, renColor, " is a '", editScript, sb);
                            TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                            TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("'"), editScript, sb);
                        }).
                        Case<PDLSetCmpPos, PDLPos, PDLComparisonOperator>((pos, op) =>
                        {
                            if (negate)
                                TermCase(renamed, deleted, set, "", delColor, renColor, "not every symbol ", editScript, sb);
                            else
                                TermCase(renamed, deleted, set, "", delColor, renColor, "every symbol ", editScript, sb);
                            switch (op)
                            {
                                case PDLComparisonOperator.Ge: TermCase(renamed, deleted, set, delColor, renColor, "after ", sb); break;
                                case PDLComparisonOperator.Geq: TermCase(renamed, deleted, set, delColor, renColor, "after and including ", sb); break;
                                case PDLComparisonOperator.Le: TermCase(renamed, deleted, set, delColor, renColor, "before ", sb); break;
                                case PDLComparisonOperator.Leq: TermCase(renamed, deleted, set, delColor, renColor, "before and including ", sb); break;
                                default: throw new PDLException("undefined operator");
                            }
                            Pattern.Match(pos).
                                Case<PDLFirst>(() =>
                                {
                                    TermCase(renamed, deleted, pos, delColor, renColor, "the first one", sb);
                                }).
                                Case<PDLLast>(() =>
                                {
                                    TermCase(renamed, deleted, pos, delColor, renColor, "the last one", sb);
                                }).
                                Default(() =>
                                {
                                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos, delColor, renColor, editScript, sb, varName);
                                });
                            TermCase(renamed, deleted, term, "", delColor, renColor, " has label ", editScript, sb);
                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                            TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                        }).
                        Case<PDLPredSet, string, PDLPred>((var, phi) =>
                            {
                                Pattern.Match(phi).
                                    Case<PDLModSetEq, PDLSet, int, int>((set1, m, n) =>
                                    {
                                        var cast = set1 as PDLAllPosUpto;
                                        if (m == 2 && cast != null && cast.pos is PDLPosVar)
                                        {
                                            if (negate)
                                                TermCase(renamed, deleted, set, "", delColor, renColor, "not every ", editScript, sb);
                                            else
                                                TermCase(renamed, deleted, set, "", delColor, renColor, "every ", editScript, sb);
                                            TermCase(renamed, deleted, phi, "n", delColor, renColor, (n == 1 ? "odd" : "even"), editScript, sb);
                                            TermCase(renamed, deleted, set, "", delColor, renColor, " position", editScript, sb);
                                            TermCase(renamed, deleted, term, "", delColor, renColor, " has label '", editScript, sb);
                                            TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                                        }
                                        else
                                        {
                                            if (negate)
                                                TermCase(renamed, deleted, set, "", delColor, renColor, "not every position " + var + " such that ", editScript, sb);
                                            else
                                                TermCase(renamed, deleted, set, "", delColor, renColor, "every position " + var + " such that ", editScript, sb);
                                            ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                            TermCase(renamed, deleted, term, "", delColor, renColor, " has label '", editScript, sb);
                                            TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                                        }
                                    }).
                                    Default(() =>
                                    {
                                        if (negate)
                                            TermCase(renamed, deleted, set, "", delColor, renColor, "not every position " + var + " such that ", editScript, sb);
                                        else
                                            TermCase(renamed, deleted, set, "", delColor, renColor, "every position " + var + " such that ", editScript, sb);
                                        ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                        TermCase(renamed, deleted, term, "", delColor, renColor, " has label '", editScript, sb);
                                        TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                                        TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                                    });
                            }).
                        Default(() =>
                        {
                            if (negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, "not every position in ", editScript, sb);
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, "every position in ", editScript, sb);
                            ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                            TermCase(renamed, deleted, term, "", delColor, renColor, " has label '", editScript, sb);
                            TermCase(renamed, deleted, term, "label", delColor, renColor, label.ToString(), editScript, sb);
                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                        });
                }).


                Case<PDLBelongs, PDLPos, PDLSet>((pos, set) =>
                {
                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos, delColor, renColor, editScript, sb, varName);
                    if (negate)
                        TermCase(renamed, deleted, term, delColor, renColor, " doesn't belong to ", sb);
                    else
                        TermCase(renamed, deleted, term, delColor, renColor, " belongs to ", sb);
                    ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                }).

                Case<PDLBinaryFormula, PDLPred, PDLPred, PDLLogicalOperator>((phi1, phi2, op) =>
                {
                    if (negate)
                        TermCase(renamed, deleted, notterm, delColor, renColor, "it is not the case that ", sb);

                    switch (op)
                    {
                        case PDLLogicalOperator.And:
                            {
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi1, delColor, renColor, editScript, sb, varName);
                                sb.Append(", ");
                                TermCase(renamed, deleted, term, delColor, renColor, "and ", sb);
                                break;
                            }
                        case PDLLogicalOperator.If:
                            {
                                TermCase(renamed, deleted, term, delColor, renColor, "if ", sb);
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi1, delColor, renColor, editScript, sb, varName);
                                sb.Append(", ");
                                TermCase(renamed, deleted, term, delColor, renColor, "then ", sb);
                                break;
                            }
                        case PDLLogicalOperator.Iff:
                            {
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi1, delColor, renColor, editScript, sb, varName);
                                sb.Append(", ");
                                TermCase(renamed, deleted, term, delColor, renColor, "if and only if ", sb);
                                break;
                            }
                        case PDLLogicalOperator.Or:
                            {
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi1, delColor, renColor, editScript, sb, varName);
                                sb.Append(", ");
                                TermCase(renamed, deleted, term, delColor, renColor, "or ", sb);
                                break;
                            }
                        default: throw new PDLException("undefined operator");
                    }

                    ToHTMLColoredEnglishStringInt(renamed, deleted, phi2, delColor, renColor, editScript, sb, varName);
                }).

                Case<PDLBinaryPosFormula, PDLPos, PDLPos, PDLPosComparisonOperator>((pos1, pos2, op) =>
                {
                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos1, delColor, renColor, editScript, sb, varName);
                    switch (op)
                    {
                        case PDLPosComparisonOperator.Eq:
                            {
                                if (negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't the same as ", sb); 
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is the same as ", sb); 
                                break;
                            }

                        case PDLPosComparisonOperator.Ge:
                            {
                                if (negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't after ", sb); 
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is after ", sb); 
                                break;                                
                            }

                        case PDLPosComparisonOperator.Geq:
                            {
                                if(negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't after or the same as ", sb); 
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is after or the same as ", sb); 
                                break;
                            }

                        case PDLPosComparisonOperator.Le:
                            {
                                if (negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't before ", sb); 
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is before ", sb); 
                                break;                                
                            }

                        case PDLPosComparisonOperator.Leq:
                            {
                                if (negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't before or the same as ", sb);
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is before or is the same as ", sb);
                                break; 
                            }

                        case PDLPosComparisonOperator.Pred:
                            {
                                if (negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't right before ", sb); 
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is right before ", sb); 
                                break;
                            }

                        case PDLPosComparisonOperator.Succ:
                            {
                                if (negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, " isn't right after ", sb); 
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, " is right after ", sb);
                                break;
                            }

                        default: throw new PDLException("Undefined operator");
                    }
                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos2, delColor, renColor, editScript, sb, varName);
                }).

                Case<PDLEmptyString>(() =>
                {
                    if(negate)
                        TermCase(renamed, deleted, term, delColor, renColor, string.Format("<i>s</i> isn't the empty string", varName), sb);
                    else
                        TermCase(renamed, deleted, term, delColor, renColor, string.Format("<i>s</i> is the empty string", varName), sb);
                }).

                Case<PDLFalse>(() => TermCase(renamed, deleted, term, delColor, renColor, "false", sb)).

                Case<PDLIndicesOf, string>((str) =>
                {
                    TermCase(renamed, deleted, term, "", delColor, renColor, "the set of positions where a substring '", editScript, sb);
                    TermCase(renamed, deleted, term, "str", delColor, renColor, str, editScript, sb);
                    TermCase(renamed, deleted, term, "", delColor, renColor, "' starts", editScript, sb);
                }).

                Case<PDLQuantifiedFormula, PDLPred, String, PDLQuantifier>((phi, var, q) =>
                {
                    switch (q)
                    {
                        case PDLQuantifier.ExistsFO:
                            {
                                Pattern.Match(phi).
                                    Case<PDLAtPos, char, PDLPos>((label, pos) =>
                                    {
                                        if(negate)
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("<i>{0}</i> doesn't contain at least one '", varName), sb);
                                        else
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("<i>{0}</i> contains at least one '", varName), sb);
                                        TermCase(renamed, deleted, phi, "label", delColor, renColor, label.ToString(), editScript, sb);
                                        TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                                    }).
                                    Default(() =>
                                    {
                                        if(negate)
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("there doesn't exist a position <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                        else
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("there exists a position <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                        ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                    });
                                break;
                            }
                        case PDLQuantifier.ExistsSO:
                            {
                                if(negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, string.Format("there doesn't exist a set of positions <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, string.Format("there exists a set of positions <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                break;
                            }
                        case PDLQuantifier.ForallFO:
                            {
                                Pattern.Match(phi).
                                    Case<PDLAtPos, char, PDLPos>((label, pos) =>
                                    {
                                        if(negate)
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("not every symbol in <i>{0}</i> is a '", varName), sb);
                                        else
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("every symbol in <i>{0}</i> is a '", varName), sb);
                                        TermCase(renamed, deleted, phi, "label", delColor, renColor, label.ToString(), editScript, sb);
                                        TermCase(renamed, deleted, term, delColor, renColor, string.Format("'"), sb);
                                    }).
                                    Default(() =>
                                    {
                                        if(negate)
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("not every position <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                        else
                                            TermCase(renamed, deleted, term, delColor, renColor, string.Format("for every position <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                        ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                    });
                                break;
                            }
                        case PDLQuantifier.ForallSO:
                            {
                                if(negate)
                                    TermCase(renamed, deleted, term, delColor, renColor, string.Format("not every set of positions <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                else
                                    TermCase(renamed, deleted, term, delColor, renColor, string.Format("for every set of positions <i>{0}</i> in <i>{1}</i>, ", var, varName), sb);
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                break;
                            }
                        default: throw new PDLException("Quantifier undefined");
                    }
                }).

                Case<PDLSetCardinality, PDLSet, int, PDLComparisonOperator>((set, n, op) =>
                {
                    Pattern.Match(set).
                        Case<PDLAllPos>(() =>
                        {
                            if (negate)
                                TermCase(renamed, deleted, term, delColor, renColor, string.Format("<i>{0}</i> doesn't have length", varName), sb);
                            else
                                TermCase(renamed, deleted, term, delColor, renColor, string.Format("<i>{0}</i> has length", varName), sb);
                            switch (op)
                            {
                                case PDLComparisonOperator.Eq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" exactly "), editScript, sb); break;
                                case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" greater than "), editScript, sb); break;
                                case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" greater or equal than "), editScript, sb); break;
                                case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" samller than "), editScript, sb); break;
                                case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" smaller or equal than "), editScript, sb); break;
                                default: throw new PDLException("Undefined operator");
                            }
                            TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString(), editScript, sb);
                        }).
                        Case<PDLIndicesOf, string>((str) =>
                        {
                            if (str.Length == 1)
                            {
                                if (negate)
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("<i>{0}</i> doesn't contain", varName), editScript, sb);
                                else
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("<i>{0}</i> contains", varName), editScript, sb);

                                switch (op)
                                {
                                    case PDLComparisonOperator.Eq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" exactly "), editScript, sb); break;
                                    case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" more than "), editScript, sb); break;
                                    case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" at least "), editScript, sb); break;
                                    case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" less than "), editScript, sb); break;
                                    case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" at most "), editScript, sb); break;
                                    default: throw new PDLException("Undefined operator");
                                }
                                if (n == 1)
                                    TermCase(renamed, deleted, term, "n", delColor, renColor, "one ", editScript, sb);
                                else
                                    if (n == 2)
                                        TermCase(renamed, deleted, term, "n", delColor, renColor, "two ", editScript, sb);
                                    else
                                        if (n == 3)
                                            TermCase(renamed, deleted, term, "n", delColor, renColor, "three ", editScript, sb);
                                        else
                                            TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString()+" ", editScript, sb);                                
                                TermCase(renamed, deleted, set, "str", delColor, renColor, str, editScript, sb);
                                TermCase(renamed, deleted, term, "", delColor, renColor, " ", editScript, sb);
                                if (n > 1 || n == 0)
                                    TermCase(renamed, deleted, set, "", delColor, renColor, "'s", editScript, sb);
                            }
                            else
                            {
                                TermCase(renamed, deleted, set, "str", delColor, renColor, str, editScript, sb);
                                if (negate)
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format(" doesn't appear in <i>{0}</i>", varName), editScript, sb);
                                else
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format(" appears in <i>{0}</i> ", varName), editScript, sb);

                                switch (op)
                                {
                                    case PDLComparisonOperator.Eq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" exactly "), editScript, sb); break;
                                    case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" more than "), editScript, sb); break;
                                    case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" at least "), editScript, sb); break;
                                    case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" less than "), editScript, sb); break;
                                    case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" at most "), editScript, sb); break;
                                    default: throw new PDLException("Undefined operator");
                                }
                                if (n == 1)
                                    TermCase(renamed, deleted, term, "n", delColor, renColor, "once", editScript, sb);
                                else
                                    if (n == 2)
                                        TermCase(renamed, deleted, term, "n", delColor, renColor, "twice", editScript, sb);
                                    else
                                        TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString() +" times", editScript, sb);                               
                            }
                        }).
                        Case<PDLUnion, PDLSet, PDLSet>((set1, set2) =>
                        {
                            if (set1 is PDLIndicesOf && set2 is PDLIndicesOf)
                            {
                                var phi1cast = set1 as PDLIndicesOf;
                                var phi2cast = set2 as PDLIndicesOf;
                                TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("' the total number of occurences of "), editScript, sb);
                                TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("'"), editScript, sb);
                                TermCase(renamed, deleted, set1, "str", delColor, renColor, phi1cast.str, editScript, sb);
                                TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("' and '"), editScript, sb);
                                TermCase(renamed, deleted, set2, "str", delColor, renColor, phi2cast.str, editScript, sb);
                                TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("'"), editScript, sb);
                                if(negate)
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("' in <i>{0}</i> isn't", varName), editScript, sb);
                                else
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("' in <i>{0}</i> is", varName), editScript, sb);
                                switch (op)
                                {
                                    case PDLComparisonOperator.Eq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" exactly "), editScript, sb); break;
                                    case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" greater than "), editScript, sb); break;
                                    case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" at least "), editScript, sb); break;
                                    case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" less than "), editScript, sb); break;
                                    case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" at most "), editScript, sb); break;
                                    default: throw new PDLException("Undefined operator");
                                }
                                TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString(), editScript, sb);
                            }
                            else
                            {
                                ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                                if(negate)
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" doesn't have"), editScript, sb);
                                else
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" has"), editScript, sb);
                               switch (op)
                                    {
                                        case PDLComparisonOperator.Eq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" exactly "), editScript, sb); break;
                                        case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size greater than "), editScript, sb); break;
                                        case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size greater or equal than "), editScript, sb); break;
                                        case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size smaller than "), editScript, sb); break;
                                        case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size smaller or equal than "), editScript, sb); break;
                                        default: throw new PDLException("Undefined operator");
                                    }
                                TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString(), editScript, sb);
                                TermCase(renamed, deleted, term, "", delColor, renColor, " elements ", editScript, sb);
                            }
                        }).
                        Default(() =>
                        {
                            ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                            if (negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" doesn't have"), editScript, sb);
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" has"), editScript, sb);
                            switch (op)
                            {
                                case PDLComparisonOperator.Eq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" exactly "), editScript, sb); break;
                                case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size greater than "), editScript, sb); break;
                                case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size greater or equal than "), editScript, sb); break;
                                case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size smaller than "), editScript, sb); break;
                                case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" size smaller or equal than "), editScript, sb); break;
                                default: throw new PDLException("Undefined operator");
                            }
                            TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString(), editScript, sb);
                            TermCase(renamed, deleted, term, "", delColor, renColor, " elements ", editScript, sb);
                        });
                }).

                Case<PDLNot, PDLPred>((phi) =>
                {
                    if(!negate)
                        TermCase(renamed, deleted, term, delColor, renColor, "it is not the case that ", sb);                    
                    ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                }).

                Case<PDLPosConstant, PDLPosConstantName>((op) =>
                {
                    switch (op)
                    {
                        case PDLPosConstantName.First: TermCase(renamed, deleted, term, delColor, renColor, "the first position", sb); break;
                        case PDLPosConstantName.Last: TermCase(renamed, deleted, term, delColor, renColor, "the last position", sb); break;
                        default: throw new PDLException("undefined operator");
                    }
                }).

                Case<PDLPosUnary, PDLPos, PDLPosUnaryConstructor>((pos, op) =>
                {
                    switch (op)
                    {
                        case PDLPosUnaryConstructor.Pred: TermCase(renamed, deleted, term, delColor, renColor, "the position before ", sb); break;
                        case PDLPosUnaryConstructor.Succ: TermCase(renamed, deleted, term, delColor, renColor, "the position after ", sb); break;
                        default: throw new PDLException("undefined operator");
                    }
                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos, delColor, renColor, editScript, sb, varName);
                }).

                Case<PDLPosVar, string>((var) => TermCase(renamed, deleted, term, delColor, renColor, var, sb)).

                Case<PDLPredSet, string, PDLPred>((var, phi) =>
                {
                    Pattern.Match(phi).
                        Case<PDLModSetEq, PDLSet, int, int>((set, m, n) =>
                        {
                            var cast = set as PDLAllPosUpto;
                            if (m == 2 && cast != null && cast.pos is PDLPosVar)
                            {
                                TermCase(renamed, deleted, set, delColor, renColor, "the set of ", sb);
                                TermCase(renamed, deleted, term, "n", delColor, renColor, (n == 1 ? "odd" : "even"), editScript, sb);
                                TermCase(renamed, deleted, set, delColor, renColor, "positions", sb);
                            }
                            else
                            {
                                TermCase(renamed, deleted, term, delColor, renColor, "the set {" + var + " | such that ", sb);
                                ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                                TermCase(renamed, deleted, term, delColor, renColor, "}", sb);
                            }
                        }).
                        Default(() =>
                        {
                            TermCase(renamed, deleted, term, delColor, renColor, "the set {" + var + " | such that ", sb);
                            ToHTMLColoredEnglishStringInt(renamed, deleted, phi, delColor, renColor, editScript, sb, varName);
                            TermCase(renamed, deleted, term, delColor, renColor, "}", sb);
                        });
                }).

                Case<PDLSetBinary, PDLSet, PDLSet, PDLBinarySetOperator>((set1, set2, op) =>
                {
                    switch (op)
                    {
                        case PDLBinarySetOperator.Intersection:
                            {
                                TermCase(renamed, deleted, term, delColor, renColor, "the intersection of ", sb); break;
                            }
                        case PDLBinarySetOperator.Union:
                            {
                                TermCase(renamed, deleted, term, delColor, renColor, "the union of ", sb); break;
                            }
                        default: throw new PDLException("undefined operator");
                    }
                    ToHTMLColoredEnglishStringInt(renamed, deleted, set1, delColor, renColor, editScript, sb, varName);
                    TermCase(renamed, deleted, term, delColor, renColor, ", and ", sb);
                    ToHTMLColoredEnglishStringInt(renamed, deleted, set2, delColor, renColor, editScript, sb, varName);
                    TermCase(renamed, deleted, term, delColor, renColor, ", ", sb);

                }).

                Case<PDLSetCmpPos, PDLPos, PDLComparisonOperator>((pos1, op) =>
                {
                    switch (op)
                    {
                        case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, delColor, renColor, "the set of positions after ", sb); break;
                        case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, delColor, renColor, "the set of positions from ", sb); break;
                        case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, delColor, renColor, "the set of positions before ", sb); break;
                        case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, delColor, renColor, "the set of positions up to ", sb); break;
                        default: throw new PDLException("undefined operator");
                    }
                    ToHTMLColoredEnglishStringInt(renamed, deleted, pos1, delColor, renColor, editScript, sb, varName);
                }).

                Case<PDLSetVar, string>((var) => TermCase(renamed, deleted, term, delColor, renColor, var, sb)).

                Case<PDLSetModuleComparison, PDLSet, int, int, PDLComparisonOperator>((set, m, n, op) =>
                {
                    if (m == 2)
                    {
                        //CASE mod 2
                        Pattern.Match(set).
                            Case<PDLAllPos>(() =>
                            {
                                switch (op)
                                {
                                    case PDLComparisonOperator.Eq:
                                        {
                                            if(negate)
                                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("<i>{0}</i> doesn't have ", varName), editScript, sb);
                                            else
                                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("<i>{0}</i> has ", varName), editScript, sb);
                                            TermCase(renamed, deleted, term, "n", delColor, renColor, (n == 1 ? "odd" : "even"), editScript, sb);
                                            TermCase(renamed, deleted, set, "", delColor, renColor, string.Format(" length", varName), editScript, sb);
                                            break;
                                        }
                                    default: throw new PDLException("This formula shouldn't be enumerated with this operator and value 2");
                                }
                            }).
                            Case<PDLIndicesOf, string>((str) =>
                            {
                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("'"), editScript, sb);
                                TermCase(renamed, deleted, set, "str", delColor, renColor, str, editScript, sb);
                                if(negate)
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("' doesn't appear in <i>{0}</i> an ", varName), editScript, sb);
                                else
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("' appears in <i>{0}</i> an ", varName), editScript, sb);

                                TermCase(renamed, deleted, term, "n", delColor, renColor, (n == 1 ? "odd" : "even"), editScript, sb);
                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" number of times"), editScript, sb);
                            }).
                            Default(() =>
                            {
                                switch (op)
                                {
                                    case PDLComparisonOperator.Eq:
                                        {
                                            ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                                            if(negate)
                                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" doesn't have an ", varName), editScript, sb);
                                            else
                                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" has an ", varName), editScript, sb);

                                            TermCase(renamed, deleted, term, "n", delColor, renColor, (n == 1 ? "odd" : "even"), editScript, sb);
                                            TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" number of elements", varName), editScript, sb);
                                            break;
                                        }
                                    default: throw new PDLException("This formula shouldn't be enumerated with this operator and value 2");
                                }
                            });
                    }
                    else
                    {
                        if (n == 0 && op == PDLComparisonOperator.Eq)
                        {
                            //CASE % m = 0
                            Pattern.Match(set).
                                Case<PDLAllPos>(() =>
                                {
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("the "), editScript, sb);
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("length", varName), editScript, sb);
                                    if (negate)
                                        TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" of <i>{0}</i> is not divisible by ", varName), editScript, sb);
                                    else
                                        TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" of <i>{0}</i> is divisible by ", varName), editScript, sb);
                                    TermCase(renamed, deleted, term, "m", delColor, renColor, m.ToString(), editScript, sb);
                                }).
                                Case<PDLIndicesOf, string>((str) =>
                                {
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("the number of times "), editScript, sb);
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("the substring '"), editScript, sb);
                                    TermCase(renamed, deleted, set, "str", delColor, renColor, str, editScript, sb);
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("' appears in <i>{0}</i> ", varName), editScript, sb);
                                    if (negate)
                                        TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("is not divisible by ", varName), editScript, sb);
                                    else
                                        TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("is divisible by ", varName), editScript, sb);
                                    TermCase(renamed, deleted, term, "m", delColor, renColor, m.ToString(), editScript, sb);
                                }).
                                Default(() =>
                                {
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("the size of "), editScript, sb);
                                    ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                                    if (negate)
                                        TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" is not divisible by "), editScript, sb);
                                    else
                                        TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" is divisible by ", varName), editScript, sb);
                                    TermCase(renamed, deleted, term, "m", delColor, renColor, m.ToString(), editScript, sb);
                                });
                        }
                        else
                        {
                            // m!=2 and n!=0 and op not equality
                            Pattern.Match(set).
                                Case<PDLAllPos>(() =>
                                {
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("dividing ", varName), editScript, sb);
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("the length of <i>{0}</i> by ", varName), editScript, sb);
                                    TermCase(renamed, deleted, term, "m", delColor, renColor, m.ToString(), editScript, sb);
                                }).
                                Case<PDLIndicesOf, string>((str) =>
                                {
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("dividing "), editScript, sb);
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("the number of times the substring '"), editScript, sb);
                                    TermCase(renamed, deleted, set, "str", delColor, renColor, str, editScript, sb);
                                    TermCase(renamed, deleted, set, "", delColor, renColor, string.Format("' appears in <i>{0}</i> ", varName), editScript, sb);
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("by "), editScript, sb);
                                    TermCase(renamed, deleted, term, "m", delColor, renColor, m.ToString(), editScript, sb);
                                }).
                                Default(() =>
                                {
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("dividing the size of "), editScript, sb);
                                    ToHTMLColoredEnglishStringInt(renamed, deleted, set, delColor, renColor, editScript, sb, varName);
                                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" by "), editScript, sb);
                                    TermCase(renamed, deleted, term, "m", delColor, renColor, m.ToString(), editScript, sb);
                                });

                            if (negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" doesn't give remainder "), editScript, sb);
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" gives remainder "), editScript, sb);
                            switch (op)
                            {
                                case PDLComparisonOperator.Eq: break;
                                case PDLComparisonOperator.Ge: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" greater than "), editScript, sb); break;
                                case PDLComparisonOperator.Geq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" greater or equal than "), editScript, sb); break;
                                case PDLComparisonOperator.Le: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" smaller than "), editScript, sb); break;
                                case PDLComparisonOperator.Leq: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format(" smaller or equal than "), editScript, sb); break;
                                default: throw new PDLException("Undefined operator");
                            }
                            TermCase(renamed, deleted, term, "n", delColor, renColor, n.ToString(), editScript, sb);
                        }
                    }
                }).

                Case<PDLStringPos, string, PDLStringPosOperator>((str, op) =>
                {
                    switch (op)
                    {
                        case PDLStringPosOperator.FirstOcc: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("the first occurence of ", str), editScript, sb); break;
                        case PDLStringPosOperator.LastOcc: TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("the last occurence of ", str), editScript, sb); break;
                        default: throw new PDLException("undefined operator");
                    }
                    TermCase(renamed, deleted, term, "", delColor, renColor, "'", editScript, sb);
                    TermCase(renamed, deleted, term, "str", delColor, renColor, str, editScript, sb);
                    TermCase(renamed, deleted, term, "", delColor, renColor, "'", editScript, sb);
                }).

                Case<PDLStringQuery, string, PDLStringQueryOp>((str, op) =>
                {
                    TermCase(renamed, deleted, term, "", delColor, renColor, string.Format("s "), editScript, sb);
                    switch (op)
                    {
                        case PDLStringQueryOp.Contains: 
                            if(negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, "doesn't contain ", editScript, sb); 
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, "contains '", editScript, sb); 
                            break;

                        case PDLStringQueryOp.EndsWith: 
                            if(negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, "doesn't end with ", editScript, sb); 
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, "ends with ", editScript, sb); 
                            break;
                        case PDLStringQueryOp.IsString: 
                            if(negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, "isn't the string ", editScript, sb); 
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, "is the string ", editScript, sb); 
                            break;
                        case PDLStringQueryOp.StartsWith: 
                            if(negate)
                                TermCase(renamed, deleted, term, "", delColor, renColor, "doesn't start with ", editScript, sb); 
                            else
                                TermCase(renamed, deleted, term, "", delColor, renColor, "starts with ", editScript, sb); 
                            break;
                        default: throw new PDLException("undefined operator");
                    }
                    TermCase(renamed, deleted, term, "", delColor, renColor, "'", editScript, sb);
                    TermCase(renamed, deleted, term, "str", delColor, renColor, str, editScript, sb);
                    TermCase(renamed, deleted, term, "", delColor, renColor, "'", editScript, sb);
                }).

                Case<PDLTrue>(() => TermCase(renamed, deleted, term, delColor, renColor, "true", sb));
        }
 public Transformation()
 {
     totalCost = 0;
     editScriptAtoB = new TreeEditScript();
     editScriptBtoA = new TreeEditScript();
     pdlA = null;
     pdlB = null;
     pdlMappingTreeA = new Dictionary<string,Pair<PDL,string>>();
     pdlMappingTreeB = new Dictionary<string, Pair<PDL, string>>();
     minSizeForTreeA = 0;
 }
 private void ToHTMLColoredEnglishStringExt(HashSet<PDL> renamed, HashSet<PDL> deleted, PDL term, string delColor, string renColor, TreeEditScript editScript, StringBuilder sb, string varName)
 {
     Pattern.Match(term).
         Case<PDLFalse>(() => TermCase(renamed, deleted, term, delColor, renColor, "no string", sb)).
         Case<PDLTrue>(() => TermCase(renamed, deleted, term, delColor, renColor, "every input string", sb)).
         Case<PDLEmptyString>(() => TermCase(renamed, deleted, term, delColor, renColor, "the empty string", sb)).
         Default(() => {
              sb.Append("{ <i>s</i> | ");
             ToHTMLColoredEnglishStringInt(renamed, deleted, term, delColor, renColor, editScript, sb, varName);
              sb.Append(" }");
         });           
 }
        /** This sets the value in the cell of the ForestDistance table
         */
        private void setForestScript(int a, int b,
                   TreeEditScript script,
                   Dictionary<int, Dictionary<int, TreeEditScript>>
                   forestES)
        {

            Dictionary<int, TreeEditScript> rows = null;
            if (!forestES.ContainsKey(a))
                forestES[a] = new Dictionary<int, TreeEditScript>();

            rows = forestES[a];
            rows[b] = script;
        }
        /** This returns the value in the cell of the ForestDistance table
         */
        private TreeEditScript getForestScript(int a, int b,
                   Dictionary<int, Dictionary<int, TreeEditScript>>
                   forestES)
        {

            Dictionary<int, TreeEditScript> rows = null;
            if (!forestES.ContainsKey(a))
                forestES[a] = new Dictionary<int, TreeEditScript>();

            rows = forestES[a];
            if (!rows.ContainsKey(b))
                rows[b] = new TreeEditScript();

            return rows[b];
        }
        //Computes tree edits distance betwee aTree and bTree
        public Transformation findDistance(TreeDefinition aTree, TreeDefinition bTree)
        {
            distance = new double[aTree.getNodeCount() + 1, bTree.getNodeCount() + 1];
            distScript = new TreeEditScript[aTree.getNodeCount() + 1, bTree.getNodeCount() + 1];

            //Preliminaries
            //1. Find left-most leaf and key roots
            Dictionary<int, int> aLeftLeaf = new Dictionary<int, int>();
            Dictionary<int, int> bLeftLeaf = new Dictionary<int, int>();
            List<int> aTreeKeyRoots = new List<int>();
            List<int> bTreeKeyRoots = new List<int>();

            findHelperTables(aTree, aLeftLeaf, aTreeKeyRoots, aTree.getRootID());

            findHelperTables(bTree, bLeftLeaf, bTreeKeyRoots, bTree.getRootID());

            var a = bTree.getRootID();
            //Comparison
            foreach (int aKeyroot in aTreeKeyRoots)
            {
                foreach (int bKeyroot in bTreeKeyRoots)
                {
                    //Re-initialise forest distance tables
                    Dictionary<int, Dictionary<int, Double>> fD =
                        new Dictionary<int, Dictionary<int, Double>>();

                    //Re-initialise forest edit script distance tables
                    Dictionary<int, Dictionary<int, TreeEditScript>> fESD =
                        new Dictionary<int, Dictionary<int, TreeEditScript>>();

                    setForestDistance(aLeftLeaf[aKeyroot], bLeftLeaf[bKeyroot], 0.0d, fD);
                    //script is automatically null                 

                    //for all descendents of aKeyroot: i
                    for (int i = aLeftLeaf[aKeyroot]; i <= aKeyroot; i++)
                    {
                        var edit = new Delete(i,aTree);

                        setForestDistance(i,
                          bLeftLeaf[bKeyroot] - 1,
                          getForestDistance(i - 1, bLeftLeaf[bKeyroot] - 1, fD) +
                          edit.getCost(),
                          fD);

                        var scriptSuffix = new TreeEditScript(getForestScript(i - 1, bLeftLeaf[bKeyroot] - 1, fESD));
                        scriptSuffix.Insert(edit);

                        setForestScript(i, bLeftLeaf[bKeyroot] - 1, scriptSuffix, fESD);
                    }

                    //for all descendents of bKeyroot: j
                    for (int j = bLeftLeaf[bKeyroot]; j <= bKeyroot; j++)
                    {
                        var edit = new Insert(j, bTree);

                        setForestDistance(aLeftLeaf[aKeyroot] - 1, j,
                          getForestDistance(aLeftLeaf[aKeyroot] - 1, j - 1, fD) +
                          edit.getCost(),
                          fD);

                        var scriptSuffix = new TreeEditScript(getForestScript(aLeftLeaf[aKeyroot] - 1, j - 1, fESD));
                        scriptSuffix.Insert(edit);

                        setForestScript(aLeftLeaf[aKeyroot] - 1, j, scriptSuffix, fESD);
                    }

                    for (int i = aLeftLeaf[aKeyroot]; i <= aKeyroot; i++)
                    {
                        for (int j = bLeftLeaf[bKeyroot]; j <= bKeyroot; j++)
                        {
                            TreeEditScript tempScript = null;

                            EditOperation delEdit = new Delete(i, aTree); ;
                            EditOperation insEdit = new Insert(j, bTree);
                            double min;
                            double delCost = getForestDistance(i - 1, j, fD) + delEdit.getCost();
                            double insCost = getForestDistance(i, j - 1, fD) + insEdit.getCost();

                            //This min compares del vs ins
                            if (delCost <= insCost)
                            {
                                //Option 1: Delete node from aTree
                                tempScript = new TreeEditScript(getForestScript(i - 1, j, fESD));
                                tempScript.Insert(delEdit);
                                min = delCost;
                            }
                            else
                            {
                                //Option 2: Insert node into bTree
                                tempScript = new TreeEditScript(getForestScript(i, j - 1, fESD));
                                tempScript.Insert(insEdit);
                                min = insCost;
                            }

                            if (aLeftLeaf[i] == aLeftLeaf[aKeyroot] && bLeftLeaf[j] == bLeftLeaf[bKeyroot])
                            {
                                var renEdit = new Rename(i, j, aTree, bTree);
                                var dist = getForestDistance(i - 1, j - 1, fD) + renEdit.getCost();

                                distance[i, j] = Math.Min(min, dist);

                                if (min <= dist)
                                {
                                    tempScript = new TreeEditScript(tempScript);
                                    distScript[i, j] = tempScript;
                                }
                                else
                                {
                                    tempScript = new TreeEditScript(getForestScript(i - 1, j - 1, fESD));
                                    tempScript.Insert(renEdit);
                                    distScript[i, j] = tempScript;
                                }
                                setForestDistance(i, j, distance[i, j], fD);
                                setForestScript(i, j, new TreeEditScript(distScript[i, j]), fESD);

                            }
                            else
                            {
                                var value = getForestDistance(aLeftLeaf[i] - 1, bLeftLeaf[j] - 1, fD) + distance[i, j];
                                setForestDistance(i, j, Math.Min(min, value), fD);

                                if (min <= value)
                                    setForestScript(i, j, new TreeEditScript(tempScript), fESD);
                                else
                                {
                                    var tempList = getForestScript(aLeftLeaf[i] - 1, bLeftLeaf[j] - 1, fESD).script;
                                    tempList = distScript[i, j].script.Concat(tempList).ToList();

                                    setForestScript(i, j, new TreeEditScript(tempList), fESD);
                                }

                                setForestDistance(i, j, Math.Min(min, value), fD);
                                
                            }
                        }
                    }
                }
            }

            Transformation transform = new Transformation();
            transform.totalCost = distance[aTree.getNodeCount(), bTree.getNodeCount()];
            transform.editScriptAtoB = distScript[aTree.getNodeCount(), bTree.getNodeCount()];
            transform.pdlA = aTree.pdl;
            transform.pdlB = bTree.pdl;
            transform.pdlMappingTreeB = bTree.pdlNodeMapping;
            transform.pdlMappingTreeA = aTree.pdlNodeMapping;
            return transform;
        }
 public TreeEditScript(TreeEditScript teScript){
     this.script = new List<EditOperation>(teScript.script);
 }
        private void TermCase(HashSet<PDL> renamed, HashSet<PDL> deleted, PDL phi, string tag, string delColor, string renColor, string message, TreeEditScript editScript, StringBuilder sb)
        {
            var isDel = deleted.Contains(phi);
            var isRen = renamed.Contains(phi);
            foreach (var edit in editScript.script)
            {
                if (edit.getCost() > 0)
                {
                    if (isDel && edit is Delete)
                    {
                        var tmp = edit as Delete;
                        if (tmp.pdlA.First == phi && tmp.pdlA.Second == tag)
                        {
                            if(tag== "")
                                sb.AppendFormat("<font color='{0}'><b>{1}</b></font>", delColor, message);
                            else
                                sb.AppendFormat("<i><font color='{0}'><b>{1}</b></font></i>", delColor, message);
                            return;
                        }
                    }
                    else
                        if (isRen && edit is Rename)
                        {
                            var tmp = edit as Rename;
                            if (tmp.pdlA.First == phi && tmp.pdlA.Second == tag)
                            {
                                if (tag == "")
                                    sb.AppendFormat("<font color='{0}'><b>{1}</b></font>", renColor, message);
                                else
                                    sb.AppendFormat("<i><font color='{0}'><b>{1}</b></font></i>", renColor, message);                                
                                return;
                            }
                        }
                }

            }
            if (tag == "")
                sb.AppendFormat("{0}", message);
            else
                sb.AppendFormat("<i>{0}</i>", message);   
        }