Example #1
0
//  load expressions, returning list and augmented parse tree list
func load(filename string) []*RegEx {
	elist := make([]*RegEx, 0) // expression structure list
	rx.LoadExpressions(filename, func(l *rx.RegExParsed) {
		if l.Tree != nil { // if a real expression
			e := &RegEx{}
			e.index = len(elist)
			e.cnum = len(elist)
			e.RegExParsed = *l         // save parse tree
			e.examples = genex(l.Tree) // gen examples unaugmented
			t := rx.Augment(l.Tree, e.index)
			e.dfa = rx.BuildDFA(t) // build DFA
			if verbose {
				fmt.Println()
				showexpr(e)     // show details of expr
				showexamples(e) // show its examples
			}
			elist = append(elist, e)
		}
	})
	if verbose {
		fmt.Printf("\nloaded %d expression(s), ignored %d more\n",
			rx.InputRegExCount, rx.InputErrorCount)
	}
	return elist
}
Example #2
0
//  details responds to an inspection request for a single expression
func details(w http.ResponseWriter, r *http.Request) {
	field := fmt.Sprintf("v%d", baseExpr)
	expr := r.FormValue(field)     // must read before any writing
	expr = strings.TrimSpace(expr) // trim leading/trailing blanks
	putheader(w, r, "Inspect Expression")
	tree, err := rx.Parse(expr)
	if err == nil {
		fmt.Fprintf(w, "<P>Regular Expression: %s\n", hx(expr))
		// must print (or at least stringize) tree before augmenting
		fmt.Fprintf(w, "<P>Initial Parse Tree: %s\n", hx(tree))

		augt := rx.Augment(tree, 0)
		dfa := rx.BuildDFA(augt)
		dmin := dfa.Minimize()

		fmt.Fprintf(w, "<P>Augmented Tree: %s\n", hx(augt))
		fmt.Fprintf(w, "<h2>Examples</h2>\n<P>")
		genexamples(w, tree, 0)
		genexamples(w, tree, 1)
		genexamples(w, tree, 2)
		genexamples(w, tree, 3)
		genexamples(w, tree, 5)
		genexamples(w, tree, 8)

		showaut(w, dmin, []string{expr})
	} else {
		fmt.Fprint(w, "<P>")
		showerror(w, err)
	}

	fmt.Fprint(w, "<h2>Try another?</h2>")
	putform(w, "/details", "Enter a regular expression:",
		1, []string{expr}, 0, nil)
	putfooter(w, r)
}
Example #3
0
// individual handles separate processing of each input regex
func individual(l *rx.RegExParsed, cx int, i int, image string, augt rx.Node) {
	babble("tree:   %s\n", image)
	babble("augmnt: %v\n", augt)
	x := augt.MaxLen()
	if x >= 0 {
		babble("length: %d to %d\n", augt.MinLen(), x)
	} else {
		babble("length: %d to *\n", augt.MinLen())
	}
	babble("cplxty: %d\n", cx)

	dfa := rx.BuildDFA(augt)

	if *opt['R'] {
		rand.Seed(int64(seedvalue))
	}
	if *opt['g'] {
		rx.ShowLabel(os.Stdout, "Examples")
		examples(dfa, l.Tree, 0) // gen and test w/ max repl of 0
		examples(dfa, l.Tree, 1) // ... and 1
		examples(dfa, l.Tree, 2) // ... and 2
		examples(dfa, l.Tree, 3) // ... and 3
		examples(dfa, l.Tree, 5) // ... and 5
		examples(dfa, l.Tree, 8) // ... and 8
	}
	showDFA(dfa, "Annotated Tree", false)
}
Example #4
0
// main control
func main() {

	filename := cmdline() // process command line

	maxEx := *numElem * 4
	exprs, trees := load(filename)            // load expressions
	qns := make([]string, 0, maxEx)           //create list of question words
	answers := new(rx.BitSet)                 //create list of answers
	dfaList := make([]*rx.DFA, 0, len(trees)) //list of candidate DFAs
	ind := make([]int, 0, len(dfaList))       //index array to track id of each regex

	a := 0
	init := 0

	if *mode == 1 { //run with examples

		//ask for examples
		fmt.Println("Enter some examples: ")

		//read examples
		r := bufio.NewReader(os.Stdin)
		line, err := r.ReadString(delim)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		for line != string('\n') {
			line = line[:len(line)-1]
			qns = append(qns, line)
			answers.Set(a)
			a++
			line, err = r.ReadString(delim)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		}

		//ask for counter examples
		fmt.Println("\nEnter some counter-examples: ")
		rr := bufio.NewReader(os.Stdin)

		//read counter examples
		line, err = rr.ReadString(delim)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		for line != string('\n') {
			line = line[:len(line)-1]
			qns = append(qns, line)
			line, err = rr.ReadString(delim)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}

		}

		fmt.Printf("Processing ...\n")

		//build the DFAs of all candidates
		for i := 0; i < len(trees); i++ {
			aDfa := rx.BuildDFA(trees[i])
			dfaList = append(dfaList, aDfa)
			//fmt.Printf("rx { %d } %s\n", i, exprs[i].Expr)
		}

		fmt.Printf("\n")

		//refine the candidate set based on examples and counter examples
		dfaList, exprs, ind = refine(answers, qns, dfaList, exprs, ind)
		init++

		fmt.Printf("Length of dfaList: %d\n", len(dfaList))
		for i := 0; i < len(ind); i++ {
			fmt.Printf("rx { %d } %s\n", ind[i], exprs[i].Expr)
		}

	} else if *mode == 2 { //partition

		numPerGroup := *numElem

		//build DFAs of all candidates
		for i := 0; i < len(trees); i++ {
			aDfa := rx.BuildDFA(trees[i])
			dfaList = append(dfaList, aDfa)
			//fmt.Printf("rx { %d } %s\n", i, exprs[i].Expr)
		}

		times := 0
		for len(dfaList) > 50 {

			permArray := rand.Perm(len(dfaList)) //randomly permute candidate set
			qns = make([]string, 0, maxEx)       //initialize new set of questions
			answers = new(rx.BitSet)             //initialize new set of answers

			//ask best question in each partition. Return questions and answers
			answers, qns = askBulk(answers, qns, permArray, dfaList, exprs, numPerGroup)

			fmt.Println("Here length of dfaList =", len(dfaList))

			//refine the candidate set based on questions ans answers
			dfaList, exprs, ind = refine(answers, qns, dfaList, exprs, ind)
			init++

			fmt.Printf("Length of dfaList: %d\n", len(dfaList))

			times++
		}

	} else if *mode == 3 { //ask all DFAs

		numPerGroup := *numElem

		//build DFA's of all candidates
		for i := 0; i < len(trees); i++ {
			aDfa := rx.BuildDFA(trees[i])
			dfaList = append(dfaList, aDfa)
			fmt.Printf("rx { %d } %s\n", i, exprs[i].Expr)
		}

		times := 0
		for len(dfaList) > 50 {
			//fmt.Println("iteration = ", times)
			//default partition is 20 per group
			permArray := rand.Perm(len(dfaList)) //randomly permute candidate set
			qns = make([]string, 0, maxEx)       //initialize new set of questions
			answers = new(rx.BitSet)             //initialize new set of answers

			//ask best question based on number of DFAs that accept question word
			answers, qns = askBulk2(answers, qns, permArray, dfaList, exprs, numPerGroup)

			fmt.Println("Here length of dfaList =", len(dfaList))
			//fmt.Printf("\n")

			//refine candidate set based on questions and answers
			dfaList, exprs, ind = refine(answers, qns, dfaList, exprs, ind)
			init++

			fmt.Printf("Length of dfaList: %d\n", len(dfaList))

			times++
		}

	} else { //mode = 0, run basic algorithm
		//build DFA's of all candidates
		for i := 0; i < len(trees); i++ {
			aDfa := rx.BuildDFA(trees[i])
			dfaList = append(dfaList, aDfa)
			//fmt.Printf("rx { %d } %s\n", i, exprs[i].Expr)
		}

	}

	param := 1
	value := *numElem
	tempLen := 0
	done := false
	numPerGroup := 5

	for len(dfaList) > param && !done {

		subjlist := make([]int, 0, *group)
		subjtrees := make([]rx.Node, 0, *group)
		expressions := make([]*RegEx, 0, len(dfaList))

		if init == 0 { //if this is the first iteration, mode = 0

			//pick a random subset
			for i := 0; i < *group && i < len(dfaList); i++ {
				j := rand.Intn(len(dfaList)) // naive; can duplicate
				subjlist = append(subjlist, j)
				subjtrees = append(subjtrees, dfaList[j].Tree)
				expressions = append(expressions, &RegEx{j, exprs[j].Expr})
				fmt.Printf("rx { %d } %s\n", j, exprs[j].Expr)
			}
			init++
		} else if len(dfaList) < value { //if the number of dfa's is small enough, run qns on all remaining

			for i := 0; i < len(dfaList); i++ {
				//j := rand.Intn(len(dfaList)) // naive; can duplicate
				subjlist = append(subjlist, i)
				subjtrees = append(subjtrees, dfaList[i].Tree)
				expressions = append(expressions, &RegEx{ind[i], exprs[i].Expr})
				fmt.Printf("rx { %d } %s\n", ind[i], exprs[i].Expr)
			}

		} else { //if number of dfa's is too large, do nothing
		}

		qns = make([]string, 0, maxEx)       //initialize new set of questions
		answers = new(rx.BitSet)             //initialize new set of answers
		permArray := rand.Perm(len(dfaList)) //randomly permute candidate DFAs
		fmt.Println("len dfa list = ", len(dfaList))

		//ask best question based on number of candidates that accept question word
		answers, qns = askBulk2(answers, qns, permArray, dfaList, exprs, numPerGroup)

		fmt.Printf("\n")

		fmt.Println("before length of dfaList = ", len(dfaList))
		tempLen = len(dfaList) //store current length

		//refine the candidate set based on questions and answers
		dfaList, exprs, ind = refine(answers, qns, dfaList, exprs, ind)

		fmt.Println("length of dfaList = ", len(dfaList))

		//if refinement did not change candidate list then we have equivalent reg exp
		if tempLen == len(dfaList) {
			done = true
			fmt.Println("Main: There are ", len(dfaList), " reg exs that match your query and they are equivalent:")
			for i := 0; i < len(dfaList); i++ {
				fmt.Printf("rx { %d } %s\n ", ind[i], exprs[i].Expr)
			}
		}

	}

	//if one remaining reg ex, print it
	if len(dfaList) == 1 {
		fmt.Printf("\nMain: The reg ex you are looking for is: rx { %d } %s\n\nMETA DATA: \n", ind[0], exprs[0].Expr)

		// print accumulated metadata
		exprs[0].ShowMeta(os.Stdout, "")
		fmt.Printf("\n")
	}

	//if no remaining reg exs, no match in our library
	if len(dfaList) == 0 {
		fmt.Printf("Main: No reg ex in our library matches your query.\n")
	}

}