public class Nn {
   static double I0[]={0,1,0,1}, I1[]={0,1,1,0}, Y[]={0,1,0,0};
   static int numLayer=2;
   static int numNeuron=2;

   public static void main(String[] args) {

      Layer layers[]= new Layer[numLayer];

      layers[0]= new Layer(2);
      layers[1]= new Layer(1);
      for(int count=0; count<1000; count++){
         for(int pat=0; pat<4; pat++) {
            //forward prop
            layers[0].neurons[0].output= I0[pat];
            layers[0].neurons[1].output= I1[pat];
            double o0=layers[0].neurons[0].output;
            double o1=layers[0].neurons[1].output;
            double out= layers[1].neurons[0].getOut(o0,o1);
            //backprop
            layers[1].neurons[0].learn (out, Y[pat], o0, o1);
         }
      }
      //report
      for(int pat=0; pat<4; pat++) {
         System.out.println( layers[1].neurons[0].getOut(I0[pat],I1[pat])); 
      }
   }

}

class Layer {

   Neuron[] neurons;

   public Layer(int numNeuron) {
      neurons= new Neuron[numNeuron];
      for (int i=0; i< numNeuron ; i++) {
          neurons[i]= new Neuron();
       } 
   }
}

class Neuron {

   double th;
   double[] w= new double[2];
   double output;
   double learn_rate=0.1;

   public Neuron () {
      th= Math.random();
      w[0]= Math.random();
      w[1]= Math.random();
   }

   double getOut(double in0, double in1) {
      return 1.0/(1.0+ Math.exp(-w[0]*in0 - w[1]*in1 - th));
   }

   void learn(double out, double Y, double I0, double I1) {
      w[0]= w[0] + learn_rate*(Y-out)*out*(1.0-out)*I0; 
      w[1]= w[1] + learn_rate*(Y-out)*out*(1.0-out)*I1;
      th= th + learn_rate*(Y-out)*out*(1.0-out);
   }
}
