import java.util.*;
public class OptionExample {
static abstract class Exp {
abstract Value eval();
abstract String toStrng();
abstract boolean hasZero();
abstract Exp noNegConstants();
}
static abstract class Value extends Exp {
abstract Value add_values(Value other);
abstract Value add(Int other);
abstract Value add(MyString other);
abstract Value add(Rational other);
Value eval() {
return this;
}
}
static class Int extends Value {
public int i;
Int(int i) {
this.i = i;
}
String toStrng() {
return "" + i;
}
boolean hasZero() {
return i==0;
}
Exp noNegConstants() {
if(i < 0)
return new Negate(new Int(-i));
else
return this;
}
Value add_values(Value other) {
return other.add(this);
}
Value add(Int other) {
return new Int(other.i + i);
}
Value add(MyString other) {
return new MyString(other.s + i);
}
Value add(Rational other) {
return new Rational(other.i+other.j*i,other.j);
}
}
static class MyString extends Value {
public String s;
MyString(String s) {
this.s = s;
}
String toStrng() {
return s;
}
boolean hasZero() {
return false;
}
Exp noNegConstants() {
return this;
}
Value add_values(Value other) {
return other.add(this);
}
Value add(Int other) {
return new MyString("" + other.i + s);
}
Value add(MyString other) {
return new MyString(other.s + s);
}
Value add(Rational other) {
return new MyString("" + other.i + "/" + other.j + s);
}
}
static class Rational extends Value {
int i;
int j;
Rational(int i, int j) {
this.i = i;
this.j = j;
}
String toStrng() {
return "" + i + "/" + j;
}
boolean hasZero() {
return i==0;
}
Exp noNegConstants() {
if(i < 0 && j < 0)
return new Rational(-i,-j);
else if(j < 0)
return new Negate(new Rational(i,-j));
else if(i < 0)
return new Negate(new Rational(-i,j));
else
return this;
}
Value add_values(Value other) {
return other.add(this);
}
Value add(Int other) {
return other.add(this);
}
Value add(MyString other) {
return new MyString(other.s + i + "/" + j);
}
Value add(Rational other) {
int a = i;
int b = j;
int c = other.i;
int d = other.j;
return new Rational(a*d+b*c,b*d);
}
}
static class Negate extends Exp {
public Exp e;
Negate(Exp e) {
this.e = e;
}
Value eval() {
return new Int(- ((Int)(e.eval())).i);
}
String toStrng() {
return "-(" + e.toStrng() + ")";
}
boolean hasZero() {
return e.hasZero();
}
Exp noNegConstants() {
return new Negate(e.noNegConstants());
}
}
static class Add extends Exp {
Exp e1;
Exp e2;
Add(Exp e1, Exp e2) {
this.e1 = e1;
this.e2 = e2;
}
Value eval() {
return e1.eval().add_values(e2.eval());
}
String toStrng() {
return "(" + e1.toStrng() + " + " + e2.toStrng() + ")";
}
boolean hasZero() {
return e1.hasZero() || e2.hasZero();
}
Exp noNegConstants() {
return new Add(e1.noNegConstants(), e2.noNegConstants());
}
}
static class Mult extends Exp {
Exp e1;
Exp e2;
Mult(Exp e1, Exp e2) {
this.e1 = e1;
this.e2 = e2;
}
Value eval() {
return new Int(((Int)(e1.eval())).i * ((Int)(e2.eval())).i);
}
String toStrng() {
return "(" + e1.toStrng() + " * " + e2.toStrng() + ")";
}
boolean hasZero() {
return e1.hasZero() || e2.hasZero();
}
Exp noNegConstants() {
return new Mult(e1.noNegConstants(), e2.noNegConstants());
}
}
public static void main(String[] args) {
Value a = new Int(5);
Value b = new Int(6);
System.out.println(new Add(a,b).eval().toStrng());
}
}