Skip to content
Snippets Groups Projects
Commit d1eaeec4 authored by dgelessus's avatar dgelessus
Browse files

Evaluate :let expressions when variable is set, not when it it used

parent be3891f3
No related branches found
No related tags found
No related merge requests found
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
:help :let :help :let
``` ```
%% Output %% Output
``` ```
:let NAME VALUE :let NAME EXPR
``` ```
Set the value of a local variable. Evaluate an expression and store it in a local variable.
Variables are available in all states and are not affected by machine loads. A variable created by `:let` shadows any identifier from the machine with the same name. The expression is evaluated only once, in the current state, and its value is stored. Once set, variables are available in all states and are not affected by machine loads. A variable created by `:let` shadows any identifier from the machine with the same name.
```
:let NAME VALUE
```
Set the value of a local variable. **Note:** The values of local variables are currently stored in text form. Values must have a syntactically valid text representation, and large values may cause performance issues.
:let NAME EXPR
Evaluate an expression and store it in a local variable.
Variables are available in all states and are not affected by machine loads. A variable created by `:let` shadows any identifier from the machine with the same name. The expression is evaluated only once, in the current state, and its value is stored. Once set, variables are available in all states and are not affected by machine loads. A variable created by `:let` shadows any identifier from the machine with the same name.
**Note:** The values of local variables are currently stored in text form. Values must have a syntactically valid text representation, and large values may cause performance issues.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
:help :unlet :help :unlet
``` ```
%% Output %% Output
``` ```
:unlet NAME :unlet NAME
``` ```
Remove a local variable. Remove a local variable.
```
:unlet NAME :unlet NAME
```
Remove a local variable. Remove a local variable.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
:let hello 1..5 \/ {10} :let hello 1..5 \/ {10}
``` ```
%% Output
$\{1,2,3,4,5,10\}$
{1,2,3,4,5,10}
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
hello hello
``` ```
%% Output %% Output
$\{1,2,3,4,5,10\}$ $\{1,2,3,4,5,10\}$
{1,2,3,4,5,10} {1,2,3,4,5,10}
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
:let n 2 :let n 2
``` ```
%% Output
$2$
2
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
n n
``` ```
%% Output %% Output
$2$ $2$
2 2
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
{x | x : hello & x mod n = 0} {x | x : hello & x mod n = 0}
``` ```
%% Output %% Output
$\{2,4,10\}$ $\{2,4,10\}$
{2,4,10} {2,4,10}
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
:unlet n :unlet n
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
n n
``` ```
%% Output %% Output
:eval: Computation not completed: Unknown identifier "n", the possible completion is "not" :eval: Computation not completed: Unknown identifier "n", the possible completion is "not"
......
...@@ -5,6 +5,10 @@ import java.util.List; ...@@ -5,6 +5,10 @@ import java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import de.prob.animator.domainobjects.AbstractEvalResult;
import de.prob.animator.domainobjects.EvalResult;
import de.prob.animator.domainobjects.FormulaExpand;
import de.prob.statespace.AnimationSelector;
import de.prob2.jupyter.ProBKernel; import de.prob2.jupyter.ProBKernel;
import de.prob2.jupyter.UserErrorException; import de.prob2.jupyter.UserErrorException;
...@@ -16,37 +20,44 @@ import org.jetbrains.annotations.Nullable; ...@@ -16,37 +20,44 @@ import org.jetbrains.annotations.Nullable;
public final class LetCommand implements Command { public final class LetCommand implements Command {
private final @NotNull Injector injector; private final @NotNull Injector injector;
private final @NotNull AnimationSelector animationSelector;
@Inject @Inject
public LetCommand(final @NotNull Injector injector) { public LetCommand(final @NotNull Injector injector, final @NotNull AnimationSelector animationSelector) {
super(); super();
this.injector = injector; this.injector = injector;
this.animationSelector = animationSelector;
} }
@Override @Override
public @NotNull String getSyntax() { public @NotNull String getSyntax() {
return ":let NAME VALUE"; return ":let NAME EXPR";
} }
@Override @Override
public @NotNull String getShortHelp() { public @NotNull String getShortHelp() {
return "Set the value of a local variable."; return "Evaluate an expression and store it in a local variable.";
} }
@Override @Override
public @NotNull String getHelpBody() { public @NotNull String getHelpBody() {
return "Variables are available in all states and are not affected by machine loads. A variable created by `:let` shadows any identifier from the machine with the same name.\n\n**Note:** Local variables are currently stored in text form. Values must have a syntactically valid text representation, and large values may cause performance issues."; return "The expression is evaluated only once, in the current state, and its value is stored. Once set, variables are available in all states and are not affected by machine loads. A variable created by `:let` shadows any identifier from the machine with the same name.\n\n**Note:** The values of local variables are currently stored in text form. Values must have a syntactically valid text representation, and large values may cause performance issues.";
} }
@Override @Override
public @Nullable DisplayData run(final @NotNull String argString) { public @NotNull DisplayData run(final @NotNull String argString) {
final List<String> split = CommandUtils.splitArgs(argString, 2); final List<String> split = CommandUtils.splitArgs(argString, 2);
if (split.size() != 2) { if (split.size() != 2) {
throw new UserErrorException("Expected 2 arguments, not " + split.size()); throw new UserErrorException("Expected 2 arguments, not " + split.size());
} }
this.injector.getInstance(ProBKernel.class).getVariables().put(split.get(0), split.get(1)); final String name = split.get(0);
return null; final String expr = split.get(1);
final AbstractEvalResult evaluated = CommandUtils.withSourceCode(expr, () -> this.animationSelector.getCurrentTrace().evalCurrent(expr, FormulaExpand.EXPAND));
if (evaluated instanceof EvalResult) {
this.injector.getInstance(ProBKernel.class).getVariables().put(name, evaluated.toString());
}
return CommandUtils.displayDataForEvalResult(evaluated);
} }
@Override @Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment