Files
kraken/koka_bench/java/deriv.java
2022-05-19 00:43:27 -04:00

236 lines
5.0 KiB
Java

interface Expr {
}
final class ValExpr implements Expr {
long value;
ValExpr(long i) {
value = i;
}
}
final class VarExpr implements Expr {
String name;
VarExpr(String s) {
name = s;
}
}
final class LnExpr implements Expr {
Expr expr;
LnExpr(Expr e) {
expr = e;
}
}
final class AddExpr implements Expr {
Expr left;
Expr right;
AddExpr(Expr l, Expr r) {
left = l;
right = r;
}
}
final class MulExpr implements Expr {
Expr left;
Expr right;
MulExpr(Expr l, Expr r) {
left = l;
right = r;
}
}
final class PowExpr implements Expr {
Expr left;
Expr right;
PowExpr(Expr l, Expr r) {
left = l;
right = r;
}
}
public class deriv {
static long pown(long x, long n) {
if (n==0) return 1;
else if (n == 1) return x;
else {
long y = pown(x, n/2);
return (y * y * (n%2 == 0 ? 1 : x));
}
}
static Expr add( Expr x, Expr y ) {
if (x instanceof ValExpr a && y instanceof ValExpr b) {
return new ValExpr( a.value + b.value );
}
else if (x instanceof ValExpr a && a.value == 0) {
return y;
}
else if (y instanceof ValExpr b && b.value == 0) {
return x;
}
else if (y instanceof ValExpr b) {
return add(y,x);
}
else if (x instanceof ValExpr a && y instanceof AddExpr b && b.left instanceof ValExpr bl) {
return add(new ValExpr(a.value + bl.value), b.right);
}
else if (y instanceof AddExpr b && b.left instanceof ValExpr) {
return add(b.left, add(x,b.right));
}
else if (x instanceof AddExpr a) {
return add(a.left, add(a.right,y));
}
else {
return new AddExpr(x,y);
}
}
static Expr mul( Expr x, Expr y ) {
if (x instanceof ValExpr a && y instanceof ValExpr b) {
return new ValExpr( a.value * b.value );
}
else if (x instanceof ValExpr a && a.value == 0) {
return x;
}
else if (y instanceof ValExpr b && b.value == 0) {
return y;
}
else if (x instanceof ValExpr a && a.value == 1) {
return y;
}
else if (y instanceof ValExpr b && b.value == 1) {
return x;
}
else if (y instanceof ValExpr b) {
return mul(y,x);
}
else if (x instanceof ValExpr a && y instanceof MulExpr b && b.left instanceof ValExpr bl) {
return mul(new ValExpr(a.value * bl.value), b.right);
}
else if (y instanceof MulExpr b && b.left instanceof MulExpr) {
return mul(b.left, mul(x,b.right));
}
else if (x instanceof MulExpr a) {
return mul(a.left, mul(a.right,y));
}
else {
return new MulExpr(x,y);
}
}
static Expr powr( Expr x, Expr y ) {
if (x instanceof ValExpr a && y instanceof ValExpr b) {
return new ValExpr(pown(a.value,b.value));
}
else if (y instanceof ValExpr b && b.value == 0) {
return new ValExpr(1);
}
else if (y instanceof ValExpr b && b.value == 1) {
return x;
}
else if (x instanceof ValExpr a && a.value == 0) {
return new ValExpr(0);
}
else {
return new PowExpr(x,y);
}
}
static Expr ln( Expr x ) {
if (x instanceof ValExpr a && a.value == 1) {
return new ValExpr(0);
}
else {
return new LnExpr(x);
}
}
static Expr d( String x, Expr e ) {
if (e instanceof ValExpr) {
return new ValExpr(0);
}
else if (e instanceof VarExpr a) {
return new ValExpr(a.name == x ? 1 : 0);
}
else if (e instanceof AddExpr a) {
Expr f = a.left;
Expr g = a.right;
return add(d(x,f),d(x,g));
}
else if (e instanceof MulExpr a) {
Expr f = a.left;
Expr g = a.right;
return add(mul(f,d(x,g)),mul(g,d(x,f)));
}
else if (e instanceof PowExpr a) {
Expr f = a.left;
Expr g = a.right;
return mul(powr(f,g),add(mul(mul(g,d(x,f)),powr(f,new ValExpr(-1))),mul(ln(f),d(x,g))));
}
else if (e instanceof LnExpr a) {
Expr f = a.expr;
return mul(d(x,f),powr(f,new ValExpr(-1)));
}
else {
return e;
}
}
static long count( Expr e ) {
if (e instanceof ValExpr) {
return 1;
}
else if (e instanceof VarExpr) {
return 1;
}
else if (e instanceof AddExpr a) {
Expr f = a.left;
Expr g = a.right;
return count(f) + count(g);
}
else if (e instanceof MulExpr a) {
Expr f = a.left;
Expr g = a.right;
return count(f) + count(g);
}
else if (e instanceof PowExpr a) {
Expr f = a.left;
Expr g = a.right;
return count(f) + count(g);
}
else if (e instanceof LnExpr a) {
Expr f = a.expr;
return count(f);
}
else {
return 0;
}
}
static Expr deriv( long i, Expr e) {
Expr f = d("x",e);
System.out.println( (i+1) + " count: " + count(f) );
return f;
}
static Expr nest( long s, Expr e) {
long n = s;
while(n > 0) {
e = deriv(s - n, e);
n--;
}
return e;
}
public static void main(String args[])
{
Expr x = new VarExpr("x");
Expr e = powr(x,x);
nest(Integer.parseInt(args[0]),e);
System.out.println( "done" );
}
}