예제 #1
0
        private static IEnumerable <Match> matchRepeatRepeat(SymbolicString s1, SymbolicString s2)
        {
            Debug.Assert(s1.root.isWord());
            Debug.Assert(s2.root.isWord());

            // Assume s1 is fully consumed
            foreach (var m in allLeftMatches(s1, s2))
            {
                yield return(m);
            }

            // Assume s2 is fully consumed
            foreach (var m in allLeftMatches(s2, s1))
            {
                yield return(m.reverse());
            }

            // Assume both are fully consumed
            if (omegaEqual(s1.root, s2.root))
            {
                yield return(Match.FullMatch(ComparisonExpression.Equal(
                                                 LinearIntegerExpression.Times(s1.root.wordLength(), s1.repeat),
                                                 LinearIntegerExpression.Times(s2.root.wordLength(), s2.repeat)
                                                 )));
            }
            else
            {
                yield return(Match.FullMatch(LogicalExpression.And(
                                                 ComparisonExpression.Equal(s2.length(), 0),
                                                 ComparisonExpression.Equal(s1.length(), 0)
                                                 )));
            }
        }
예제 #2
0
        private static IEnumerable <Match> longLeftMatches(SymbolicString s1, SymbolicString s2)
        {
            var l1    = s1.root.wordLength();
            var l2    = s2.root.wordLength();
            var g     = gcd(l1, l2);
            var v_beg = LinearIntegerExpression.FreshVariable();
            var v_end = LinearIntegerExpression.FreshVariable();

            // Split exactly at s2 root border
            yield return(Match.PartialSecond(
                             LogicalExpression.And(
                                 // the beginning matches the s1
                                 ComparisonExpression.Equal(
                                     LinearIntegerExpression.Times(l2, v_beg),
                                     LinearIntegerExpression.Times(l1, s1.repeat)
                                     ),
                                 // left over right bit is nonempty
                                 ComparisonExpression.GreaterThan(
                                     LinearIntegerExpression.Times(l2, v_end),
                                     0
                                     ),
                                 // beginning and end match s2
                                 ComparisonExpression.Equal(v_beg + v_end, s2.repeat),
                                 ComparisonExpression.GreaterThanOrEqual(v_beg, 0),
                                 ComparisonExpression.GreaterThanOrEqual(v_end, 0)
                                 ),
                             SymbolicString.Repeat(s2.root, v_end)
                             ));

            // Split in the middle of s2 root
            if (l2 != 1)
            {
                for (int i = g; i < l2; i += g)
                {
                    var suffix = SymbolicString.Concat(s2.root.sub_strings.Skip(i));
                    yield return(Match.PartialSecond(
                                     LogicalExpression.And(
                                         ComparisonExpression.Equal(
                                             LinearIntegerExpression.Times(l2, v_beg) + g,
                                             LinearIntegerExpression.Times(l1, s1.repeat)
                                             ),
                                         ComparisonExpression.GreaterThan(
                                             LinearIntegerExpression.Times(l2, v_beg) + suffix.length(),
                                             0
                                             ),
                                         ComparisonExpression.Equal(v_beg + v_end + 1, s2.repeat),
                                         ComparisonExpression.GreaterThanOrEqual(v_beg, 0),
                                         ComparisonExpression.GreaterThanOrEqual(v_end, 0)
                                         ),
                                     SymbolicString.Concat(suffix, SymbolicString.Repeat(s2.root, v_end))
                                     ));
                }
            }
        }
예제 #3
0
        public LinearIntegerExpression length()
        {
            switch (this.expression_type)
            {
            case SymbolicStringType.Symbol:
                return(LinearIntegerExpression.Constant(1));

            case SymbolicStringType.Concat:
                return(LinearIntegerExpression.Plus(this.sub_strings.Select(x => x.length())));

            case SymbolicStringType.Repeat:
                var sub = this.root.length();
                Contract.Assert(sub.isConstant());
                return(LinearIntegerExpression.Times(sub.constant, this.repeat));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
 public static LinearIntegerExpression operator -(LinearIntegerExpression a, LinearIntegerExpression b)
 {
     return(Plus(a, LinearIntegerExpression.Times(-1, b)));
 }