/*
// AlgoDat II, Aufgabe 43
// Christian Semrau

Type Komplex

Functions:
  mk_komplex: REAL x REAL --> Komplex   Konstruktor
  real_part: Komplex --> REAL           Selektor
  im_part: Komplex --> REAL             Selektor
  add: Komplex x Komplex --> Komplex
  sub: Komplex x Komplex --> Komplex
  mult: Komplex x Komplex --> Komplex
  div: Komplex x Komplex -/-> Komplex

Axioms: forall a,b, c,d: REAL, x,y: Komplex
  real_part(mk_komplex(a, b)) = a
  im_part(mk_komplex(a, b)) = b

  add (mk_komplex(a,b), mk_komplex(c,d)) = mk_komplex(a+c, c+d)
  mult(mk_komplex(a,b), mk_komplex(c,d)) = mk_komplex(a*c-b*d, a*d+b*c)

  sub(add (x,y),y) = x
  div(mult(x,y),y) = x
  // wir brauchen ja eigentlich keine Rechenvorschriften, sondern
  // nur eindeutige Eigenschaften ;)

Preconditions: forall x,y: Komplex
  pre(div(x,y)): (real_part(y) != 0) OR (im_part(y) != 0)
  // durch 0 teilen geht nicht
*/

/**
 * AlgoDat II, Aufgabe 43
 * 
 * @author Christian Semrau
 * <a href="mailto:Christian.Semrau@student.uni-magdeburg.de">
 * Christian.Semrau@student.uni-magdeburg.de</a>
 */
class Komplex{
// Komplex ist nicht public, damit sie in dieser Datei kompiliert werden kann
  private double re, im;
  private Komplex(double a, double b){ re = a; im = b; }  
  static Komplex add(Komplex a, Komplex b) {
    return new Komplex(a.re+b.re, a.im+b.im); }
  static Komplex div(Komplex c1, Komplex c2) {
    if (c2.re==0 && c2.im==0) throw new IllegalArgumentException();
    double a=c1.re, b=c1.im, c=c2.re, d=c2.im, n=c*c+d*d;
    return new Komplex((a*c+b*d)/n,(b*c-a*d)/n);
  }  
  static double im_part(Komplex a) { return a.im; }  
  static Komplex mk_komplex(double a, double b) { return new Komplex(a, b); }  
  static Komplex mult(Komplex a, Komplex b) {
    return new Komplex(a.re*b.re-a.im*b.im, a.re*b.im+a.im*b.re); }
  static double real_part(Komplex a) { return a.re; }  
  static Komplex sub(Komplex a, Komplex b) {
    return new Komplex(a.re-b.re, a.im-b.im); }

  public static void main(String args[]) {
    Komplex a,b,z;
    a = mk_komplex(1,1);
    b = mk_komplex(1,-1);
    z = add(a, b);
    System.out.println(a+"+"+b+"="+z);
    z = sub(a, b);
    System.out.println(a+"-"+b+"="+z);
    z = mult(a, b);
    System.out.println(a+"*"+b+"="+z);
    z = div(a, b);
    System.out.println(a+"/"+b+"="+z);
  }
  public String toString() { return "("+re+"+"+im+"i)"; }
}