/* * JFLAP - Formal Languages and Automata Package * * * Susan H. Rodger * Computer Science Department * Duke University * August 27, 2009 * Copyright (c) 2002-2009 * All rights reserved. * JFLAP is open source software. Please see the LICENSE for terms. * */ package pumping.cf; import pumping.ContextFreePumpingLemma; import pumping.LemmaMath; /** * The context-free pumping lemma for L = * {w1vvRw2, : * na(w1) = * na(w2), * |v| ≥ 3, v, w1, * & w2 ∈ {a, b}*}. * * @author Chris Morgan */ public class W1VVrW2 extends ContextFreePumpingLemma { public String getTitle() { return "w1 v v^R w2 : na(w1) = na(w2), |v|>=3, w1 & w2 element_of {ab}*"; } public String getHTMLTitle() { return "w1vvRw2, : " + "na(w1) = " + "na(w2), " + "|v| " + GREATER_THAN +" 3, v, w1, " + "w2 " + ELEMENT_OF + " " + AB_STAR; } public void setDescription() { partitionIsValid = true; explanation = "Because this is a context-free language, a valid decomposition exists. If |'v'| " + GREATER_THAN + " 3, " + "or if m " + GREATER_OR_EQ + " 8 and there are no \"b\"s in w1 and w2, one could " + "just pump single opposite characters in 'v' and 'vR' repeatedly to find a valid decomposition. " + "For example, if |'v'| = 4, then v could equal the fourth character of 'v' and y the first " + "character of 'vR'. Otherwise, if m " + GREATER_OR_EQ + " 8 and |v| = 3, one could just " + "pump the first \"b\" value in w1 or w2."; } protected void addCases() { // TODO Auto-generated method stub } public void chooseI() { i = 3; } protected void chooseW() { int power = m / 2; w = pumpString("ab", power) + "abbbba" + pumpString("ab", power); } protected void setRange() { myRange = new int[]{2, 15}; } /** * This method returns the first acceptable vvR segment that it * can find. * * @param s the string in which to find the vvR segment. * @return the segment in an int[], with the first index of the segment of the * given string in the first array item, and the last index in the second array item. */ private int[] getVVr(String s) { if (s.length()<6) return null; boolean match; for (int end = s.length() - 1; end >= 5; end--) for (int start = 0; start <= end - 5; start++) if ((end-start) % 2 == 1 && s.charAt(start) == s.charAt(end)) { match = true; for (int i=0; i<=(end-start)/2; i++) if (s.charAt(start+i) != s.charAt(end-i)) match = false; if (match && LemmaMath.countInstances(s.substring(0, start), 'a') == LemmaMath.countInstances(s.substring(end+1), 'a')) return new int[] {start, end}; } return null; } public void chooseDecomposition() { int[] v = getVVr(w); String w1, w2; w1 = w.substring(0, v[0]); w2 = w.substring(v[1]+1); //If possible, the last character in v and the first in v^R if (v[1]-v[0] > 5 || LemmaMath.countInstances(w1, 'b') == 0 && LemmaMath.countInstances(w2, 'b') == 0) setDecomposition(new int[] {v[0] + (v[1]-v[0]) / 2, 1, 0, 1}); //Otherwise, pump the first 'b' character found else if (w1.indexOf('b') > -1) setDecomposition(new int[] {w1.indexOf('b'), 1, 0, 0}); else setDecomposition(new int[] {w2.indexOf('b') + v[1] + 1, 1, 0, 0}); } public boolean isInLang(String s) { char[] list = new char[]{'a', 'b'}; if (LemmaMath.otherCharactersFound(s, list)) return false; if (getVVr(s) == null) return false; else return true; } }