need help n python assignment
Microsoft Word - Pro1.docx In this nfa.py write a minimal finite-automata library. This is an NFA class (with DFA as a special case where delta happens to be a function) with methods: __init__, matches, epsilonClosure, move, NFA_to_DFA, statecount, isDFA, mi nimizeDFA, and generateSVG. Several of these (generateSVG, statecount, matches, isDFA) may not need to be modified at all, and several others have been partially stubbed out for you. • __init__: The constructor accepts a Regex object (defined in regex.py) that may be produced from a string using the regex procedure; e.g., NFA(regex("a*b")) should yield an NFA object that models the regular expression (a*)b. The Regex object yielded by regex("a*b") in this case will be the same as the expression: SeqRegex(StarRegex(CharRegex("a")),CharRegex("b")). • matches: This method accepts a string and returns True or False to indicate if the NFA/DFA receiving the call accepts the string. This code is already written and will work properly both for NFAs and DFAs if you add correct epsilonClosure and move methods. • epsilonClosure: This method takes a set of states in the receiving NFA and yields the set of states which are epsilon-reachable (i.e., reachable without consuming/reading any characters) from any in the input set. Note that the return value should be a superset of the input set as all states are epsilon-reachable from themselves. See the slides online for a formal definition. • move: This method takes a set of states and an (the next) input character, and returns the set of states reachable by traversing exactly one edge in this.delta annotated with the input character. See the slides for this definition as well. • NFA_to_DFA: This method constructs a new NFA object that encodes the NFA this as a DFA. This means the output value should pass the isDFA predicate’s test. This method should not modify this, but should produce a fresh DFA object using the subset construction we saw in class. • statecount: This method returns the number of states in the NFA/DFA. It is already written and will work properly if you use this.Q to maintain the set (or frozenset) of NFA states. • isDFA: This method checks if the receiver is a DFA specifically and not only an NFA. That is, it returns True if and only if this.delta is set of triples encoding a function (from a pair of a state and string to a state) and not a relation (False otherwise). You should not need to change this code unless you decide to represent this.delta in a different way. • minimizeDFA: (Extra credit.) This method should construct and yield a fresh DFA that encodes the current DFA in its minimal form. This method does not need to handle inputs that do not pass isDFA. Writing this method successfully is not required for full points on project 1. • generateSVG: This method is already written. You do not need to modify this method unless you represent NFAs/DFAs differently than the stubbed code suggests. It does not need to work properly; you may break this code and still earn 100% on the project, however, you may find it very helpful for debugging your code and visualizing the NFAs/DFAs your code produces as SVGs. Running this method will save a diagram, nfa.svg, in your working directory. Although not required, it is highly recommended that you write your NFA class in such a way as to keep this code functional. You will need to install graphviz on your system and also the graphviz python3 library if you wish to use this feature. Below are some other general guidelines: • You should not need to modify stubbed out code which is already in the starter. In some cases it will be safe, but its best to treat existing code as a guide to completing the NFA class correctly. When you first download the starter. Try opening a python3 REPL in the /p1/ folder and running: from nfa import * followed by NFA(regex("")).generateSVG() to see that this works. If it does not, you may need to ensure pip3 is installed and then run pip3 install graphviz to install the graphviz package. If it works properly you should see the following SVG when opening nfa.svg or nfa.html which will display the SVG and auto-refresh in case it is modified. • The class’s constructor __init__ consumes a regular expression object (these are defined in regex.py, which you do not need to modify at all, but is worth your perusal before starting.) This implements the RE->NFA constructions by recursively building NFAs. The starter has an example or two to get you started. You should try first implementing this correctly and seeing that your solutions work by testing them with matches and generateSVG. • You should implement move and epsilonClosure methods like we saw in class. epsilonClosure accepts a set of states and returns the set of states which are reachable while reading/consuming no characters. move accepts a set of states, and a single-character string, and returns the set of states reachable by consuming exactly that character via a single edge (no epsilon edges– triples (q0, "", q1) in self.delta. • NFA_to_DFA generates a newly allocated NFA instance which qualifies as a DFA in that isDFA will return true, and which is identical, in the language it denotes, to self, but is a (possibly non-minimal) DFA constructed via the subset algorithm. Note that the State class, defined in state.py can be instantiated with no arguments (in which case it is a fresh, anonymous, and always-unique state) or it can be instantiated with a key object or name object which determines its uniqueness (i.e. "q1"). Consider using the convention State(frozenset({...})) to name DFA states based on sets of NFA states when performing the subset construction. • Write your own tests! Write lots of your own tests. p1-starter/tester.py #!/usr/bin/python3 # ####################### # # This file runs tests for this coding assignment. # Read the file but do not modify. # # ####################### # # Some code taken from test.py from submit # import os, sys, subprocess, json, argparse, signal from subprocess import Popen, PIPE, STDOUT, TimeoutExpired ##################### # Start Test Utilities ##################### def preparefile(file): pass def runcmdsafe(binfile): b_stdout, b_stderr, b_exitcode = runcmd(binfile) return b_stdout, b_stderr, b_exitcode def runcmd(cmd): stdout, stderr, process = None, None, None if os.name != 'nt': cmd = "exec " + cmd with Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT) as process: try: stdout, stderr = process.communicate(timeout=15) except TimeoutExpired: if os.name == 'nt': Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid)) else: process.kill() exit() return stdout, stderr, process.returncode def assertequals(expected, actual): if expected == actual: passtest('') else: failtest(f'Expected {expected} got {actual}') def failtest(message): testmsg('failed', message) def passtest(message): testmsg('passed', message) def testmsg(status, message): x = { "status": status, "message": message } print(json.dumps(x)) sys.exit() ##################### # End Test Utilities ##################### verbose = False def runtest(name): global verbose print('---------------------') print(f'\nRunning test: {name}') try: python_bin = sys.executable output = subprocess.check_output(f'{python_bin} driver.py', cwd=f'test/{name}', shell=True) y = json.loads(output) status = y["status"] message = y["message"] stdout = output if verbose and len(message) > 0: print("\n\nSTDOUT: ") print(message) if status == "failed": print('FAILED') return False if status == "passed": print(' PASSED') return True except: print(' TIMED OUT') return False def runtests(): tests = listtests() num_passed = 0 for test in tests: if runtest(test): num_passed += 1 print('\n===========================') print(f'Summary: {num_passed} / {len(tests)} tests passed') print('===========================') def listtests(): tests = [test for test in os.listdir("test/")] tests.sort() return tests def main(): global verbose parser = argparse.ArgumentParser() parser.add_argument('--list', '-l', help='List available tests', action='store_true') parser.add_argument("--all", "-a", help='Perform all tests', action='store_true') parser.add_argument('--verbose', '-v', help='View test stdout, verbose output', action='store_true') parser.add_argument('--test', '-t', help='Perform a specific testname (case sensitive)') args = parser.parse_args() if args.verbose: verbose = True if args.all: runtests() return if args.test: if not os.path.exists(f'test/{args.test}'): print(f'Test "{args.test}" not found') return runtest(args.test) return if args.list: print("Available tests: ") print(*listtests(), sep='\n') return parser.print_help() if __name__ == "__main__": main() __MACOSX/p1-starter/._tester.py p1-starter/test/public-11/test.py import os, sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..'))) from nfa import * r = regex("(x|y|)(xxyy|xyy|xxy)*") nfar = NFA(r) mindfa = nfar.NFA_to_DFA().minimizeDFA() if (nfar.isDFA() == False and mindfa.isDFA() and mindfa.matches("xxxx") == False and mindfa.matches("xxxy") and mindfa.matches("yxxyyxyy")): exit(0) else: exit(1) __MACOSX/p1-starter/test/public-11/._test.py p1-starter/test/public-11/driver.py #!/usr/bin/python3 ##################################################### ############# LEAVE CODE BELOW ALONE ############# # Include base directory into path import os, sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..'))) # Import tester from tester import failtest, passtest, assertequals, runcmd, preparefile, runcmdsafe ############# END UNTOUCHABLE CODE ############# ##################################################### ################################### # Write your testing script below # ################################### python_bin = sys.executable # prepare necessary files preparefile('./test.py') # run test file b_stdout, b_stderr, b_exitcode = runcmdsafe(f'{python_bin} ./test.py') # convert stdout bytes to utf-8 stdout = "" stderr = "" try: stdout = b_stdout.decode('utf-8') stderr = b_stderr.decode('utf-8') except: pass if b_exitcode == 0: passtest('') else: failtest(stdout+"\n\n"+stderr) __MACOSX/p1-starter/test/public-11/._driver.py __MACOSX/p1-starter/test/._public-11 p1-starter/test/public-10/test.py import os, sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..'))) from nfa import * r0 = DisjRegex(EpsilonRegex(), SeqRegex(SeqRegex(CharRegex("a"),CharRegex("b")),SeqRegex(CharRegex("b"),CharRegex("a")))) r = regex("(abba|)") # You can insert an epsilon by closing a paren after a |, or using parens with nothing between them: () if (NFA(r).NFA_to_DFA().isDFA() and NFA(r).NFA_to_DFA().matches("abba") and NFA(r).NFA_to_DFA().matches("") and NFA(r).NFA_to_DFA().matches("a") == False): exit(0) else: exit(1) __MACOSX/p1-starter/test/public-10/._test.py p1-starter/test/public-10/driver.py #!/usr/bin/python3 ##################################################### ############# LEAVE CODE BELOW ALONE ############# # Include base directory into path import os, sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..'))) # Import tester from tester import failtest