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) ))); } }
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)) )); } } }
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))); }