NOTE: the interpreter you are working with for this assignment is very simple, in the sense that it does not do a whole lot. For example, the only things you can put in an input file are of the form: expression ; and /* commented text */ where "expression" is an expression in the Arith language. Things like strings and lambda expressions are not supported. Also, you cannot write definitions like "short_name = long_expression" as you were able to do on the last assignment. All of this keeps the interpreter simple, but at the expense of making it a bit harder to use. ============================================================================ The type of eval is: eval : term -> term When you download the interpreter, the version of eval as given does the following: if there is a term t2 such that "t1 --> t2" (i.e., t1 small-steps to t2), then "eval t1" returns t2. If instead there is no term t2 such that "t1 --> t2", then "eval t1" simply returns t1. Note that this does *not* coincide with the behavior described in the text for eval. We have modified the code slightly. So if you get bizarre results from the interpreter right after you download it, now you know why. ============================================================================ YOUR TASK: Modify the definition of eval so that it does the following. If there is a term t2 such that t1 big-steps to t2 (i.e., t1 \Downarrow t2), then "eval t1" should return t2. If instead there is no term t2 such that t1 big-steps to t2, then "eval t1" should simply return t1. All your changes to code should be confined to one file: core.ml. You can do this assignment by modifying only the definition of eval. However, if you find it helpful to define helper functions outside of eval, that is fine. IMPORTANT: Under no circumstances should a call "eval t" result in an uncaught NoRuleApplies exception. Instead, "eval t" should always return a term. This does not mean that you cannot raise NoRuleApplies inside of any of your code. It does mean that you should implement appropriate exception handling if necessary. ============================================================================ END RESULT: Your interpreter should behave as follows when you're done. If you run it on a file with e1; e2; e3; ... then for each expression ei, the interpreter should printout what ei big-steps to, or if ei does not big-step to anything, it should just print out ei. For example, if your file contains: true; succ (succ (pred 0)); iszero (pred (succ (succ 0))); if (if true then (succ false) else 0) then (succ 0) else (iszero 0); then the interpreter should print out true 2 false (if if true then (succ false) else 0 then 1 else iszero 0) when run on that file. NOTE: the interpreter does do some pretty printing for numbers. For example, "succ 0" will be printed out as "1", "succ (succ 0)" will be printed out as "2", and so on.