Pretty Printing Scala Case Classes Like A Tree - scala

I am looking to build a tool that when an expression is input into it, it would produce a step by step evaluation proof and render it as a tree. I will also do the same thing for type checking tree.
Here are several examples of expressions and their equivalent ASTs:
1 + 1 + 1 = Plus(Plus(Num(1), Num(1)), Num(1))
\x:int.x = Lambda(x,IntTy,Var(x))
if 1 + x == 2 then 90 + 1 else 99 = IfThenElse(Eq(Plus(Num(1),Var(x)),Num(2)),Plus(Num(90),Num(1)),Num(99))
I want to output a nicely formatted step-by-step execution tree. Taking an example 1:
Num(1) | {eval res.} Num(1) | {eval res.}
--------------------------------- --------------------
Plus(Num(1), Num(1)) | {eval res.} Num(1) | {eval res.}
--------------------------------------------------------------
Plus(Plus(Num(1), Num(1)), Num(1)) | {eval res.}
At each recursive step, I want to embed evaluation result into {eval res.}
In the future, I will also want to add capability of the user being able to do small-step evaluation. So, when we start at the bottom, when a button is clicked or something like that, the Plus(Num(1), Num(1)) | {eval res.} appears but not Num(1) | {eval res.} because left hand side recursion did not bottom out yet and it continues.
Here are a few examples of such proof trees:
https://i.imgur.com/8hv5Mwb.png
And type checking derivation: https://i.imgur.com/J3RvoYT.png
I want to print out a tree in a vertical manner like that. Having looked through related questions, I have not found anyone attempting this.

Related

Solving a left recursion problem in xText

I am currently working on creating a DSL in xText and I am stumbling upon a problem which is probably related to an ambiguity or left recursion problem. I am not sure which of these two problems applies to my case (similar topics I found online also mention that these problems often seem related) but I guess it has to do with left recursion.
On line 100 in my DSL code I declare a rule called Expression. As you can see it aggregates multiple other types (which on their part again aggregate multiple other types and eventually types called Factor (on line 130) can also be aggregated). Eventually this whole 'aggregation tree' boils down to a problem with this Factor type. As you can see, this type can aggregate an Expression again. So there is a loop; an Expression type can eventually contain a Factor type, and the Factor type can then again contain an Expression type (after which this loop can theoretically continue infinitely; I guess that's where the problem is because the ANTLR parser used by xText was not designed for this kind of recursion). I tried to solve this problem by using a syntactic predicate (=> symbol) in the Expression type (see
(=> "endSimpleExpression")
but it's still not working. I know for sure that it has to do with the relationship between the types Expressions and Factor (because if I don't add Expression types in the Factor type, the DSL works just fine). I assume that I am not placing the syntactic predicate on the right place. Another solution that I considered was the use of left Factoring, but I don't know how to apply left factoring in this case. I am curious to your thoughts on this problem.
grammar org.xtext.example.mydsl.FinalDsl with org.eclipse.xtext.common.Terminals
generate finalDsl "http://www.xtext.org/example/mydsl/FinalDsl"
Model:
'functionName' name = STRING
functions += FunctionElements*
;
// Function elements of which the model exists. The model can contain
// library functions, for loops, and if/else statements.
FunctionElements:
ifElseStatements += IfElseStatements |
statements += Statement
;
// IfElse Statements requiring if statements and optionally followed by
// one else statement.
IfElseStatements:
ifStatements += IfStatements
(elseStatement = ElseStatement)?
;
// If statements requiring conditions and optionally followed by
// library functions or for loops.
IfStatements:
'if'
expression = Expression
(ifFunctions += libraryFunctionsEnum | forLoops += ForLoops)
;
// Else statement requiring one or multiple library functions.
ElseStatement:
'else' elseFunctions += libraryFunctionsEnum
;
// For loops requiring one condition and followed by zero or more
// library functions
ForLoops:
'for'
expressions = Expression
libraryFunctions += libraryFunctionsEnum*
;
Statement:
//compoundStatement += CompoundStatement | //left out of Statement because
// otherwise a recursive call exists (statement += compoundstatement += statement
simpleStatement += SimpleStatement |
structuredStatement += StructuredStatement
;
SimpleStatement:
classOperationStatement += ClassOperationStatement |
libraryInterFaceMethodStatement += LibraryInterFaceMethodStatement |
libraryPersistenceMethodStatement += LibraryPersistenceMethodStatement
;
StructuredStatement:
forLoops += ForLoops | ifElseStatements += IfElseStatements
;
ClassOperationStatement:
classOperationName += libraryFunctionsEnum
;
LibraryInterFaceMethodStatement:
interfaceMethods += libraryInterFaceMethodStatementEnum
;
LibraryPersistenceMethodStatement:
persistenceMethods += libraryPersistenceMethodStatementEnum
;
//*Eventually filled with details from class diagram, but for now we manually fill it for the sake of testing.
enum libraryFunctionsEnum:
login='login'|
hasCode= 'encrypt'|
display='display'
;
enum libraryPersistenceMethodStatementEnum:
createInstance = "createInstance" |
log = "log"
;
enum libraryInterFaceMethodStatementEnum:
mesasge = "message" |
error = "error"
;
Expression:
simpleExpression = SimpleExpression
(relationalOperator = RelationalOperator
additionalSimpleExpression = SimpleExpression)?
(=> "endSimpleExpression")
;
SimpleExpression:
term = Term
additionalExpressions += AdditionalExpressions*
;
AdditionalExpressions:
additionOperator = AdditionOperator
term = Term
;
Term:
factorTerm = Factor
additionalTerm += AdditionalTerm*
;
AdditionalTerm:
multiplicationOperator = MultiplicationOperator
factor = Factor
;
// We can optionally integrate Java types right here (int, boolean, string, etc.)
Factor: {Factor} (
"(" expression = Expression ")" |
//'not' factor += Factor |
operationParameterName = OperationParameterName |
classAttributeName += ClassAttributeName |
INT //| STRING //| set = Set
)
;
OperationParameterName: // We can use identifiers right here, but for now I put in a string
'operationParameter' STRING
;
ClassAttributeName: // We can use identifiers right here, but for now I put in a string
STRING
;
RelationalOperator:
"=" | "<>" | "<" | "<=" | ">" | ">=" | "in"
;
AdditionOperator:
"+" | "-" | "or"
;
MultiplicationOperator:
"*" | "/" | "and"
;
enum logicalOperators:
greaterThan='>'|
smallerThan='<'|
greaterOrEqualThan='=>'|
smallerOrEqualThan='<='|
equalTo='=='
;
InternalFinalDsl.g:139:2: [fatal] rule ruleFunctionElements has non-LL(*) decision due to recursive rule invocations reachable from alts 1,2.
So let's look at the rule FunctionElements:
FunctionElements:
ifElseStatements += IfElseStatements |
statements += Statement
;
Okay, so FunctionElements can either be an IfElseStatement or a Statement. That sounds suspicious and sure enough: a Statement can be a StructuredStatement, which can in turn be an IfElseStatement. So the above is ambiguous because an IfElseStatement could either be derived directly via FunctionElements -> IfElseStatement or indirectly via FunctionElements -> Statement -> StructuredStatement -> IfElseStatement.
So you should simply remove the IfElseStatement alternative because it is redundant.

how to construct sub-expressions with only two variables and one arithmatic operation from complex Expression Maple/Matlab?

let the Symbolic expression is as below.
y = s + (a/b)*log((a+c)/(b*a)); %# it can be any type of expression
how can I get all possible sub-expressions with two variables and one operator between them.
subExpression1 = b*a;
subExpression2 = a/b;
I got stuck whlie extracting sub-expressions based on operator. if I read one operator I have to study its LHS and RHS and verify that it operates just on one variable but not a other subexpression.
Is there a way to study both LHS and RHS of a operator ??
any comments and suggestions would be very helpful
Firstly, there is no subexpression a*b in your expression. Inside the call to log in your unparsed input there appears a subterm c/b*a. But in Maple's syntax that gets parsed to something mathematically equivalent to (c*a)/b and not c/(b*a).
But your question contains other ambiguity. Let's consider a few examples:
restart;
expr1 := y = s + (a/b)*log(a+c/b*a);
c a
a ln(a + ---)
b
expr1 := y = s + -------------
b
expr2 := y = s + a*log(a+c/b*a)/b;
c a
a ln(a + ---)
b
expr2 := y = s + -------------
b
expr2 - expr1;
0 = 0
So the expr1 and expr2 are mathematically equivalent. Maple is even holding their structures the same, internally. (You can check that using both the lprint and the dismantle commands.)
So you appear to be asking for a/b to be recognized in either, after parsing the input, even though that term does not appear indentically in the verbatim input (before parsing). That's not wrong, per se, but we'll need to know that it's part of your expectation. If a/b is to be recognized as a candidate subpression of that value, regardless of whether it's entered like expr1 or expr2, then that is a key detail. If that is not your desire then you will really have to justify how they could be distinguished from each other after parsing (since they may parse to the same thing, depending on what's occurred already in the Maple session!).
Also, how do you intend on handling something which is mathematically equivalent to (a*s)/(b)? Do you want code that returns all possible arithmetic pairings, eg. a*s, a/b, s/b? Or do you want just a*s, or just a/b, or just s/b?
Now consider another example:
expr3 := a+c*a/b;
c a
expr3 := a + ---
b
normal(expr3);
a (b + c)
---------
b
Those are mathematically equivalent, though stored differently. Depending on your definition of acceptable "sub-expression" you may or may not want want a/b, or c/b, or b+c, in your results.
I think that you'll probably need to resolve what precisely you want, in at least these three example's ambiguous situations above, before your question could be resolved sensibly.
You can try the semi-documented mtree utility to create a parse tree, which can be used to analyze valid code strings (including symbolics) as well as whole files. Here's how to use it:
tree = mtree('y = s + (a/b)*log((a+c)/(b*a));');
The you can do all sorts of things with it, like dump it to text:
>> tree.dumptree
1 *<root>: EXPR: 1/03
2 *Arg: EQUALS: 1/03
3 *Left: ID: 1/01 (y)
4 *Right: PLUS: 1/07
5 *Left: CALL: 1/05
6 *Left: ID: 1/05 (s)
7 *Right: MUL: 1/14
8 *Left: PARENS: 1/09
9 *Arg: DIV: 1/11
10 *Left: CALL: 1/10
11 *Left: ID: 1/10 (a)
12 *Right: CALL: 1/12
13 *Left: ID: 1/12 (b)
14 *Right: CALL: 1/18
15 *Left: ID: 1/15 (log)
16 *Right: DIV: 1/24
17 *Left: PARENS: 1/19
18 *Arg: PLUS: 1/21
19 *Left: CALL: 1/20
20 *Left: ID: 1/20 (a)
21 *Right: CALL: 1/22
22 *Left: ID: 1/22 (c)
23 *Right: PARENS: 1/25
24 *Arg: MUL: 1/27
25 *Left: CALL: 1/26
26 *Left: ID: 1/26 (b)
27 *Right: CALL: 1/28
28 *Left: ID: 1/28 (a)
Notice that when you have binary operations (e.g. PLUS or MUL) they are followed by a *Left and a *Right line which contains the operands.
Take a look inside MATLAB\R20###\toolbox\matlab\codetools\#mtree\mtree.m for more information on what can be done with these objects.

if-statement: how to rewrite in matlab

I'm newby in Matlab. I have took the work code with complex if-statement condition and need to rewrite it. This code should prepare some initial data to solve an optimization task. This if-statement condition looks like:
x=[784.8 959.2 468 572 279 341 139.5 170.5 76.5 93.5 45 55];
a=nchoosek(x,6); % all possible combinations from 6 elements of x
n=length(a);
q=[];
for i=1:n
if( ((a(i,1)==x(1)) & (a(i,2)==x(2))) |
((a(i,1)==x(3)) & (a(i,2)==x(4))) |
((a(i,1)==x(5)) & (a(i,2)==x(6))) |
((a(i,1)==x(7)) & (a(i,2)==x(8))) |
((a(i,2)==x(3)) & (a(i,3)==x(4))) |
((a(i,2)==x(5)) & (a(i,3)==x(6))) |
((a(i,2)==x(7)) & (a(i,3)==x(8))) |
((a(i,3)==x(3)) & (a(i,4)==x(4))) |
((a(i,3)==x(5)) & (a(i,4)==x(6))) |
((a(i,3)==x(7)) & (a(i,4)==x(8))) |
((a(i,3)==x(9)) & (a(i,4)==x(10)))|
((a(i,4)==x(5)) & (a(i,5)==x(6))) |
((a(i,4)==x(7)) & (a(i,5)==x(8))) |
((a(i,4)==x(9)) & (a(i,5)==x(10)))|
((a(i,5)==x(5)) & (a(i,6)==x(6))) |
((a(i,5)==x(7)) & (a(i,6)==x(8))) |
((a(i,5)==x(9)) & (a(i,6)==x(10)) |
((a(i,5)==x(11)) & (a(i,6)==x(12)))))
q(i,:)=a(i,:);
end;
end;
q;
R1=a-q;
R1(~any(R1,2),:) = [];
R1(:, ~any(R1)) = [];
Question: Could anyone give an idea how to rewrite if-statement to improve readability of code?
If I understood you correctly, what the convoluted if statement basically says
If "x(1) x(2)" or "x(3) x(4)" or ... "x(11) x(12)" appears anywhere consecutively in row i
Think about it:
((a(i,1)==x(1)) & (a(i,2)==x(2))) | ((a(i,1)==x(3)) & (a(i,2)==x(4))) |
((a(i,1)==x(5)) & (a(i,2)==x(6))) | ((a(i,1)==x(7)) & (a(i,2)==x(8)))
is no different from:
((a(i,1)==x(1)) & (a(i,2)==x(2))) | ((a(i,1)==x(3)) & (a(i,2)==x(4))) |
((a(i,1)==x(5)) & (a(i,2)==x(6))) | ((a(i,1)==x(7)) & (a(i,2)==x(8))) |
((a(i,1)==x(9)) & (a(i,2)==x(10))) | ((a(i,1)==x(11)) & (a(i,2)==x(12)))
since [x(9) x(10)] and [x(11) x(12)] will never appear at a(i, 1:2), so the line I added is always false and does not change the result of the chain of OR's. But if makes the logic much easier to understand. Same logic applies to a(i,2:3), a(i,3:4)..., complete those cases too and then you will get the first statement I made in this answer.
Then, instead of generating a directly from x, you should generate a from the INDEX of x, i.e. [1:12], as such:
a = nchoosek(1:length(x), 6);
Why? You said x consists of real numbers, and using == on real numbers does not guarantee success, and is a very bad practice in general.
Then, your target becomes:
find if sequence `[1 2]` or `[3 4]` or `[5 6]` ... exists in each line of `a`
which is equivalent to:
find if there is any odd number n followed by n+1
This logic can be represented as:
success = any (mod(a(:,1:end-1), 2) & diff(a,1,2)==1, 2)
Now success(i) will be true/false for the every a(i) that your statement evaluates to the same value. This method is better than your statement because it is very concise, automatically adapts to different sizes of x and does not need to run in a loop.
And if you want to get the actual combination of x values, just do
x(a(i)); % Get the ith permutation of x
x(a); % Get all permutation of x
x(a(success,:)); % Get all permutation of x that satisfy the requirement.
EDIT:
q = a; % q is basically a copy of a
q(~success,:) = 0; % except the `non-success` rows are zero
x(q) - x(a) % suppose q and a store index, this will give you the substraction.

Multiple queries (OR statements) using find

Currently to perform multiple queries using find, I invoke each query individually separated by |
index = find(strcmp(data{:,{'type'}},'A') | strcmp(data{:,{'type'}},'B') | strcmp(data{:,{'type'}},'C') | strcmp(data{:,{'type'}},'D'));
To find all rows that where the field 'type' contains either A, B, C or D.
data is held in a table hence the usage of }.
Is there a more concise way of doing this without the need to specify the query in full each time?
You could use ismember instead of multiple uses of strcmp.
index = find(ismember(data{:,{'type'}}, {'A','B','C','D'}));
An alternative (because ismember will probably be slower than multiple uses of strcmp) would be to factor out the repeated code -
x = data{:, {'type'}}; %# This isn't valid MATLAB but whatever...
index = find(strcmp(x,'A') | strcmp(x,'B') | strcmp(x,'C') | strcmp(x,'D'));
You could also use multiple lines for readability
x = data{:, {'type'}}; %# This isn't valid MATLAB but whatever...
index = find(strcmp(x,'A') ...
| strcmp(x,'B') ...
| strcmp(x,'C') ...
| strcmp(x,'D'));

Simplify Boolean expression with De Morgan's laws

I need to simplify this Boolean expression with De Morgan's laws.
¬c xor (¬b ∨ c)
Could someone help me?
(accidentally made two accounts, so just responding with this one)
Ive found the best way to visualize a logic formula you do not understand is to make a table for it.
In the case of XOR, it represents One variable or another, but not both. So, lets make a table for A XOR B
A | B | Result
T | T | F *1
T | F | T *2
F | T | T *3
F | F | F *4
To generate the smallest possible result from the above table we can first take the most complex result that takes into account each option. Converting each line into a logical statement is fairly easy.
First, throw out anything that results in a False, Then take those that result in true, and convert them into a logical statement separated by 'OR's. In this case, 1 and 4 are false, and 2 and 3 are true. This means we only need to create logical statements for 2 and 3. I think how to do so would be best explained by example
Lets say X, Y, and Z are our variables, and the table gave us the following rows as true:
T | T | F - X & Y & ¬Z
F | T | F - ¬X & Y & ¬Z
F | F | F - ¬X & ¬Y & ¬Z
then to complete, we simply 'OR' them together
(X & Y & ¬Z) V (¬X & Y & ¬Z) V (¬X & ¬Y & ¬Z)
as you can see, where the variable is true, you put the variable directly in, and where it is false, you put a '¬' before the variable. The statement above basically says...
(True when X=T,Y=T,Z=F: False otherwise) OR (True when X=F,Y=T,Z=F: False otherwise) OR (True when X=F,Y=F,Z=F: False otherwise)
So finally bringing it back to our XOR the table rows are...
*2 A & ¬B
*3 ¬A & B
and are combined to be...
(A & ¬B) V (¬A & B)
So, now that you have an explanation of what to do with xor, you can apply this example to your problem, and come up with a logical statement you can use De Morgan's laws on to simplify.
first you have to split up xor into its basic form.
XOR represents A or B where A != B. If you can do that you should have more luck using demorgans on the whole equation