Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| creating:actions [2025/08/26 22:13] – Improve double-priming error message, remove ambiguous usage of "current" ahelwer | creating:actions [2025/11/03 23:08] (current) – One more instanceof-cast ahelwer | ||
|---|---|---|---|
| Line 146: | Line 146: | ||
| </ | </ | ||
| - | ===== Reading | + | ===== Reading, Priming, & Setting |
| To resolve variable values, modify the ever-more-complicated '' | To resolve variable values, modify the ever-more-complicated '' | ||
| Line 193: | Line 193: | ||
| This is why the prime operator somewhat uniquely modifies the state of the '' | This is why the prime operator somewhat uniquely modifies the state of the '' | ||
| Similar to in '' | Similar to in '' | ||
| - | |||
| - | ===== Setting State Variables ===== | ||
| We can retrieve state variable values, but what about assigning them? | We can retrieve state variable values, but what about assigning them? | ||
| Line 200: | Line 198: | ||
| This requires modifying the '' | This requires modifying the '' | ||
| If the '' | If the '' | ||
| - | <code java [highlight_lines_extra=" | + | <code java [highlight_lines_extra=" |
| case EQUAL: | case EQUAL: | ||
| - | if (left instanceof | + | if (left instanceof UnboundVariable |
| - | UnboundVariable var = (UnboundVariable)left; | + | |
| next.put(var.name().lexeme, | next.put(var.name().lexeme, | ||
| return true; | return true; | ||
| Line 210: | Line 207: | ||
| </ | </ | ||
| - | We only modify variable values in '' | + | We only modify variable values in '' |
| - | + | ||
| - | Although we won't yet use it, now is also a good time to define our '' | + | |
| - | <code java> | + | |
| - | void step(Token location) { | + | |
| - | if (!isComplete()) { | + | |
| - | throw new RuntimeError(location, | + | |
| - | " | + | |
| - | } | + | |
| - | + | ||
| - | primed = false; | + | |
| - | current = next; | + | |
| - | clearNext(); | + | |
| - | } | + | |
| - | + | ||
| - | private void isComplete() { | + | |
| - | return !variables.isEmpty() && next.values().stream() | + | |
| - | .noneMatch(v -> v instanceof | + | |
| - | } | + | |
| - | + | ||
| - | private void clearNext() { | + | |
| - | next = new HashMap<> | + | |
| - | for (Token variable : variables.values()) { | + | |
| - | next.put(variable.lexeme, | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | '' | + | |
| - | + | ||
| - | Now we see things taking shape: '' | + | |
| - | The system' | + | |
| - | Then, '' | + | |
| - | The values of variables in '' | + | |
| ===== Nondeterminism ===== | ===== Nondeterminism ===== | ||
| Line 269: | Line 233: | ||
| public Interpreter(boolean replMode) { | public Interpreter(boolean replMode) { | ||
| - | </ | ||
| - | |||
| - | We also update '' | ||
| - | <code java [highlight_lines_extra=" | ||
| - | private void clearNext() { | ||
| - | possibleNext = new HashSet<> | ||
| - | next = new HashMap<> | ||
| </ | </ | ||
| Line 316: | Line 273: | ||
| For more on this peculiar issue, consult the Java '' | For more on this peculiar issue, consult the Java '' | ||
| - | Now we can write the central loop: | + | This code also requires a new '' |
| + | <code java> | ||
| + | private void clearNext() { | ||
| + | possibleNext = new HashSet<> | ||
| + | next = new HashMap<> | ||
| + | for (Token variable : variables.values()) { | ||
| + | next.put(variable.lexeme, | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Now we can write the central | ||
| <code java [highlight_lines_extra=" | <code java [highlight_lines_extra=" | ||
| while (!possibleNext.isEmpty()) { | while (!possibleNext.isEmpty()) { | ||
| Line 329: | Line 297: | ||
| Note again the judicious use of '' | Note again the judicious use of '' | ||
| + | This code requires yet another '' | ||
| + | <code java> | ||
| + | private boolean isComplete() { | ||
| + | return !variables.isEmpty() && next.values().stream() | ||
| + | .noneMatch(v -> v instanceof UnboundVariable); | ||
| + | } | ||
| + | </ | ||
| It's worth spending some time considering the '' | It's worth spending some time considering the '' | ||
| Line 363: | Line 338: | ||
| Actions like '' | Actions like '' | ||
| Add the following code to the '' | Add the following code to the '' | ||
| - | <code java [highlight_lines_extra=" | + | <code java [highlight_lines_extra=" |
| case IN: | case IN: | ||
| checkSetOperand(expr.operator, | checkSetOperand(expr.operator, | ||
| - | if (left instanceof | + | if (left instanceof UnboundVariable |
| - | UnboundVariable var = (UnboundVariable)left; | + | |
| Map< | Map< | ||
| for (Object element : (Set<?> | for (Object element : (Set<?> | ||
| Line 434: | Line 408: | ||
| private void checkIsValue(Object... operands) { | private void checkIsValue(Object... operands) { | ||
| for (Object operand : operands) { | for (Object operand : operands) { | ||
| - | if (operand instanceof UnboundVariable) { | + | if (operand instanceof UnboundVariable |
| - | UnboundVariable var = (UnboundVariable)operand; | + | |
| throw new RuntimeError(var.name(), | throw new RuntimeError(var.name(), | ||
| } | } | ||
| Line 444: | Line 417: | ||
| In our '' | In our '' | ||
| Also, two values can only be compared for equality if they are both defined: | Also, two values can only be compared for equality if they are both defined: | ||
| - | <code java [highlight_lines_extra=" | + | <code java [highlight_lines_extra=" |
| case EQUAL: | case EQUAL: | ||
| - | if (left instanceof UnboundVariable) { | + | if (left instanceof UnboundVariable |
| - | UnboundVariable var = (UnboundVariable)left; | + | |
| checkIsValue(right); | checkIsValue(right); | ||
| next.put(var.name().lexeme, | next.put(var.name().lexeme, | ||
| Line 500: | Line 472: | ||
| if (replMode && statements.size() == 1 | if (replMode && statements.size() == 1 | ||
| - | && statements.get(0) instanceof Stmt.Print) { | + | && statements.get(0) instanceof Stmt.Print |
| - | tryStep((Stmt.Print)statements.get(0)); | + | tryStep(action); |
| } else { | } else { | ||
| interpreter.interpret(statements); | interpreter.interpret(statements); | ||
| Line 548: | Line 520: | ||
| Map< | Map< | ||
| - | interpreter.setNextState(nextState); | + | interpreter.goToState(nextState); |
| - | interpreter.step(action.location); | + | |
| System.out.println(true); | System.out.println(true); | ||
| System.out.println(nextState); | System.out.println(nextState); | ||
| Line 556: | Line 527: | ||
| We also print out '' | We also print out '' | ||
| - | This called two methods; one, in '' | + | This called two methods; one, '' |
| <code java> | <code java> | ||
| - | void setNextState(Map< | + | void goToState(Map< |
| - | | + | |
| + | primed = state == null; | ||
| + | clearNext(); | ||
| } | } | ||
| </ | </ | ||
| Line 594: | Line 567: | ||
| Now we can put it all together and build a real model checker in [[creating: | Now we can put it all together and build a real model checker in [[creating: | ||
| - | [[creating: | + | [[creating: |