diff --git a/Makefile b/Makefile
index 10ebfcd4fd6cc78dd78e599f6c6bdbed920af59e..d856502eb00c8874a3ece597297736debadc95aa 100644
--- a/Makefile
+++ b/Makefile
@@ -56,6 +56,7 @@ TARGETS=\
   cerberus \
   chrony \
   debie1 \
+  genann \
   gzip124 \
   hiredis \
   icpc \
diff --git a/README.md b/README.md
index 9e9c7550aca2ba46656f4b0b3fccefc2c99d2058..0fb01735f56315fa807934f98a80c847f39e1145 100644
--- a/README.md
+++ b/README.md
@@ -127,6 +127,7 @@ when available. We also summarize the license of each directory below.
 - `debie1`: distribution and use authorized by Patria Aviation Oy,
             Space Systems Finland Ltd. and Tidorum Ltd, see `README.txt`
             and `terms_of_use-2014-05.pdf`
+- `genann`: Zlib, see `LICENSE`
 - `gzip124`: GPL
 - `hiredis`: Redis license (BSD-style), see `COPYING`
 - `icpc`: Unlicense
diff --git a/frama-c b/frama-c
index 086dbf6774409ce5457bbc1ddb232e1f97714b23..4adb46e09b8f6bd9809fa98cf1bbc7731c8eea87 160000
--- a/frama-c
+++ b/frama-c
@@ -1 +1 @@
-Subproject commit 086dbf6774409ce5457bbc1ddb232e1f97714b23
+Subproject commit 4adb46e09b8f6bd9809fa98cf1bbc7731c8eea87
diff --git a/genann/.frama-c/GNUmakefile b/genann/.frama-c/GNUmakefile
new file mode 100644
index 0000000000000000000000000000000000000000..614826732f32e132fe5165595d155a00de41c682
--- /dev/null
+++ b/genann/.frama-c/GNUmakefile
@@ -0,0 +1,49 @@
+# Makefile template for Frama-C/Eva case studies.
+# For details and usage information, see the Frama-C User Manual.
+
+### Prologue. Do not modify this block. #######################################
+-include path.mk
+FRAMAC ?= frama-c
+include $(shell $(FRAMAC)-config -print-share-path)/analysis-scripts/prologue.mk
+###############################################################################
+
+# Edit below as needed. Suggested flags are optional.
+
+MACHDEP = gcc_x86_64
+
+# The source code uses the __FILE__ macro; to obtain stable oracles, we use
+# a specific GCC option based on the directory containing this Makefile.
+mkfile_path := $(abspath $(firstword $(MAKEFILE_LIST))/../..)
+
+## Preprocessing flags (for -cpp-extra-args)
+CPPFLAGS    += \
+  -ffile-prefix-map=$(mkfile_path)=.
+
+## General flags
+FCFLAGS     += \
+  -add-symbolic-path=..:. \
+  -kernel-warn-key annot:missing-spec=abort \
+  -kernel-warn-key typing:implicit-function-declaration=abort \
+
+## Eva-specific flags
+EVAFLAGS    += \
+  -eva-warn-key builtins:missing-spec=abort \
+  -eva-slevel 9 \
+
+## GUI-only flags
+FCGUIFLAGS += \
+
+## Analysis targets (suffixed with .eva)
+TARGETS = genann.eva
+
+### Each target <t>.eva needs a rule <t>.parse with source files as prerequisites
+genann.parse: \
+  ../genann.c \
+  ../test.c \
+
+### Epilogue. Do not modify this block. #######################################
+include $(shell $(FRAMAC)-config -print-share-path)/analysis-scripts/epilogue.mk
+###############################################################################
+
+# optional, for OSCS
+-include ../../Makefile.common
diff --git a/genann/.frama-c/genann.eva/alarms.csv b/genann/.frama-c/genann.eva/alarms.csv
new file mode 100644
index 0000000000000000000000000000000000000000..d353cf06ad00ff0e9a4f7bbe8c2db2a8e1960492
--- /dev/null
+++ b/genann/.frama-c/genann.eva/alarms.csv
@@ -0,0 +1,76 @@
+directory	file	line	function	property kind	status	property
+.	genann.c	115	genann_init	signed_overflow	Unknown	(int)((int)(inputs + 1) * hidden) + (int)((int)((int)(hidden_layers - 1) * (int)(hidden + 1)) * hidden) ≤ 2147483647
+.	genann.c	115	genann_init	signed_overflow	Unknown	(int)(inputs + 1) * hidden ≤ 2147483647
+.	genann.c	115	genann_init	signed_overflow	Unknown	inputs + 1 ≤ 2147483647
+.	genann.c	115	genann_init	signed_overflow	Unknown	(int)((int)(hidden_layers - 1) * (int)(hidden + 1)) * hidden ≤ 2147483647
+.	genann.c	115	genann_init	signed_overflow	Unknown	(int)(hidden_layers - 1) * (int)(hidden + 1) ≤ 2147483647
+.	genann.c	115	genann_init	signed_overflow	Unknown	hidden + 1 ≤ 2147483647
+.	genann.c	116	genann_init	signed_overflow	Unknown	tmp_0 * outputs ≤ 2147483647
+.	genann.c	116	genann_init	signed_overflow	Unknown	inputs + 1 ≤ 2147483647
+.	genann.c	117	genann_init	signed_overflow	Unknown	hidden_weights + output_weights ≤ 2147483647
+.	genann.c	119	genann_init	signed_overflow	Unknown	(int)(inputs + (int)(hidden * hidden_layers)) + outputs ≤ 2147483647
+.	genann.c	119	genann_init	signed_overflow	Unknown	inputs + (int)(hidden * hidden_layers) ≤ 2147483647
+.	genann.c	119	genann_init	signed_overflow	Unknown	hidden * hidden_layers ≤ 2147483647
+.	genann.c	122	genann_init	signed_overflow	Unknown	(int)(total_weights + total_neurons) + (int)(total_neurons - inputs) ≤ 2147483647
+.	genann.c	122	genann_init	signed_overflow	Unknown	total_weights + total_neurons ≤ 2147483647
+.	genann.c	126	genann_init	mem_access	Unknown	\valid(&ret->inputs)
+.	genann.c	127	genann_init	mem_access	Unknown	\valid(&ret->hidden_layers)
+.	genann.c	128	genann_init	mem_access	Unknown	\valid(&ret->hidden)
+.	genann.c	129	genann_init	mem_access	Unknown	\valid(&ret->outputs)
+.	genann.c	131	genann_init	mem_access	Unknown	\valid(&ret->total_weights)
+.	genann.c	132	genann_init	mem_access	Unknown	\valid(&ret->total_neurons)
+.	genann.c	135	genann_init	mem_access	Unknown	\valid(&ret->weight)
+.	genann.c	136	genann_init	mem_access	Unknown	\valid(&ret->output)
+.	genann.c	136	genann_init	mem_access	Unknown	\valid_read(&ret->total_weights)
+.	genann.c	136	genann_init	mem_access	Unknown	\valid_read(&ret->weight)
+.	genann.c	137	genann_init	mem_access	Unknown	\valid(&ret->delta)
+.	genann.c	137	genann_init	mem_access	Unknown	\valid_read(&ret->output)
+.	genann.c	137	genann_init	mem_access	Unknown	\valid_read(&ret->total_neurons)
+.	genann.c	141	genann_init	mem_access	Unknown	\valid(&ret->activation_hidden)
+.	genann.c	142	genann_init	mem_access	Unknown	\valid(&ret->activation_output)
+.	genann.c	164	genann_read	mem_access	Unknown	\valid_read(&ann->total_weights)
+.	genann.c	166	fscanf_va_2	precondition	Unknown	\valid(param0)
+.	genann.c	166	genann_read	mem_access	Unknown	\valid_read(&ann->weight)
+.	genann.c	166	genann_read	precondition of fscanf_va_2	Unknown	\valid(param0)
+.	genann.c	180	genann_copy	mem_access	Unknown	\valid_read(&ann->inputs)
+.	genann.c	180	genann_copy	mem_access	Unknown	\valid_read(&ann->total_neurons)
+.	genann.c	180	genann_copy	mem_access	Unknown	\valid_read(&ann->total_weights)
+.	genann.c	197	genann_randomize	mem_access	Unknown	\valid_read(&ann->total_weights)
+.	genann.c	200	genann_randomize	mem_access	Unknown	\valid(ann->weight + i)
+.	genann.c	200	genann_randomize	mem_access	Unknown	\valid_read(&ann->weight)
+.	genann.c	212	genann_run	mem_access	Unknown	\valid_read(&ann->weight)
+.	genann.c	397	genann_write	mem_access	Unknown	\valid_read(&ann->outputs)
+.	genann.c	401	genann_write	initialization	Unknown	\initialized(ann->weight + i)
+.	test.c	37	basic	mem_access	Unknown	\valid_read(&ann->total_weights)
+.	test.c	71	xor	mem_access	Unknown	\valid(&ann->activation_hidden)
+.	test.c	201	persist	precondition of fclose	Unknown	valid_stream: \valid(stream)
+.	test.c	206	persist	precondition of fclose	Unknown	valid_stream: \valid(stream)
+.	test.c	208	persist	mem_access	Unknown	\valid_read(&second->inputs)
+.	test.c	209	persist	mem_access	Unknown	\valid_read(&second->hidden_layers)
+.	test.c	210	persist	mem_access	Unknown	\valid_read(&second->hidden)
+.	test.c	211	persist	mem_access	Unknown	\valid_read(&second->outputs)
+.	test.c	212	persist	mem_access	Unknown	\valid_read(&second->total_weights)
+.	test.c	216	persist	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	216	persist	initialization	Unknown	\initialized(first->weight + i)
+.	test.c	216	persist	initialization	Unknown	\initialized(second->weight + i)
+.	test.c	216	persist	is_nan_or_infinite	Unknown	\is_finite(*(second->weight + i))
+.	test.c	216	persist	mem_access	Unknown	\valid_read(&second->weight)
+.	test.c	216	persist	mem_access	Unknown	\valid_read(second->weight + i)
+.	test.c	216	persist	signed_overflow	Unknown	lfails + 1 ≤ 2147483647
+.	test.c	229	copy	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	229	copy	mem_access	Unknown	\valid_read(&second->inputs)
+.	test.c	230	copy	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	231	copy	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	232	copy	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	233	copy	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	237	copy	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	237	copy	initialization	Unknown	\initialized(first->weight + i)
+.	test.c	237	copy	initialization	Unknown	\initialized(second->weight + i)
+.	test.c	237	copy	signed_overflow	Unknown	lfails + 1 ≤ 2147483647
+.	test.c	251	sigmoid	signed_overflow	Unknown	ltests + 1 ≤ 2147483647
+.	test.c	251	sigmoid	signed_overflow	Unknown	lfails + 1 ≤ 2147483647
+.	test.c	270	main	signed_overflow	Unknown	(int)(ltests - ts_6) - (int)(lfails - fs_6) ≤ 2147483647
+.	test.c	270	main	signed_overflow	Unknown	-2147483648 ≤ (int)(ltests - ts_6) - (int)(lfails - fs_6)
+.	test.c	271	main	signed_overflow	Unknown	(int)(ltests - ts_7) - (int)(lfails - fs_7) ≤ 2147483647
+.	test.c	271	main	signed_overflow	Unknown	-2147483648 ≤ (int)(ltests - ts_7) - (int)(lfails - fs_7)
+FRAMAC_SHARE/libc	stdio.h	120	fclose	precondition	Unknown	valid_stream: \valid(stream)
diff --git a/genann/.frama-c/genann.eva/metrics.log b/genann/.frama-c/genann.eva/metrics.log
new file mode 100644
index 0000000000000000000000000000000000000000..c489c1d7860d89e4d32e8b88d150a68f986b313f
--- /dev/null
+++ b/genann/.frama-c/genann.eva/metrics.log
@@ -0,0 +1,39 @@
+[metrics] Eva coverage statistics
+=======================
+Syntactically reachable functions = 25 (out of 25)
+Semantically reached functions = 24
+Coverage estimation = 96.0% 
+
+Unreached functions (1) =
+  <genann.c>: genann_act_linear;
+[metrics] References to non-analyzed functions
+------------------------------------
+Function genann_train references genann_act_linear (at genann.c:292)
+Function genann_train references genann_act_linear (at genann.c:293)
+[metrics] Statements analyzed by Eva
+--------------------------
+1042 stmts in analyzed functions, 947 stmts analyzed (90.9%)
+backprop: 18 stmts out of 18 (100.0%)
+genann_act_hidden_indirect: 2 stmts out of 2 (100.0%)
+genann_act_output_indirect: 2 stmts out of 2 (100.0%)
+genann_act_threshold: 2 stmts out of 2 (100.0%)
+genann_copy: 12 stmts out of 12 (100.0%)
+genann_free: 2 stmts out of 2 (100.0%)
+genann_init: 48 stmts out of 48 (100.0%)
+genann_init_sigmoid_lookup: 10 stmts out of 10 (100.0%)
+genann_randomize: 10 stmts out of 10 (100.0%)
+genann_read: 30 stmts out of 30 (100.0%)
+genann_write: 9 stmts out of 9 (100.0%)
+main: 116 stmts out of 116 (100.0%)
+persist: 45 stmts out of 45 (100.0%)
+sigmoid: 21 stmts out of 21 (100.0%)
+train_and: 71 stmts out of 71 (100.0%)
+train_or: 72 stmts out of 72 (100.0%)
+train_xor: 71 stmts out of 71 (100.0%)
+basic: 78 stmts out of 80 (97.5%)
+genann_train: 132 stmts out of 152 (86.8%)
+genann_act_sigmoid_cached: 22 stmts out of 26 (84.6%)
+genann_run: 91 stmts out of 118 (77.1%)
+copy: 31 stmts out of 41 (75.6%)
+xor: 47 stmts out of 73 (64.4%)
+genann_act_sigmoid: 5 stmts out of 11 (45.5%)
diff --git a/genann/.frama-c/genann.eva/nonterm.log b/genann/.frama-c/genann.eva/nonterm.log
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/genann/.frama-c/genann.eva/warnings.log b/genann/.frama-c/genann.eva/warnings.log
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/genann/.frama-c/genann.parse/framac.ast b/genann/.frama-c/genann.parse/framac.ast
new file mode 100644
index 0000000000000000000000000000000000000000..2cd55aae413401085745e4d29e28d6b1fbc2995a
--- /dev/null
+++ b/genann/.frama-c/genann.parse/framac.ast
@@ -0,0 +1,2402 @@
+/* Generated by Frama-C */
+#include "assert.h"
+#include "errno.h"
+#include "math.h"
+#include "signal.h"
+#include "stdarg.h"
+#include "stddef.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "strings.h"
+#include "time.h"
+struct genann;
+struct genann {
+   int inputs ;
+   int hidden_layers ;
+   int hidden ;
+   int outputs ;
+   double (*activation_hidden)(struct genann const *ann, double a) ;
+   double (*activation_output)(struct genann const *ann, double a) ;
+   int total_weights ;
+   int total_neurons ;
+   double *weight ;
+   double *output ;
+   double *delta ;
+};
+typedef struct genann genann;
+genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs);
+
+genann *genann_read(FILE *in);
+
+void genann_randomize(genann *ann);
+
+genann *genann_copy(genann const *ann);
+
+void genann_free(genann *ann);
+
+double const *genann_run(genann const *ann, double const *inputs);
+
+void genann_train(genann const *ann, double const *inputs,
+                  double const *desired_outputs, double learning_rate);
+
+void genann_write(genann const *ann, FILE *out);
+
+void genann_init_sigmoid_lookup(genann const *ann);
+
+double genann_act_sigmoid(genann const *ann __attribute__((__unused__)),
+                          double a);
+
+double genann_act_sigmoid_cached(genann const *ann __attribute__((__unused__)),
+                                 double a);
+
+double genann_act_threshold(struct genann const *ann __attribute__((__unused__)),
+                            double a);
+
+double genann_act_linear(struct genann const *ann __attribute__((__unused__)),
+                         double a);
+
+double genann_act_hidden_indirect(struct genann const *ann, double a)
+{
+  double tmp;
+  tmp = (*(ann->activation_hidden))(ann,a);
+  return tmp;
+}
+
+double genann_act_output_indirect(struct genann const *ann, double a)
+{
+  double tmp;
+  tmp = (*(ann->activation_output))(ann,a);
+  return tmp;
+}
+
+double const sigmoid_dom_min = - 15.0;
+double const sigmoid_dom_max = 15.0;
+double interval;
+double lookup[4096];
+double genann_act_sigmoid(genann const *ann __attribute__((__unused__)),
+                          double a)
+{
+  double __retres;
+  double tmp;
+  if (a < - 45.0) {
+    __retres = (double)0;
+    goto return_label;
+  }
+  if (a > 45.0) {
+    __retres = (double)1;
+    goto return_label;
+  }
+  tmp = exp(- a);
+  __retres = 1.0 / ((double)1 + tmp);
+  return_label: return __retres;
+}
+
+void genann_init_sigmoid_lookup(genann const *ann)
+{
+  int i;
+  double const f = (sigmoid_dom_max - sigmoid_dom_min) / (double)4096;
+  interval = (double)4096 / (sigmoid_dom_max - sigmoid_dom_min);
+  i = 0;
+  while (i < 4096) {
+    lookup[i] = genann_act_sigmoid(ann,sigmoid_dom_min + f * (double)i);
+    i ++;
+  }
+  return;
+}
+
+double genann_act_sigmoid_cached(genann const *ann __attribute__((__unused__)),
+                                 double a)
+{
+  double __retres;
+  int tmp_2;
+  int tmp_1;
+  if (sizeof(a) == sizeof(float)) {
+    int tmp;
+    tmp = __fc_fpclassifyf((float)a);
+    tmp_1 = tmp == 0;
+  }
+  else {
+    int tmp_0;
+    tmp_0 = __fc_fpclassify(a);
+    tmp_1 = tmp_0 == 0;
+  }
+  if (tmp_1) tmp_2 = 0; else tmp_2 = 1;
+  __FC_assert(tmp_2 != 0,"genann.c",87,"!isnan(a)");
+  if (a < sigmoid_dom_min) {
+    __retres = lookup[0];
+    goto return_label;
+  }
+  if (a >= sigmoid_dom_max) {
+    __retres = lookup[4096 - 1];
+    goto return_label;
+  }
+  size_t j = (unsigned long)((a - sigmoid_dom_min) * interval + 0.5);
+  if ((long)(! (! (j >= (size_t)4096)))) {
+    __retres = lookup[4096 - 1];
+    goto return_label;
+  }
+  __retres = lookup[j];
+  return_label: return __retres;
+}
+
+double genann_act_linear(struct genann const *ann __attribute__((__unused__)),
+                         double a)
+{
+  return a;
+}
+
+double genann_act_threshold(struct genann const *ann __attribute__((__unused__)),
+                            double a)
+{
+  double __retres;
+  __retres = (double)(a > (double)0);
+  return __retres;
+}
+
+genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs)
+{
+  genann *__retres;
+  int tmp;
+  int tmp_0;
+  if (hidden_layers < 0) {
+    __retres = (genann *)0;
+    goto return_label;
+  }
+  if (inputs < 1) {
+    __retres = (genann *)0;
+    goto return_label;
+  }
+  if (outputs < 1) {
+    __retres = (genann *)0;
+    goto return_label;
+  }
+  if (hidden_layers > 0) 
+    if (hidden < 1) {
+      __retres = (genann *)0;
+      goto return_label;
+    }
+  if (hidden_layers) tmp = (inputs + 1) * hidden + ((hidden_layers - 1) * (
+                                                    hidden + 1)) * hidden;
+  else tmp = 0;
+  int const hidden_weights = tmp;
+  if (hidden_layers) tmp_0 = hidden + 1; else tmp_0 = inputs + 1;
+  int const output_weights = tmp_0 * outputs;
+  int const total_weights = hidden_weights + output_weights;
+  int const total_neurons = (inputs + hidden * hidden_layers) + outputs;
+  int const size =
+    (int)(sizeof(genann) + sizeof(double) * (unsigned long)((total_weights + total_neurons) + (
+                                                            total_neurons - inputs)));
+  genann *ret = malloc((unsigned long)size);
+  if (! ret) {
+    __retres = (genann *)0;
+    goto return_label;
+  }
+  ret->inputs = inputs;
+  ret->hidden_layers = hidden_layers;
+  ret->hidden = hidden;
+  ret->outputs = outputs;
+  ret->total_weights = total_weights;
+  ret->total_neurons = total_neurons;
+  ret->weight = (double *)((char *)ret + sizeof(genann));
+  ret->output = ret->weight + ret->total_weights;
+  ret->delta = ret->output + ret->total_neurons;
+  genann_randomize(ret);
+  ret->activation_hidden = (double (*)(struct genann const *ann, double a))(& genann_act_sigmoid_cached);
+  ret->activation_output = (double (*)(struct genann const *ann, double a))(& genann_act_sigmoid_cached);
+  genann_init_sigmoid_lookup((genann const *)ret);
+  __retres = ret;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    requires \valid(param3);
+    requires \valid(param2);
+    requires \valid(param1);
+    requires \valid(param0);
+    ensures \initialized(param3);
+    ensures \initialized(param2);
+    ensures \initialized(param1);
+    ensures \initialized(param0);
+    assigns \result, stream->__fc_FILE_data, *param3, *param2, *param1,
+            *param0;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+    assigns *param3
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+    assigns *param2
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+    assigns *param1
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+    assigns *param0
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fscanf_va_1(FILE * __restrict stream, char const * __restrict format,
+                int *param0, int *param1, int *param2, int *param3);
+
+/*@ requires valid_read_string(format);
+    requires \valid(param0);
+    ensures \initialized(param0);
+    assigns \result, stream->__fc_FILE_data, *param0;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+    assigns *param0
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fscanf_va_2(FILE * __restrict stream, char const * __restrict format,
+                double *param0);
+
+genann *genann_read(FILE *in)
+{
+  genann *__retres;
+  int inputs;
+  int hidden_layers;
+  int hidden;
+  int outputs;
+  int rc;
+  int i;
+  __fc_errno = 0;
+  rc = fscanf(in,"%d %d %d %d",& inputs,& hidden_layers,& hidden,& outputs); /* fscanf_va_1 */
+  if (rc < 4) goto _LOR;
+  else 
+    if (__fc_errno != 0) {
+      _LOR: {
+              perror("fscanf");
+              __retres = (genann *)0;
+              goto return_label;
+            }
+    }
+  genann *ann = genann_init(inputs,hidden_layers,hidden,outputs);
+  i = 0;
+  while (i < ann->total_weights) {
+    __fc_errno = 0;
+    rc = fscanf(in," %le",ann->weight + i); /* fscanf_va_2 */
+    if (rc < 1) goto _LOR_0;
+    else 
+      if (__fc_errno != 0) {
+        _LOR_0:
+        {
+          perror("fscanf");
+          genann_free(ann);
+          __retres = (genann *)0;
+          goto return_label;
+        }
+      }
+    i ++;
+  }
+  __retres = ann;
+  return_label: return __retres;
+}
+
+genann *genann_copy(genann const *ann)
+{
+  genann *__retres;
+  int const size =
+    (int)(sizeof(genann) + sizeof(double) * (unsigned long)((ann->total_weights + ann->total_neurons) + (
+                                                            ann->total_neurons - ann->inputs)));
+  genann *ret = malloc((unsigned long)size);
+  if (! ret) {
+    __retres = (genann *)0;
+    goto return_label;
+  }
+  memcpy((void *)ret,(void const *)ann,(unsigned long)size);
+  ret->weight = (double *)((char *)ret + sizeof(genann));
+  ret->output = ret->weight + ret->total_weights;
+  ret->delta = ret->output + ret->total_neurons;
+  __retres = ret;
+  return_label: return __retres;
+}
+
+void genann_randomize(genann *ann)
+{
+  int i;
+  i = 0;
+  while (i < ann->total_weights) {
+    {
+      int tmp;
+      tmp = rand();
+      double r = (double)tmp / (double)32767;
+      *(ann->weight + i) = r - 0.5;
+    }
+    i ++;
+  }
+  return;
+}
+
+void genann_free(genann *ann)
+{
+  free((void *)ann);
+  return;
+}
+
+double const *genann_run(genann const *ann, double const *inputs)
+{
+  double const *__retres;
+  int h;
+  int j;
+  int k;
+  double const *w = (double const *)ann->weight;
+  double *o = ann->output + ann->inputs;
+  double const *i = (double const *)ann->output;
+  memcpy((void *)ann->output,(void const *)inputs,
+         sizeof(double) * (unsigned long)ann->inputs);
+  if (! ann->hidden_layers) {
+    double *ret = o;
+    j = 0;
+    while (j < ann->outputs) {
+      {
+        double const *tmp;
+        double *tmp_1;
+        tmp = w;
+        w ++;
+        double sum = *tmp * - 1.0;
+        k = 0;
+        while (k < ann->inputs) {
+          {
+            double const *tmp_0;
+            tmp_0 = w;
+            w ++;
+            sum += *tmp_0 * *(i + k);
+          }
+          k ++;
+        }
+        tmp_1 = o;
+        o ++;
+        *tmp_1 = genann_act_output_indirect(ann,sum);
+      }
+      j ++;
+    }
+    __retres = (double const *)ret;
+    goto return_label;
+  }
+  j = 0;
+  while (j < ann->hidden) {
+    {
+      double const *tmp_2;
+      double *tmp_4;
+      tmp_2 = w;
+      w ++;
+      double sum_0 = *tmp_2 * - 1.0;
+      k = 0;
+      while (k < ann->inputs) {
+        {
+          double const *tmp_3;
+          tmp_3 = w;
+          w ++;
+          sum_0 += *tmp_3 * *(i + k);
+        }
+        k ++;
+      }
+      tmp_4 = o;
+      o ++;
+      *tmp_4 = genann_act_hidden_indirect(ann,sum_0);
+    }
+    j ++;
+  }
+  i += ann->inputs;
+  h = 1;
+  while (h < ann->hidden_layers) {
+    j = 0;
+    while (j < ann->hidden) {
+      {
+        double const *tmp_5;
+        double *tmp_7;
+        tmp_5 = w;
+        w ++;
+        double sum_1 = *tmp_5 * - 1.0;
+        k = 0;
+        while (k < ann->hidden) {
+          {
+            double const *tmp_6;
+            tmp_6 = w;
+            w ++;
+            sum_1 += *tmp_6 * *(i + k);
+          }
+          k ++;
+        }
+        tmp_7 = o;
+        o ++;
+        *tmp_7 = genann_act_hidden_indirect(ann,sum_1);
+      }
+      j ++;
+    }
+    i += ann->hidden;
+    h ++;
+  }
+  double const *ret_0 = (double const *)o;
+  j = 0;
+  while (j < ann->outputs) {
+    {
+      double const *tmp_8;
+      double *tmp_10;
+      tmp_8 = w;
+      w ++;
+      double sum_2 = *tmp_8 * - 1.0;
+      k = 0;
+      while (k < ann->hidden) {
+        {
+          double const *tmp_9;
+          tmp_9 = w;
+          w ++;
+          sum_2 += *tmp_9 * *(i + k);
+        }
+        k ++;
+      }
+      tmp_10 = o;
+      o ++;
+      *tmp_10 = genann_act_output_indirect(ann,sum_2);
+    }
+    j ++;
+  }
+  __FC_assert((w - ann->weight == (long)ann->total_weights) != 0,"genann.c",
+              271,"w - ann->weight == ann->total_weights");
+  __FC_assert((o - ann->output == (long)ann->total_neurons) != 0,"genann.c",
+              272,"o - ann->output == ann->total_neurons");
+  __retres = ret_0;
+  return_label: return __retres;
+}
+
+void genann_train(genann const *ann, double const *inputs,
+                  double const *desired_outputs, double learning_rate)
+{
+  int h;
+  int j;
+  int k;
+  genann_run(ann,inputs);
+  {
+    double const *o =
+      (double const *)((ann->output + ann->inputs) + ann->hidden * ann->hidden_layers);
+    double *d = ann->delta + ann->hidden * ann->hidden_layers;
+    double const *t = desired_outputs;
+    if (& genann_act_output_indirect == & genann_act_linear) goto _LOR;
+    else 
+      if (ann->activation_output == & genann_act_linear) {
+        _LOR:
+        {
+          j = 0;
+          while (j < ann->outputs) {
+            {
+              double *tmp;
+              double const *tmp_0;
+              double const *tmp_1;
+              tmp = d;
+              d ++;
+              tmp_0 = t;
+              t ++;
+              tmp_1 = o;
+              o ++;
+              *tmp = *tmp_0 - *tmp_1;
+            }
+            j ++;
+          }
+        }
+      }
+      else {
+        j = 0;
+        while (j < ann->outputs) {
+          {
+            double *tmp_2;
+            tmp_2 = d;
+            d ++;
+            *tmp_2 = ((*t - *o) * *o) * (1.0 - *o);
+            o ++;
+            t ++;
+          }
+          j ++;
+        }
+      }
+  }
+  h = ann->hidden_layers - 1;
+  while (h >= 0) {
+    {
+      double const *o_0 =
+        (double const *)((ann->output + ann->inputs) + h * ann->hidden);
+      double *d_0 = ann->delta + h * ann->hidden;
+      double const * const dd =
+        (double const *)(ann->delta + (h + 1) * ann->hidden);
+      double const * const ww =
+        (double const *)((ann->weight + (ann->inputs + 1) * ann->hidden) + 
+                         ((ann->hidden + 1) * ann->hidden) * h);
+      j = 0;
+      while (j < ann->hidden) {
+        {
+          double delta = (double)0;
+          k = 0;
+          while (1) {
+            int tmp_3;
+            if (h == ann->hidden_layers - 1) tmp_3 = ann->outputs;
+            else tmp_3 = ann->hidden;
+            ;
+            if (! (k < tmp_3)) break;
+            {
+              double const forward_delta = *(dd + k);
+              int const windex = k * (ann->hidden + 1) + (j + 1);
+              double const forward_weight = *(ww + windex);
+              delta += forward_delta * forward_weight;
+            }
+            k ++;
+          }
+          *d_0 = (*o_0 * (1.0 - *o_0)) * delta;
+          d_0 ++;
+          o_0 ++;
+        }
+        j ++;
+      }
+    }
+    h --;
+  }
+  {
+    int tmp_4;
+    int tmp_5;
+    double const *d_1 =
+      (double const *)(ann->delta + ann->hidden * ann->hidden_layers);
+    if (ann->hidden_layers) tmp_4 = (ann->inputs + 1) * ann->hidden + 
+                                    ((ann->hidden + 1) * ann->hidden) * (
+                                    ann->hidden_layers - 1);
+    else tmp_4 = 0;
+    double *w = ann->weight + tmp_4;
+    if (ann->hidden_layers) tmp_5 = ann->inputs + ann->hidden * (ann->hidden_layers - 1);
+    else tmp_5 = 0;
+    double const * const i = (double const *)(ann->output + tmp_5);
+    j = 0;
+    while (j < ann->outputs) {
+      {
+        double *tmp_6;
+        tmp_6 = w;
+        w ++;
+        *tmp_6 += (*d_1 * learning_rate) * - 1.0;
+        k = 1;
+        while (1) {
+          int tmp_8;
+          if (ann->hidden_layers) tmp_8 = ann->hidden;
+          else tmp_8 = ann->inputs;
+          ;
+          if (! (k < tmp_8 + 1)) break;
+          {
+            double *tmp_7;
+            tmp_7 = w;
+            w ++;
+            *tmp_7 += (*d_1 * learning_rate) * *(i + (k - 1));
+          }
+          k ++;
+        }
+        d_1 ++;
+      }
+      j ++;
+    }
+    __FC_assert((w - ann->weight == (long)ann->total_weights) != 0,
+                "genann.c",362,"w - ann->weight == ann->total_weights");
+  }
+  h = ann->hidden_layers - 1;
+  while (h >= 0) {
+    {
+      int tmp_9;
+      int tmp_10;
+      double const *d_2 = (double const *)(ann->delta + h * ann->hidden);
+      if (h) tmp_9 = ann->inputs + ann->hidden * (h - 1); else tmp_9 = 0;
+      double const *i_0 = (double const *)(ann->output + tmp_9);
+      if (h) tmp_10 = (ann->inputs + 1) * ann->hidden + ((ann->hidden + 1) * ann->hidden) * (
+                                                        h - 1);
+      else tmp_10 = 0;
+      double *w_0 = ann->weight + tmp_10;
+      j = 0;
+      while (j < ann->hidden) {
+        {
+          double *tmp_11;
+          tmp_11 = w_0;
+          w_0 ++;
+          *tmp_11 += (*d_2 * learning_rate) * - 1.0;
+          k = 1;
+          while (1) {
+            int tmp_13;
+            if (h == 0) tmp_13 = ann->inputs; else tmp_13 = ann->hidden;
+            ;
+            if (! (k < tmp_13 + 1)) break;
+            {
+              double *tmp_12;
+              tmp_12 = w_0;
+              w_0 ++;
+              *tmp_12 += (*d_2 * learning_rate) * *(i_0 + (k - 1));
+            }
+            k ++;
+          }
+          d_2 ++;
+        }
+        j ++;
+      }
+    }
+    h --;
+  }
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1), (indirect: param0);
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), param3, param2, param1, param0;
+ */
+int fprintf_va_1(FILE * __restrict stream, char const * __restrict format,
+                 int param0, int param1, int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), param0;
+ */
+int fprintf_va_2(FILE * __restrict stream, char const * __restrict format,
+                 double param0);
+
+void genann_write(genann const *ann, FILE *out)
+{
+  int i;
+  fprintf(out,"%d %d %d %d",ann->inputs,ann->hidden_layers,ann->hidden,
+          ann->outputs); /* fprintf_va_1 */
+  i = 0;
+  while (i < ann->total_weights) {
+    fprintf(out," %.20e",*(ann->weight + i)); /* fprintf_va_2 */
+    i ++;
+  }
+  return;
+}
+
+static int ltests = 0;
+static int lfails = 0;
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_1(char const * __restrict format, char *param0, int param1,
+                int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_2(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_3(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_4(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_5(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_6(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_7(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+void basic(void)
+{
+  double a;
+  genann *ann = genann_init(1,0,0,1);
+  ltests ++;
+  if (ann->total_weights != 2) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",37,ann->total_weights,2); /* printf_va_1 */
+  }
+  a = (double)0;
+  *(ann->weight + 0) = (double)0;
+  *(ann->weight + 1) = (double)0;
+  {
+    double tmp_2;
+    double const *tmp_1;
+    ltests ++;
+    tmp_1 = genann_run((genann const *)ann,(double const *)(& a));
+    ;
+    tmp_2 = fabs(0.5 - *tmp_1);
+    if (tmp_2 > 0.001) {
+      double const *tmp_0;
+      lfails ++;
+      tmp_0 = genann_run((genann const *)ann,(double const *)(& a));
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",44,0.5,*tmp_0); /* printf_va_2 */
+    }
+  }
+  a = (double)1;
+  {
+    double tmp_5;
+    double const *tmp_4;
+    ltests ++;
+    tmp_4 = genann_run((genann const *)ann,(double const *)(& a));
+    ;
+    tmp_5 = fabs(0.5 - *tmp_4);
+    if (tmp_5 > 0.001) {
+      double const *tmp_3;
+      lfails ++;
+      tmp_3 = genann_run((genann const *)ann,(double const *)(& a));
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",47,0.5,*tmp_3); /* printf_va_3 */
+    }
+  }
+  a = (double)11;
+  {
+    double tmp_8;
+    double const *tmp_7;
+    ltests ++;
+    tmp_7 = genann_run((genann const *)ann,(double const *)(& a));
+    ;
+    tmp_8 = fabs(0.5 - *tmp_7);
+    if (tmp_8 > 0.001) {
+      double const *tmp_6;
+      lfails ++;
+      tmp_6 = genann_run((genann const *)ann,(double const *)(& a));
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",50,0.5,*tmp_6); /* printf_va_4 */
+    }
+  }
+  a = (double)1;
+  *(ann->weight + 0) = (double)1;
+  *(ann->weight + 1) = (double)1;
+  {
+    double tmp_11;
+    double const *tmp_10;
+    ltests ++;
+    tmp_10 = genann_run((genann const *)ann,(double const *)(& a));
+    ;
+    tmp_11 = fabs(0.5 - *tmp_10);
+    if (tmp_11 > 0.001) {
+      double const *tmp_9;
+      lfails ++;
+      tmp_9 = genann_run((genann const *)ann,(double const *)(& a));
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",55,0.5,*tmp_9); /* printf_va_5 */
+    }
+  }
+  a = (double)10;
+  *(ann->weight + 0) = (double)1;
+  *(ann->weight + 1) = (double)1;
+  {
+    double tmp_14;
+    double const *tmp_13;
+    ltests ++;
+    tmp_13 = genann_run((genann const *)ann,(double const *)(& a));
+    ;
+    tmp_14 = fabs(1.0 - *tmp_13);
+    if (tmp_14 > 0.001) {
+      double const *tmp_12;
+      lfails ++;
+      tmp_12 = genann_run((genann const *)ann,(double const *)(& a));
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",60,1.0,*tmp_12); /* printf_va_6 */
+    }
+  }
+  a = (double)(-10);
+  {
+    double tmp_17;
+    double const *tmp_16;
+    ltests ++;
+    tmp_16 = genann_run((genann const *)ann,(double const *)(& a));
+    ;
+    tmp_17 = fabs(0.0 - *tmp_16);
+    if (tmp_17 > 0.001) {
+      double const *tmp_15;
+      lfails ++;
+      tmp_15 = genann_run((genann const *)ann,(double const *)(& a));
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",63,0.0,*tmp_15); /* printf_va_7 */
+    }
+  }
+  genann_free(ann);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_8(char const * __restrict format, char *param0, int param1,
+                int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_9(char const * __restrict format, char *param0, int param1,
+                double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_10(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_11(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_12(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+void xor(void)
+{
+  genann *ann = genann_init(2,1,2,1);
+  ann->activation_hidden = & genann_act_threshold;
+  ann->activation_output = & genann_act_threshold;
+  ltests ++;
+  if (ann->total_weights != 9) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",74,ann->total_weights,9); /* printf_va_8 */
+  }
+  *(ann->weight + 0) = .5;
+  *(ann->weight + 1) = (double)1;
+  *(ann->weight + 2) = (double)1;
+  *(ann->weight + 3) = (double)1;
+  *(ann->weight + 4) = (double)1;
+  *(ann->weight + 5) = (double)1;
+  *(ann->weight + 6) = .5;
+  *(ann->weight + 7) = (double)1;
+  *(ann->weight + 8) = (double)(-1);
+  double input[4][2] =
+    {{(double)0, (double)0},
+     {(double)0, (double)1},
+     {(double)1, (double)0},
+     {(double)1, (double)1}};
+  double output[4] = {(double)0, (double)1, (double)1, (double)0};
+  {
+    double tmp_2;
+    double const *tmp_1;
+    ltests ++;
+    tmp_1 = genann_run((genann const *)ann,(double const *)(input[0]));
+    ;
+    tmp_2 = fabs(output[0] - *tmp_1);
+    if (tmp_2 > 0.001) {
+      double const *tmp_0;
+      lfails ++;
+      tmp_0 = genann_run((genann const *)ann,(double const *)(input[0]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",95,output[0],*tmp_0); /* printf_va_9 */
+    }
+  }
+  {
+    double tmp_5;
+    double const *tmp_4;
+    ltests ++;
+    tmp_4 = genann_run((genann const *)ann,(double const *)(input[1]));
+    ;
+    tmp_5 = fabs(output[1] - *tmp_4);
+    if (tmp_5 > 0.001) {
+      double const *tmp_3;
+      lfails ++;
+      tmp_3 = genann_run((genann const *)ann,(double const *)(input[1]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",96,output[1],*tmp_3); /* printf_va_10 */
+    }
+  }
+  {
+    double tmp_8;
+    double const *tmp_7;
+    ltests ++;
+    tmp_7 = genann_run((genann const *)ann,(double const *)(input[2]));
+    ;
+    tmp_8 = fabs(output[2] - *tmp_7);
+    if (tmp_8 > 0.001) {
+      double const *tmp_6;
+      lfails ++;
+      tmp_6 = genann_run((genann const *)ann,(double const *)(input[2]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",97,output[2],*tmp_6); /* printf_va_11 */
+    }
+  }
+  {
+    double tmp_11;
+    double const *tmp_10;
+    ltests ++;
+    tmp_10 = genann_run((genann const *)ann,(double const *)(input[3]));
+    ;
+    tmp_11 = fabs(output[3] - *tmp_10);
+    if (tmp_11 > 0.001) {
+      double const *tmp_9;
+      lfails ++;
+      tmp_9 = genann_run((genann const *)ann,(double const *)(input[3]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",98,output[3],*tmp_9); /* printf_va_12 */
+    }
+  }
+  genann_free(ann);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, *(param0 + (0 ..));
+ */
+int printf_va_13(char const * __restrict format, char *param0, int param1);
+
+void backprop(void)
+{
+  double input;
+  double output;
+  double const *tmp_0;
+  double const *tmp_1;
+  genann *ann = genann_init(1,0,0,1);
+  input = .5;
+  output = (double)1;
+  tmp_0 = genann_run((genann const *)ann,(double const *)(& input));
+  double first_try = *tmp_0;
+  genann_train((genann const *)ann,(double const *)(& input),
+               (double const *)(& output),.5);
+  tmp_1 = genann_run((genann const *)ann,(double const *)(& input));
+  double second_try = *tmp_1;
+  {
+    double tmp_2;
+    double tmp_3;
+    ltests ++;
+    tmp_2 = fabs(first_try - output);
+    tmp_3 = fabs(second_try - output);
+    if (! (tmp_2 > tmp_3)) {
+      lfails ++;
+      printf("%s:%d error \n",(char *)"./test.c",114); /* printf_va_13 */
+    }
+  }
+  genann_free(ann);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_14(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_15(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_16(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_17(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+void train_and(void)
+{
+  int i;
+  int j;
+  double input[4][2] =
+    {{(double)0, (double)0},
+     {(double)0, (double)1},
+     {(double)1, (double)0},
+     {(double)1, (double)1}};
+  double output[4] = {(double)0, (double)0, (double)0, (double)1};
+  genann *ann = genann_init(2,0,0,1);
+  i = 0;
+  while (i < 50) {
+    j = 0;
+    while (j < 4) {
+      genann_train((genann const *)ann,(double const *)(input[j]),
+                   (double const *)(& output[j]),.8);
+      j ++;
+    }
+    i ++;
+  }
+  ann->activation_output = & genann_act_threshold;
+  {
+    double tmp_2;
+    double const *tmp_1;
+    ltests ++;
+    tmp_1 = genann_run((genann const *)ann,(double const *)(input[0]));
+    ;
+    tmp_2 = fabs(output[0] - *tmp_1);
+    if (tmp_2 > 0.001) {
+      double const *tmp_0;
+      lfails ++;
+      tmp_0 = genann_run((genann const *)ann,(double const *)(input[0]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",135,output[0],*tmp_0); /* printf_va_14 */
+    }
+  }
+  {
+    double tmp_5;
+    double const *tmp_4;
+    ltests ++;
+    tmp_4 = genann_run((genann const *)ann,(double const *)(input[1]));
+    ;
+    tmp_5 = fabs(output[1] - *tmp_4);
+    if (tmp_5 > 0.001) {
+      double const *tmp_3;
+      lfails ++;
+      tmp_3 = genann_run((genann const *)ann,(double const *)(input[1]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",136,output[1],*tmp_3); /* printf_va_15 */
+    }
+  }
+  {
+    double tmp_8;
+    double const *tmp_7;
+    ltests ++;
+    tmp_7 = genann_run((genann const *)ann,(double const *)(input[2]));
+    ;
+    tmp_8 = fabs(output[2] - *tmp_7);
+    if (tmp_8 > 0.001) {
+      double const *tmp_6;
+      lfails ++;
+      tmp_6 = genann_run((genann const *)ann,(double const *)(input[2]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",137,output[2],*tmp_6); /* printf_va_16 */
+    }
+  }
+  {
+    double tmp_11;
+    double const *tmp_10;
+    ltests ++;
+    tmp_10 = genann_run((genann const *)ann,(double const *)(input[3]));
+    ;
+    tmp_11 = fabs(output[3] - *tmp_10);
+    if (tmp_11 > 0.001) {
+      double const *tmp_9;
+      lfails ++;
+      tmp_9 = genann_run((genann const *)ann,(double const *)(input[3]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",138,output[3],*tmp_9); /* printf_va_17 */
+    }
+  }
+  genann_free(ann);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_18(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_19(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_20(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_21(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+void train_or(void)
+{
+  int i;
+  int j;
+  double input[4][2] =
+    {{(double)0, (double)0},
+     {(double)0, (double)1},
+     {(double)1, (double)0},
+     {(double)1, (double)1}};
+  double output[4] = {(double)0, (double)1, (double)1, (double)1};
+  genann *ann = genann_init(2,0,0,1);
+  genann_randomize(ann);
+  i = 0;
+  while (i < 50) {
+    j = 0;
+    while (j < 4) {
+      genann_train((genann const *)ann,(double const *)(input[j]),
+                   (double const *)(& output[j]),.8);
+      j ++;
+    }
+    i ++;
+  }
+  ann->activation_output = & genann_act_threshold;
+  {
+    double tmp_2;
+    double const *tmp_1;
+    ltests ++;
+    tmp_1 = genann_run((genann const *)ann,(double const *)(input[0]));
+    ;
+    tmp_2 = fabs(output[0] - *tmp_1);
+    if (tmp_2 > 0.001) {
+      double const *tmp_0;
+      lfails ++;
+      tmp_0 = genann_run((genann const *)ann,(double const *)(input[0]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",160,output[0],*tmp_0); /* printf_va_18 */
+    }
+  }
+  {
+    double tmp_5;
+    double const *tmp_4;
+    ltests ++;
+    tmp_4 = genann_run((genann const *)ann,(double const *)(input[1]));
+    ;
+    tmp_5 = fabs(output[1] - *tmp_4);
+    if (tmp_5 > 0.001) {
+      double const *tmp_3;
+      lfails ++;
+      tmp_3 = genann_run((genann const *)ann,(double const *)(input[1]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",161,output[1],*tmp_3); /* printf_va_19 */
+    }
+  }
+  {
+    double tmp_8;
+    double const *tmp_7;
+    ltests ++;
+    tmp_7 = genann_run((genann const *)ann,(double const *)(input[2]));
+    ;
+    tmp_8 = fabs(output[2] - *tmp_7);
+    if (tmp_8 > 0.001) {
+      double const *tmp_6;
+      lfails ++;
+      tmp_6 = genann_run((genann const *)ann,(double const *)(input[2]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",162,output[2],*tmp_6); /* printf_va_20 */
+    }
+  }
+  {
+    double tmp_11;
+    double const *tmp_10;
+    ltests ++;
+    tmp_10 = genann_run((genann const *)ann,(double const *)(input[3]));
+    ;
+    tmp_11 = fabs(output[3] - *tmp_10);
+    if (tmp_11 > 0.001) {
+      double const *tmp_9;
+      lfails ++;
+      tmp_9 = genann_run((genann const *)ann,(double const *)(input[3]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",163,output[3],*tmp_9); /* printf_va_21 */
+    }
+  }
+  genann_free(ann);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_22(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_23(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_24(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_25(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+void train_xor(void)
+{
+  int i;
+  int j;
+  double input[4][2] =
+    {{(double)0, (double)0},
+     {(double)0, (double)1},
+     {(double)1, (double)0},
+     {(double)1, (double)1}};
+  double output[4] = {(double)0, (double)1, (double)1, (double)0};
+  genann *ann = genann_init(2,1,2,1);
+  i = 0;
+  while (i < 500) {
+    j = 0;
+    while (j < 4) {
+      genann_train((genann const *)ann,(double const *)(input[j]),
+                   (double const *)(& output[j]),(double)3);
+      j ++;
+    }
+    i ++;
+  }
+  ann->activation_output = & genann_act_threshold;
+  {
+    double tmp_2;
+    double const *tmp_1;
+    ltests ++;
+    tmp_1 = genann_run((genann const *)ann,(double const *)(input[0]));
+    ;
+    tmp_2 = fabs(output[0] - *tmp_1);
+    if (tmp_2 > 0.001) {
+      double const *tmp_0;
+      lfails ++;
+      tmp_0 = genann_run((genann const *)ann,(double const *)(input[0]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",186,output[0],*tmp_0); /* printf_va_22 */
+    }
+  }
+  {
+    double tmp_5;
+    double const *tmp_4;
+    ltests ++;
+    tmp_4 = genann_run((genann const *)ann,(double const *)(input[1]));
+    ;
+    tmp_5 = fabs(output[1] - *tmp_4);
+    if (tmp_5 > 0.001) {
+      double const *tmp_3;
+      lfails ++;
+      tmp_3 = genann_run((genann const *)ann,(double const *)(input[1]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",187,output[1],*tmp_3); /* printf_va_23 */
+    }
+  }
+  {
+    double tmp_8;
+    double const *tmp_7;
+    ltests ++;
+    tmp_7 = genann_run((genann const *)ann,(double const *)(input[2]));
+    ;
+    tmp_8 = fabs(output[2] - *tmp_7);
+    if (tmp_8 > 0.001) {
+      double const *tmp_6;
+      lfails ++;
+      tmp_6 = genann_run((genann const *)ann,(double const *)(input[2]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",188,output[2],*tmp_6); /* printf_va_24 */
+    }
+  }
+  {
+    double tmp_11;
+    double const *tmp_10;
+    ltests ++;
+    tmp_10 = genann_run((genann const *)ann,(double const *)(input[3]));
+    ;
+    tmp_11 = fabs(output[3] - *tmp_10);
+    if (tmp_11 > 0.001) {
+      double const *tmp_9;
+      lfails ++;
+      tmp_9 = genann_run((genann const *)ann,(double const *)(input[3]));
+      ;
+      printf("%s:%d (%f != %f)\n",(char *)"./test.c",189,output[3],*tmp_9); /* printf_va_25 */
+    }
+  }
+  genann_free(ann);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_26(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_27(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_28(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_29(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_30(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, *(param0 + (0 ..));
+ */
+int printf_va_31(char const * __restrict format, char *param0, int param1);
+
+void persist(void)
+{
+  int i;
+  genann *first = genann_init(1000,5,50,10);
+  FILE *out = fopen("persist.txt","w");
+  genann_write((genann const *)first,out);
+  fclose(out);
+  FILE *in = fopen("persist.txt","r");
+  genann *second = genann_read(in);
+  fclose(in);
+  ltests ++;
+  if (first->inputs != second->inputs) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",208,first->inputs,
+           second->inputs); /* printf_va_26 */
+  }
+  ltests ++;
+  if (first->hidden_layers != second->hidden_layers) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",209,first->hidden_layers,
+           second->hidden_layers); /* printf_va_27 */
+  }
+  ltests ++;
+  if (first->hidden != second->hidden) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",210,first->hidden,
+           second->hidden); /* printf_va_28 */
+  }
+  ltests ++;
+  if (first->outputs != second->outputs) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",211,first->outputs,
+           second->outputs); /* printf_va_29 */
+  }
+  ltests ++;
+  if (first->total_weights != second->total_weights) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",212,first->total_weights,
+           second->total_weights); /* printf_va_30 */
+  }
+  i = 0;
+  while (i < first->total_weights) {
+    ltests ++;
+    if (! (*(first->weight + i) == *(second->weight + i))) {
+      lfails ++;
+      printf("%s:%d error \n",(char *)"./test.c",216); /* printf_va_31 */
+    }
+    i ++;
+  }
+  genann_free(first);
+  genann_free(second);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_32(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_33(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_34(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_35(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_36(char const * __restrict format, char *param0, int param1,
+                 int param2, int param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_37(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+void copy(void)
+{
+  int i;
+  genann *first = genann_init(1000,5,50,10);
+  genann *second = genann_copy((genann const *)first);
+  ltests ++;
+  if (first->inputs != second->inputs) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",229,first->inputs,
+           second->inputs); /* printf_va_32 */
+  }
+  ltests ++;
+  if (first->hidden_layers != second->hidden_layers) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",230,first->hidden_layers,
+           second->hidden_layers); /* printf_va_33 */
+  }
+  ltests ++;
+  if (first->hidden != second->hidden) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",231,first->hidden,
+           second->hidden); /* printf_va_34 */
+  }
+  ltests ++;
+  if (first->outputs != second->outputs) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",232,first->outputs,
+           second->outputs); /* printf_va_35 */
+  }
+  ltests ++;
+  if (first->total_weights != second->total_weights) {
+    lfails ++;
+    printf("%s:%d (%d != %d)\n",(char *)"./test.c",233,first->total_weights,
+           second->total_weights); /* printf_va_36 */
+  }
+  i = 0;
+  while (i < first->total_weights) {
+    {
+      double tmp_1;
+      ltests ++;
+      tmp_1 = fabs(*(first->weight + i) - *(second->weight + i));
+      if (tmp_1 > 0.001) {
+        lfails ++;
+        printf("%s:%d (%f != %f)\n",(char *)"./test.c",237,
+               *(first->weight + i),*(second->weight + i)); /* printf_va_37 */
+      }
+    }
+    i ++;
+  }
+  genann_free(first);
+  genann_free(second);
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param3),
+            (indirect: param2), (indirect: param1),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param3, param2, param1, *(param0 + (0 ..));
+ */
+int printf_va_38(char const * __restrict format, char *param0, int param1,
+                 double param2, double param3);
+
+void sigmoid(void)
+{
+  double i = (double)(-20);
+  double const max = (double)20;
+  double const d = .0001;
+  while (i < max) {
+    {
+      double tmp_3;
+      double tmp_1;
+      double tmp_2;
+      ltests ++;
+      tmp_1 = genann_act_sigmoid((genann const *)0,i);
+      tmp_2 = genann_act_sigmoid_cached((genann const *)0,i);
+      tmp_3 = fabs(tmp_1 - tmp_2);
+      if (tmp_3 > 0.001) {
+        double tmp;
+        double tmp_0;
+        lfails ++;
+        tmp = genann_act_sigmoid_cached((genann const *)0,i);
+        tmp_0 = genann_act_sigmoid((genann const *)0,i);
+        printf("%s:%d (%f != %f)\n",(char *)"./test.c",251,tmp_0,tmp); /* printf_va_38 */
+      }
+    }
+    i += d;
+  }
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_39(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_40(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_41(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_42(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_43(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_44(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_45(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_46(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_47(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_48(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_49(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_50(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_51(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_52(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_53(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_54(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_55(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_56(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, param1, param0;
+ */
+int printf_va_57(char const * __restrict format, int param0, int param1,
+                 int param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, param0;
+ */
+int printf_va_58(char const * __restrict format, int param0, int param1);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, param0;
+ */
+int printf_va_59(char const * __restrict format, int param0, int param1);
+
+int main(int argc, char **argv)
+{
+  int __retres;
+  printf("GENANN TEST SUITE\n"); /* printf_va_39 */
+  srand((unsigned int)100);
+  {
+    clock_t tmp_0;
+    int const ts = ltests;
+    int const fs = lfails;
+    clock_t const start = clock();
+    printf("\t%-14s",(char *)"basic"); /* printf_va_40 */
+    basic();
+    tmp_0 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts) - (lfails - fs),
+           lfails - fs,
+           (int)((long)((tmp_0 - start) * (clock_t)1000) / (long)1000000)); /* printf_va_41 */
+  }
+  {
+    clock_t tmp_2;
+    int const ts_0 = ltests;
+    int const fs_0 = lfails;
+    clock_t const start_0 = clock();
+    printf("\t%-14s",(char *)"xor"); /* printf_va_42 */
+    xor();
+    tmp_2 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_0) - (lfails - fs_0),
+           lfails - fs_0,
+           (int)((long)((tmp_2 - start_0) * (clock_t)1000) / (long)1000000)); /* printf_va_43 */
+  }
+  {
+    clock_t tmp_4;
+    int const ts_1 = ltests;
+    int const fs_1 = lfails;
+    clock_t const start_1 = clock();
+    printf("\t%-14s",(char *)"backprop"); /* printf_va_44 */
+    backprop();
+    tmp_4 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_1) - (lfails - fs_1),
+           lfails - fs_1,
+           (int)((long)((tmp_4 - start_1) * (clock_t)1000) / (long)1000000)); /* printf_va_45 */
+  }
+  {
+    clock_t tmp_6;
+    int const ts_2 = ltests;
+    int const fs_2 = lfails;
+    clock_t const start_2 = clock();
+    printf("\t%-14s",(char *)"train and"); /* printf_va_46 */
+    train_and();
+    tmp_6 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_2) - (lfails - fs_2),
+           lfails - fs_2,
+           (int)((long)((tmp_6 - start_2) * (clock_t)1000) / (long)1000000)); /* printf_va_47 */
+  }
+  {
+    clock_t tmp_8;
+    int const ts_3 = ltests;
+    int const fs_3 = lfails;
+    clock_t const start_3 = clock();
+    printf("\t%-14s",(char *)"train or"); /* printf_va_48 */
+    train_or();
+    tmp_8 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_3) - (lfails - fs_3),
+           lfails - fs_3,
+           (int)((long)((tmp_8 - start_3) * (clock_t)1000) / (long)1000000)); /* printf_va_49 */
+  }
+  {
+    clock_t tmp_10;
+    int const ts_4 = ltests;
+    int const fs_4 = lfails;
+    clock_t const start_4 = clock();
+    printf("\t%-14s",(char *)"train xor"); /* printf_va_50 */
+    train_xor();
+    tmp_10 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_4) - (lfails - fs_4),
+           lfails - fs_4,
+           (int)((long)((tmp_10 - start_4) * (clock_t)1000) / (long)1000000)); /* printf_va_51 */
+  }
+  {
+    clock_t tmp_12;
+    int const ts_5 = ltests;
+    int const fs_5 = lfails;
+    clock_t const start_5 = clock();
+    printf("\t%-14s",(char *)"persist"); /* printf_va_52 */
+    persist();
+    tmp_12 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_5) - (lfails - fs_5),
+           lfails - fs_5,
+           (int)((long)((tmp_12 - start_5) * (clock_t)1000) / (long)1000000)); /* printf_va_53 */
+  }
+  {
+    clock_t tmp_14;
+    int const ts_6 = ltests;
+    int const fs_6 = lfails;
+    clock_t const start_6 = clock();
+    printf("\t%-14s",(char *)"copy"); /* printf_va_54 */
+    copy();
+    tmp_14 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_6) - (lfails - fs_6),
+           lfails - fs_6,
+           (int)((long)((tmp_14 - start_6) * (clock_t)1000) / (long)1000000)); /* printf_va_55 */
+  }
+  {
+    clock_t tmp_16;
+    int const ts_7 = ltests;
+    int const fs_7 = lfails;
+    clock_t const start_7 = clock();
+    printf("\t%-14s",(char *)"sigmoid"); /* printf_va_56 */
+    sigmoid();
+    tmp_16 = clock();
+    ;
+    ;
+    ;
+    printf("pass:%2d   fail:%2d   %4dms\n",(ltests - ts_7) - (lfails - fs_7),
+           lfails - fs_7,
+           (int)((long)((tmp_16 - start_7) * (clock_t)1000) / (long)1000000)); /* printf_va_57 */
+  }
+  if (lfails == 0) printf("ALL TESTS PASSED (%d/%d)\n",ltests,ltests); /* printf_va_58 */
+  else printf("SOME TESTS FAILED (%d/%d)\n",ltests - lfails,ltests); /* printf_va_59 */
+  __retres = lfails != 0;
+  return __retres;
+}
+
+
diff --git a/genann/.frama-c/genann.parse/metrics.log b/genann/.frama-c/genann.parse/metrics.log
new file mode 100644
index 0000000000000000000000000000000000000000..b26c37df8186b3973b640f94bc10ab1056db468f
--- /dev/null
+++ b/genann/.frama-c/genann.parse/metrics.log
@@ -0,0 +1,45 @@
+[metrics] Defined functions (25)
+======================
+ backprop (1 call); basic (1 call); copy (1 call);
+ genann_act_hidden_indirect (2 calls);
+ genann_act_linear (address taken) (0 call);
+ genann_act_output_indirect (address taken) (2 calls);
+ genann_act_sigmoid (3 calls);
+ genann_act_sigmoid_cached (address taken) (2 calls);
+ genann_act_threshold (address taken) (0 call); genann_copy (1 call);
+ genann_free (11 calls); genann_init (9 calls);
+ genann_init_sigmoid_lookup (1 call); genann_randomize (2 calls);
+ genann_read (1 call); genann_run (47 calls); genann_train (4 calls);
+ genann_write (1 call); main (0 call); persist (1 call); sigmoid (1 call);
+ train_and (1 call); train_or (1 call); train_xor (1 call); xor (1 call); 
+
+Specified-only functions (0)
+============================
+ 
+
+Undefined and unspecified functions (0)
+=======================================
+ 
+
+'Extern' global variables (0)
+=============================
+ 
+
+Potential entry points (1)
+==========================
+ main; 
+
+Global metrics
+============== 
+Sloc = 1043
+Decision point = 101
+Global variables = 6
+If = 101
+Loop = 32
+Goto = 17
+Assignment = 477
+Exit point = 25
+Function = 25
+Function call = 224
+Pointer dereferencing = 309
+Cyclomatic complexity = 126
diff --git a/genann/.frama-c/genann.parse/warnings.log b/genann/.frama-c/genann.parse/warnings.log
new file mode 100644
index 0000000000000000000000000000000000000000..accee9a71d9cec6fdb9a8bfcddfe80aa32ef2658
--- /dev/null
+++ b/genann/.frama-c/genann.parse/warnings.log
@@ -0,0 +1,2 @@
+test.c:44:[kernel:parser:decimal-float] warning: Floating-point constant 0.001 is not represented exactly. Will use 0x1.0624dd2f1a9fcp-10.
+(warn-once: no further messages from category 'parser:decimal-float' will be emitted)
diff --git a/genann/.frama-c/path.mk b/genann/.frama-c/path.mk
new file mode 120000
index 0000000000000000000000000000000000000000..57620d6d4816c69648f7a48a2ab302665cd5ac66
--- /dev/null
+++ b/genann/.frama-c/path.mk
@@ -0,0 +1 @@
+../../path.mk
\ No newline at end of file
diff --git a/genann/LICENSE b/genann/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..5ab017c453ce1b0073247fae68c1babcccc62aba
--- /dev/null
+++ b/genann/LICENSE
@@ -0,0 +1,20 @@
+zlib License
+
+Copyright (C) 2015-2018 Lewis Van Winkle
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgement in the product documentation would be
+   appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
diff --git a/genann/Makefile b/genann/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..427e3be711070d6b6f290bbd30b9fb6942becef7
--- /dev/null
+++ b/genann/Makefile
@@ -0,0 +1,34 @@
+CFLAGS = -Wall -Wshadow -O3 -g -march=native
+LDLIBS = -lm
+
+all: check example1 example2 example3 example4
+
+sigmoid: CFLAGS += -Dgenann_act=genann_act_sigmoid_cached
+sigmoid: all
+
+threshold: CFLAGS += -Dgenann_act=genann_act_threshold
+threshold: all
+
+linear: CFLAGS += -Dgenann_act=genann_act_linear
+linear: all
+
+test: test.o genann.o
+
+check: test
+	./$^
+
+example1: example1.o genann.o
+
+example2: example2.o genann.o
+
+example3: example3.o genann.o
+
+example4: example4.o genann.o
+
+
+clean:
+	$(RM) *.o
+	$(RM) test example1 example2 example3 example4 *.exe
+	$(RM) persist.txt
+
+.PHONY: sigmoid threshold linear clean
diff --git a/genann/README.md b/genann/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..4e04d47af117e185f83eba51805b8234d0efd631
--- /dev/null
+++ b/genann/README.md
@@ -0,0 +1,154 @@
+[![Build Status](https://travis-ci.org/codeplea/genann.svg?branch=master)](https://travis-ci.org/codeplea/genann)
+
+<img alt="Genann logo" src="https://codeplea.com/public/content/genann_logo.png" align="right" />
+
+# Genann
+
+Genann is a minimal, well-tested library for training and using feedforward
+artificial neural networks (ANN) in C. Its primary focus is on being simple,
+fast, reliable, and hackable. It achieves this by providing only the necessary
+functions and little extra.
+
+## Features
+
+- **C99 with no dependencies**.
+- Contained in a single source code and header file.
+- Simple.
+- Fast and thread-safe.
+- Easily extendible.
+- Implements backpropagation training.
+- *Compatible with alternative training methods* (classic optimization, genetic algorithms, etc)
+- Includes examples and test suite.
+- Released under the zlib license - free for nearly any use.
+
+## Building
+
+Genann is self-contained in two files: `genann.c` and `genann.h`. To use Genann, simply add those two files to your project.
+
+## Example Code
+
+Four example programs are included with the source code.
+
+- [`example1.c`](./example1.c) - Trains an ANN on the XOR function using backpropagation.
+- [`example2.c`](./example2.c) - Trains an ANN on the XOR function using random search.
+- [`example3.c`](./example3.c) - Loads and runs an ANN from a file.
+- [`example4.c`](./example4.c) - Trains an ANN on the [IRIS data-set](https://archive.ics.uci.edu/ml/datasets/Iris) using backpropagation.
+
+## Quick Example
+
+We create an ANN taking 2 inputs, having 1 layer of 3 hidden neurons, and
+providing 2 outputs. It has the following structure:
+
+![NN Example Structure](./doc/e1.png)
+
+We then train it on a set of labeled data using backpropagation and ask it to
+predict on a test data point:
+
+```C
+#include "genann.h"
+
+/* Not shown, loading your training and test data. */
+double **training_data_input, **training_data_output, **test_data_input;
+
+/* New network with 2 inputs,
+ * 1 hidden layer of 3 neurons each,
+ * and 2 outputs. */
+genann *ann = genann_init(2, 1, 3, 2);
+
+/* Learn on the training set. */
+for (i = 0; i < 300; ++i) {
+    for (j = 0; j < 100; ++j)
+        genann_train(ann, training_data_input[j], training_data_output[j], 0.1);
+}
+
+/* Run the network and see what it predicts. */
+double const *prediction = genann_run(ann, test_data_input[0]);
+printf("Output for the first test data point is: %f, %f\n", prediction[0], prediction[1]);
+
+genann_free(ann);
+```
+
+This example is to show API usage, it is not showing good machine learning
+techniques. In a real application you would likely want to learn on the test
+data in a random order. You would also want to monitor the learning to prevent
+over-fitting.
+
+
+## Usage
+
+### Creating and Freeing ANNs
+```C
+genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs);
+genann *genann_copy(genann const *ann);
+void genann_free(genann *ann);
+```
+
+Creating a new ANN is done with the `genann_init()` function. Its arguments
+are the number of inputs, the number of hidden layers, the number of neurons in
+each hidden layer, and the number of outputs. It returns a `genann` struct pointer.
+
+Calling `genann_copy()` will create a deep-copy of an existing `genann` struct.
+
+Call `genann_free()` when you're finished with an ANN returned by `genann_init()`.
+
+
+### Training ANNs
+```C
+void genann_train(genann const *ann, double const *inputs,
+        double const *desired_outputs, double learning_rate);
+```
+
+`genann_train()` will preform one update using standard backpropogation. It
+should be called by passing in an array of inputs, an array of expected outputs,
+and a learning rate. See *example1.c* for an example of learning with
+backpropogation.
+
+A primary design goal of Genann was to store all the network weights in one
+contigious block of memory. This makes it easy and efficient to train the
+network weights using direct-search numeric optimization algorthims,
+such as [Hill Climbing](https://en.wikipedia.org/wiki/Hill_climbing),
+[the Genetic Algorithm](https://en.wikipedia.org/wiki/Genetic_algorithm), [Simulated
+Annealing](https://en.wikipedia.org/wiki/Simulated_annealing), etc.
+These methods can be used by searching on the ANN's weights directly.
+Every `genann` struct contains the members `int total_weights;` and
+`double *weight;`.  `*weight` points to an array of `total_weights`
+size which contains all weights used by the ANN. See *example2.c* for
+an example of training using random hill climbing search.
+
+### Saving and Loading ANNs
+
+```C
+genann *genann_read(FILE *in);
+void genann_write(genann const *ann, FILE *out);
+```
+ 
+Genann provides the `genann_read()` and `genann_write()` functions for loading or saving an ANN in a text-based format.
+
+### Evaluating
+
+```C
+double const *genann_run(genann const *ann, double const *inputs);
+```
+
+Call `genann_run()` on a trained ANN to run a feed-forward pass on a given set of inputs. `genann_run()`
+will provide a pointer to the array of predicted outputs (of `ann->outputs` length).
+
+
+## Hints
+
+- All functions start with `genann_`.
+- The code is simple. Dig in and change things.
+
+## Extra Resources
+
+The [comp.ai.neural-nets
+FAQ](http://www.faqs.org/faqs/ai-faq/neural-nets/part1/) is an excellent
+resource for an introduction to artificial neural networks.
+
+If you need an even smaller neural network library, check out the excellent single-hidden-layer library [tinn](https://github.com/glouw/tinn).
+
+If you're looking for a heavier, more opinionated neural network library in C,
+I recommend the [FANN library](http://leenissen.dk/fann/wp/). Another
+good library is Peter van Rossum's [Lightweight Neural
+Network](http://lwneuralnet.sourceforge.net/), which despite its name, is
+heavier and has more features than Genann.
diff --git a/genann/doc/e1.dot b/genann/doc/e1.dot
new file mode 100644
index 0000000000000000000000000000000000000000..9e498c2359ec30482f762850535ae617e64bc435
--- /dev/null
+++ b/genann/doc/e1.dot
@@ -0,0 +1,9 @@
+digraph G {
+    rankdir=LR;
+
+    {i1 i2} -> {h1 h2 h3} -> {o1 o2};
+    i1, i2, h1, h2, h3, o1, o2 [shape=circle; label="";];
+
+    input -> hidden -> output [style=invis;];
+    input, hidden, output [shape=plaintext;];
+}
diff --git a/genann/doc/e1.png b/genann/doc/e1.png
new file mode 100644
index 0000000000000000000000000000000000000000..4a6cb9de7d606843b9d537fd8e3de9a8747fbc26
Binary files /dev/null and b/genann/doc/e1.png differ
diff --git a/genann/example/iris.data b/genann/example/iris.data
new file mode 100644
index 0000000000000000000000000000000000000000..a3490e0e07dc9d99f655a73e4f53580c8ead9b7d
--- /dev/null
+++ b/genann/example/iris.data
@@ -0,0 +1,150 @@
+5.1,3.5,1.4,0.2,Iris-setosa
+4.9,3.0,1.4,0.2,Iris-setosa
+4.7,3.2,1.3,0.2,Iris-setosa
+4.6,3.1,1.5,0.2,Iris-setosa
+5.0,3.6,1.4,0.2,Iris-setosa
+5.4,3.9,1.7,0.4,Iris-setosa
+4.6,3.4,1.4,0.3,Iris-setosa
+5.0,3.4,1.5,0.2,Iris-setosa
+4.4,2.9,1.4,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+5.4,3.7,1.5,0.2,Iris-setosa
+4.8,3.4,1.6,0.2,Iris-setosa
+4.8,3.0,1.4,0.1,Iris-setosa
+4.3,3.0,1.1,0.1,Iris-setosa
+5.8,4.0,1.2,0.2,Iris-setosa
+5.7,4.4,1.5,0.4,Iris-setosa
+5.4,3.9,1.3,0.4,Iris-setosa
+5.1,3.5,1.4,0.3,Iris-setosa
+5.7,3.8,1.7,0.3,Iris-setosa
+5.1,3.8,1.5,0.3,Iris-setosa
+5.4,3.4,1.7,0.2,Iris-setosa
+5.1,3.7,1.5,0.4,Iris-setosa
+4.6,3.6,1.0,0.2,Iris-setosa
+5.1,3.3,1.7,0.5,Iris-setosa
+4.8,3.4,1.9,0.2,Iris-setosa
+5.0,3.0,1.6,0.2,Iris-setosa
+5.0,3.4,1.6,0.4,Iris-setosa
+5.2,3.5,1.5,0.2,Iris-setosa
+5.2,3.4,1.4,0.2,Iris-setosa
+4.7,3.2,1.6,0.2,Iris-setosa
+4.8,3.1,1.6,0.2,Iris-setosa
+5.4,3.4,1.5,0.4,Iris-setosa
+5.2,4.1,1.5,0.1,Iris-setosa
+5.5,4.2,1.4,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+5.0,3.2,1.2,0.2,Iris-setosa
+5.5,3.5,1.3,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+4.4,3.0,1.3,0.2,Iris-setosa
+5.1,3.4,1.5,0.2,Iris-setosa
+5.0,3.5,1.3,0.3,Iris-setosa
+4.5,2.3,1.3,0.3,Iris-setosa
+4.4,3.2,1.3,0.2,Iris-setosa
+5.0,3.5,1.6,0.6,Iris-setosa
+5.1,3.8,1.9,0.4,Iris-setosa
+4.8,3.0,1.4,0.3,Iris-setosa
+5.1,3.8,1.6,0.2,Iris-setosa
+4.6,3.2,1.4,0.2,Iris-setosa
+5.3,3.7,1.5,0.2,Iris-setosa
+5.0,3.3,1.4,0.2,Iris-setosa
+7.0,3.2,4.7,1.4,Iris-versicolor
+6.4,3.2,4.5,1.5,Iris-versicolor
+6.9,3.1,4.9,1.5,Iris-versicolor
+5.5,2.3,4.0,1.3,Iris-versicolor
+6.5,2.8,4.6,1.5,Iris-versicolor
+5.7,2.8,4.5,1.3,Iris-versicolor
+6.3,3.3,4.7,1.6,Iris-versicolor
+4.9,2.4,3.3,1.0,Iris-versicolor
+6.6,2.9,4.6,1.3,Iris-versicolor
+5.2,2.7,3.9,1.4,Iris-versicolor
+5.0,2.0,3.5,1.0,Iris-versicolor
+5.9,3.0,4.2,1.5,Iris-versicolor
+6.0,2.2,4.0,1.0,Iris-versicolor
+6.1,2.9,4.7,1.4,Iris-versicolor
+5.6,2.9,3.6,1.3,Iris-versicolor
+6.7,3.1,4.4,1.4,Iris-versicolor
+5.6,3.0,4.5,1.5,Iris-versicolor
+5.8,2.7,4.1,1.0,Iris-versicolor
+6.2,2.2,4.5,1.5,Iris-versicolor
+5.6,2.5,3.9,1.1,Iris-versicolor
+5.9,3.2,4.8,1.8,Iris-versicolor
+6.1,2.8,4.0,1.3,Iris-versicolor
+6.3,2.5,4.9,1.5,Iris-versicolor
+6.1,2.8,4.7,1.2,Iris-versicolor
+6.4,2.9,4.3,1.3,Iris-versicolor
+6.6,3.0,4.4,1.4,Iris-versicolor
+6.8,2.8,4.8,1.4,Iris-versicolor
+6.7,3.0,5.0,1.7,Iris-versicolor
+6.0,2.9,4.5,1.5,Iris-versicolor
+5.7,2.6,3.5,1.0,Iris-versicolor
+5.5,2.4,3.8,1.1,Iris-versicolor
+5.5,2.4,3.7,1.0,Iris-versicolor
+5.8,2.7,3.9,1.2,Iris-versicolor
+6.0,2.7,5.1,1.6,Iris-versicolor
+5.4,3.0,4.5,1.5,Iris-versicolor
+6.0,3.4,4.5,1.6,Iris-versicolor
+6.7,3.1,4.7,1.5,Iris-versicolor
+6.3,2.3,4.4,1.3,Iris-versicolor
+5.6,3.0,4.1,1.3,Iris-versicolor
+5.5,2.5,4.0,1.3,Iris-versicolor
+5.5,2.6,4.4,1.2,Iris-versicolor
+6.1,3.0,4.6,1.4,Iris-versicolor
+5.8,2.6,4.0,1.2,Iris-versicolor
+5.0,2.3,3.3,1.0,Iris-versicolor
+5.6,2.7,4.2,1.3,Iris-versicolor
+5.7,3.0,4.2,1.2,Iris-versicolor
+5.7,2.9,4.2,1.3,Iris-versicolor
+6.2,2.9,4.3,1.3,Iris-versicolor
+5.1,2.5,3.0,1.1,Iris-versicolor
+5.7,2.8,4.1,1.3,Iris-versicolor
+6.3,3.3,6.0,2.5,Iris-virginica
+5.8,2.7,5.1,1.9,Iris-virginica
+7.1,3.0,5.9,2.1,Iris-virginica
+6.3,2.9,5.6,1.8,Iris-virginica
+6.5,3.0,5.8,2.2,Iris-virginica
+7.6,3.0,6.6,2.1,Iris-virginica
+4.9,2.5,4.5,1.7,Iris-virginica
+7.3,2.9,6.3,1.8,Iris-virginica
+6.7,2.5,5.8,1.8,Iris-virginica
+7.2,3.6,6.1,2.5,Iris-virginica
+6.5,3.2,5.1,2.0,Iris-virginica
+6.4,2.7,5.3,1.9,Iris-virginica
+6.8,3.0,5.5,2.1,Iris-virginica
+5.7,2.5,5.0,2.0,Iris-virginica
+5.8,2.8,5.1,2.4,Iris-virginica
+6.4,3.2,5.3,2.3,Iris-virginica
+6.5,3.0,5.5,1.8,Iris-virginica
+7.7,3.8,6.7,2.2,Iris-virginica
+7.7,2.6,6.9,2.3,Iris-virginica
+6.0,2.2,5.0,1.5,Iris-virginica
+6.9,3.2,5.7,2.3,Iris-virginica
+5.6,2.8,4.9,2.0,Iris-virginica
+7.7,2.8,6.7,2.0,Iris-virginica
+6.3,2.7,4.9,1.8,Iris-virginica
+6.7,3.3,5.7,2.1,Iris-virginica
+7.2,3.2,6.0,1.8,Iris-virginica
+6.2,2.8,4.8,1.8,Iris-virginica
+6.1,3.0,4.9,1.8,Iris-virginica
+6.4,2.8,5.6,2.1,Iris-virginica
+7.2,3.0,5.8,1.6,Iris-virginica
+7.4,2.8,6.1,1.9,Iris-virginica
+7.9,3.8,6.4,2.0,Iris-virginica
+6.4,2.8,5.6,2.2,Iris-virginica
+6.3,2.8,5.1,1.5,Iris-virginica
+6.1,2.6,5.6,1.4,Iris-virginica
+7.7,3.0,6.1,2.3,Iris-virginica
+6.3,3.4,5.6,2.4,Iris-virginica
+6.4,3.1,5.5,1.8,Iris-virginica
+6.0,3.0,4.8,1.8,Iris-virginica
+6.9,3.1,5.4,2.1,Iris-virginica
+6.7,3.1,5.6,2.4,Iris-virginica
+6.9,3.1,5.1,2.3,Iris-virginica
+5.8,2.7,5.1,1.9,Iris-virginica
+6.8,3.2,5.9,2.3,Iris-virginica
+6.7,3.3,5.7,2.5,Iris-virginica
+6.7,3.0,5.2,2.3,Iris-virginica
+6.3,2.5,5.0,1.9,Iris-virginica
+6.5,3.0,5.2,2.0,Iris-virginica
+6.2,3.4,5.4,2.3,Iris-virginica
+5.9,3.0,5.1,1.8,Iris-virginica
diff --git a/genann/example/iris.names b/genann/example/iris.names
new file mode 100644
index 0000000000000000000000000000000000000000..062b486d07bbeaecee0406160a3ced8e73d2f9d7
--- /dev/null
+++ b/genann/example/iris.names
@@ -0,0 +1,69 @@
+1. Title: Iris Plants Database
+	Updated Sept 21 by C.Blake - Added discrepency information
+
+2. Sources:
+     (a) Creator: R.A. Fisher
+     (b) Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
+     (c) Date: July, 1988
+
+3. Past Usage:
+   - Publications: too many to mention!!!  Here are a few.
+   1. Fisher,R.A. "The use of multiple measurements in taxonomic problems"
+      Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions
+      to Mathematical Statistics" (John Wiley, NY, 1950).
+   2. Duda,R.O., & Hart,P.E. (1973) Pattern Classification and Scene Analysis.
+      (Q327.D83) John Wiley & Sons.  ISBN 0-471-22361-1.  See page 218.
+   3. Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System
+      Structure and Classification Rule for Recognition in Partially Exposed
+      Environments".  IEEE Transactions on Pattern Analysis and Machine
+      Intelligence, Vol. PAMI-2, No. 1, 67-71.
+      -- Results:
+         -- very low misclassification rates (0% for the setosa class)
+   4. Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule".  IEEE 
+      Transactions on Information Theory, May 1972, 431-433.
+      -- Results:
+         -- very low misclassification rates again
+   5. See also: 1988 MLC Proceedings, 54-64.  Cheeseman et al's AUTOCLASS II
+      conceptual clustering system finds 3 classes in the data.
+
+4. Relevant Information:
+   --- This is perhaps the best known database to be found in the pattern
+       recognition literature.  Fisher's paper is a classic in the field
+       and is referenced frequently to this day.  (See Duda & Hart, for
+       example.)  The data set contains 3 classes of 50 instances each,
+       where each class refers to a type of iris plant.  One class is
+       linearly separable from the other 2; the latter are NOT linearly
+       separable from each other.
+   --- Predicted attribute: class of iris plant.
+   --- This is an exceedingly simple domain.
+   --- This data differs from the data presented in Fishers article
+	(identified by Steve Chadwick,  spchadwick@espeedaz.net )
+	The 35th sample should be: 4.9,3.1,1.5,0.2,"Iris-setosa"
+	where the error is in the fourth feature.
+	The 38th sample: 4.9,3.6,1.4,0.1,"Iris-setosa"
+	where the errors are in the second and third features.  
+
+5. Number of Instances: 150 (50 in each of three classes)
+
+6. Number of Attributes: 4 numeric, predictive attributes and the class
+
+7. Attribute Information:
+   1. sepal length in cm
+   2. sepal width in cm
+   3. petal length in cm
+   4. petal width in cm
+   5. class: 
+      -- Iris Setosa
+      -- Iris Versicolour
+      -- Iris Virginica
+
+8. Missing Attribute Values: None
+
+Summary Statistics:
+	         Min  Max   Mean    SD   Class Correlation
+   sepal length: 4.3  7.9   5.84  0.83    0.7826   
+    sepal width: 2.0  4.4   3.05  0.43   -0.4194
+   petal length: 1.0  6.9   3.76  1.76    0.9490  (high!)
+    petal width: 0.1  2.5   1.20  0.76    0.9565  (high!)
+
+9. Class Distribution: 33.3% for each of 3 classes.
diff --git a/genann/example/xor.ann b/genann/example/xor.ann
new file mode 100644
index 0000000000000000000000000000000000000000..c11a96817b02164da0b52c0d1f45280849ec0440
--- /dev/null
+++ b/genann/example/xor.ann
@@ -0,0 +1 @@
+2 1 2 1 -1.777 -5.734 -6.029 -4.460 -3.261 -3.172 2.444 -6.581 5.826
diff --git a/genann/example1.c b/genann/example1.c
new file mode 100644
index 0000000000000000000000000000000000000000..b45393c8308fa0ab26cd8e35e2c2e0e2289bf59b
--- /dev/null
+++ b/genann/example1.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "genann.h"
+
+int main(int argc, char *argv[])
+{
+    printf("GENANN example 1.\n");
+    printf("Train a small ANN to the XOR function using backpropagation.\n");
+
+    /* This will make the neural network initialize differently each run. */
+    /* If you don't get a good result, try again for a different result. */
+    srand(time(0));
+
+    /* Input and expected out data for the XOR function. */
+    const double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+    const double output[4] = {0, 1, 1, 0};
+    int i;
+
+    /* New network with 2 inputs,
+     * 1 hidden layer of 2 neurons,
+     * and 1 output. */
+    genann *ann = genann_init(2, 1, 2, 1);
+
+    /* Train on the four labeled data points many times. */
+    for (i = 0; i < 500; ++i) {
+        genann_train(ann, input[0], output + 0, 3);
+        genann_train(ann, input[1], output + 1, 3);
+        genann_train(ann, input[2], output + 2, 3);
+        genann_train(ann, input[3], output + 3, 3);
+    }
+
+    /* Run the network and see what it predicts. */
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[0][0], input[0][1], *genann_run(ann, input[0]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[1][0], input[1][1], *genann_run(ann, input[1]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[2][0], input[2][1], *genann_run(ann, input[2]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[3][0], input[3][1], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+    return 0;
+}
diff --git a/genann/example2.c b/genann/example2.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe635697eaec6150b0c50b6bfe82c304e8970d89
--- /dev/null
+++ b/genann/example2.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include "genann.h"
+
+int main(int argc, char *argv[])
+{
+    printf("GENANN example 2.\n");
+    printf("Train a small ANN to the XOR function using random search.\n");
+
+    srand(time(0));
+
+    /* Input and expected out data for the XOR function. */
+    const double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+    const double output[4] = {0, 1, 1, 0};
+    int i;
+
+    /* New network with 2 inputs,
+     * 1 hidden layer of 2 neurons,
+     * and 1 output. */
+    genann *ann = genann_init(2, 1, 2, 1);
+
+    double err;
+    double last_err = 1000;
+    int count = 0;
+
+    do {
+        ++count;
+        if (count % 1000 == 0) {
+            /* We're stuck, start over. */
+            genann_randomize(ann);
+            last_err = 1000;
+        }
+
+        genann *save = genann_copy(ann);
+
+        /* Take a random guess at the ANN weights. */
+        for (i = 0; i < ann->total_weights; ++i) {
+            ann->weight[i] += ((double)rand())/RAND_MAX-0.5;
+        }
+
+        /* See how we did. */
+        err = 0;
+        err += pow(*genann_run(ann, input[0]) - output[0], 2.0);
+        err += pow(*genann_run(ann, input[1]) - output[1], 2.0);
+        err += pow(*genann_run(ann, input[2]) - output[2], 2.0);
+        err += pow(*genann_run(ann, input[3]) - output[3], 2.0);
+
+        /* Keep these weights if they're an improvement. */
+        if (err < last_err) {
+            genann_free(save);
+            last_err = err;
+        } else {
+            genann_free(ann);
+            ann = save;
+        }
+
+    } while (err > 0.01);
+
+    printf("Finished in %d loops.\n", count);
+
+    /* Run the network and see what it predicts. */
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[0][0], input[0][1], *genann_run(ann, input[0]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[1][0], input[1][1], *genann_run(ann, input[1]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[2][0], input[2][1], *genann_run(ann, input[2]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[3][0], input[3][1], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+    return 0;
+}
diff --git a/genann/example3.c b/genann/example3.c
new file mode 100644
index 0000000000000000000000000000000000000000..2ace13b4577ed722438fc12e1cfb55101ce78837
--- /dev/null
+++ b/genann/example3.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "genann.h"
+
+const char *save_name = "example/xor.ann";
+
+int main(int argc, char *argv[])
+{
+    printf("GENANN example 3.\n");
+    printf("Load a saved ANN to solve the XOR function.\n");
+
+
+    FILE *saved = fopen(save_name, "r");
+    if (!saved) {
+        printf("Couldn't open file: %s\n", save_name);
+        exit(1);
+    }
+
+    genann *ann = genann_read(saved);
+    fclose(saved);
+
+    if (!ann) {
+        printf("Error loading ANN from file: %s.", save_name);
+        exit(1);
+    }
+
+
+    /* Input data for the XOR function. */
+    const double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+
+    /* Run the network and see what it predicts. */
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[0][0], input[0][1], *genann_run(ann, input[0]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[1][0], input[1][1], *genann_run(ann, input[1]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[2][0], input[2][1], *genann_run(ann, input[2]));
+    printf("Output for [%1.f, %1.f] is %1.f.\n", input[3][0], input[3][1], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+    return 0;
+}
diff --git a/genann/example4.c b/genann/example4.c
new file mode 100644
index 0000000000000000000000000000000000000000..14de78363db84d4e8473c2f5b3a3bfaf6bed10e5
--- /dev/null
+++ b/genann/example4.c
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <math.h>
+#include "genann.h"
+
+/* This example is to illustrate how to use GENANN.
+ * It is NOT an example of good machine learning techniques.
+ */
+
+const char *iris_data = "example/iris.data";
+
+double *input, *class;
+int samples;
+const char *class_names[] = {"Iris-setosa", "Iris-versicolor", "Iris-virginica"};
+
+void load_data() {
+    /* Load the iris data-set. */
+    FILE *in = fopen("example/iris.data", "r");
+    if (!in) {
+        printf("Could not open file: %s\n", iris_data);
+        exit(1);
+    }
+
+    /* Loop through the data to get a count. */
+    char line[1024];
+    while (!feof(in) && fgets(line, 1024, in)) {
+        ++samples;
+    }
+    fseek(in, 0, SEEK_SET);
+
+    printf("Loading %d data points from %s\n", samples, iris_data);
+
+    /* Allocate memory for input and output data. */
+    input = malloc(sizeof(double) * samples * 4);
+    class = malloc(sizeof(double) * samples * 3);
+
+    /* Read the file into our arrays. */
+    int i, j;
+    for (i = 0; i < samples; ++i) {
+        double *p = input + i * 4;
+        double *c = class + i * 3;
+        c[0] = c[1] = c[2] = 0.0;
+
+        if (fgets(line, 1024, in) == NULL) {
+            perror("fgets");
+            exit(1);
+        }
+
+        char *split = strtok(line, ",");
+        for (j = 0; j < 4; ++j) {
+            p[j] = atof(split);
+            split = strtok(0, ",");
+        }
+
+        split[strlen(split)-1] = 0;
+        if (strcmp(split, class_names[0]) == 0) {c[0] = 1.0;}
+        else if (strcmp(split, class_names[1]) == 0) {c[1] = 1.0;}
+        else if (strcmp(split, class_names[2]) == 0) {c[2] = 1.0;}
+        else {
+            printf("Unknown class %s.\n", split);
+            exit(1);
+        }
+
+        /* printf("Data point %d is %f %f %f %f  ->   %f %f %f\n", i, p[0], p[1], p[2], p[3], c[0], c[1], c[2]); */
+    }
+
+    fclose(in);
+}
+
+
+int main(int argc, char *argv[])
+{
+    printf("GENANN example 4.\n");
+    printf("Train an ANN on the IRIS dataset using backpropagation.\n");
+
+    srand(time(0));
+
+    /* Load the data from file. */
+    load_data();
+
+    /* 4 inputs.
+     * 1 hidden layer(s) of 4 neurons.
+     * 3 outputs (1 per class)
+     */
+    genann *ann = genann_init(4, 1, 4, 3);
+
+    int i, j;
+    int loops = 5000;
+
+    /* Train the network with backpropagation. */
+    printf("Training for %d loops over data.\n", loops);
+    for (i = 0; i < loops; ++i) {
+        for (j = 0; j < samples; ++j) {
+            genann_train(ann, input + j*4, class + j*3, .01);
+        }
+        /* printf("%1.2f ", xor_score(ann)); */
+    }
+
+    int correct = 0;
+    for (j = 0; j < samples; ++j) {
+        const double *guess = genann_run(ann, input + j*4);
+        if (class[j*3+0] == 1.0) {if (guess[0] > guess[1] && guess[0] > guess[2]) ++correct;}
+        else if (class[j*3+1] == 1.0) {if (guess[1] > guess[0] && guess[1] > guess[2]) ++correct;}
+        else if (class[j*3+2] == 1.0) {if (guess[2] > guess[0] && guess[2] > guess[1]) ++correct;}
+        else {printf("Logic error.\n"); exit(1);}
+    }
+
+    printf("%d/%d correct (%0.1f%%).\n", correct, samples, (double)correct / samples * 100.0);
+
+
+
+    genann_free(ann);
+    free(input);
+    free(class);
+
+    return 0;
+}
diff --git a/genann/genann.c b/genann/genann.c
new file mode 100644
index 0000000000000000000000000000000000000000..b05fa4fc737b6125ad5944ba1ea709d11bd7c6ab
--- /dev/null
+++ b/genann/genann.c
@@ -0,0 +1,405 @@
+/*
+ * GENANN - Minimal C Artificial Neural Network
+ *
+ * Copyright (c) 2015-2018 Lewis Van Winkle
+ *
+ * http://CodePlea.com
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgement in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ */
+
+#include "genann.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef genann_act
+#define genann_act_hidden genann_act_hidden_indirect
+#define genann_act_output genann_act_output_indirect
+#else
+#define genann_act_hidden genann_act
+#define genann_act_output genann_act
+#endif
+
+#define LOOKUP_SIZE 4096
+
+double genann_act_hidden_indirect(const struct genann *ann, double a) {
+    return ann->activation_hidden(ann, a);
+}
+
+double genann_act_output_indirect(const struct genann *ann, double a) {
+    return ann->activation_output(ann, a);
+}
+
+const double sigmoid_dom_min = -15.0;
+const double sigmoid_dom_max = 15.0;
+double interval;
+double lookup[LOOKUP_SIZE];
+
+#ifdef __GNUC__
+#define likely(x)       __builtin_expect(!!(x), 1)
+#define unlikely(x)     __builtin_expect(!!(x), 0)
+#define unused          __attribute__((unused))
+#else
+#define likely(x)       x
+#define unlikely(x)     x
+#define unused
+#pragma warning(disable : 4996) /* For fscanf */
+#endif
+
+
+double genann_act_sigmoid(const genann *ann unused, double a) {
+    if (a < -45.0) return 0;
+    if (a > 45.0) return 1;
+    return 1.0 / (1 + exp(-a));
+}
+
+void genann_init_sigmoid_lookup(const genann *ann) {
+        const double f = (sigmoid_dom_max - sigmoid_dom_min) / LOOKUP_SIZE;
+        int i;
+
+        interval = LOOKUP_SIZE / (sigmoid_dom_max - sigmoid_dom_min);
+        for (i = 0; i < LOOKUP_SIZE; ++i) {
+            lookup[i] = genann_act_sigmoid(ann, sigmoid_dom_min + f * i);
+        }
+}
+
+double genann_act_sigmoid_cached(const genann *ann unused, double a) {
+    assert(!isnan(a));
+
+    if (a < sigmoid_dom_min) return lookup[0];
+    if (a >= sigmoid_dom_max) return lookup[LOOKUP_SIZE - 1];
+
+    size_t j = (size_t)((a-sigmoid_dom_min)*interval+0.5);
+
+    /* Because floating point... */
+    if (unlikely(j >= LOOKUP_SIZE)) return lookup[LOOKUP_SIZE - 1];
+
+    return lookup[j];
+}
+
+double genann_act_linear(const struct genann *ann unused, double a) {
+    return a;
+}
+
+double genann_act_threshold(const struct genann *ann unused, double a) {
+    return a > 0;
+}
+
+genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs) {
+    if (hidden_layers < 0) return 0;
+    if (inputs < 1) return 0;
+    if (outputs < 1) return 0;
+    if (hidden_layers > 0 && hidden < 1) return 0;
+
+
+    const int hidden_weights = hidden_layers ? (inputs+1) * hidden + (hidden_layers-1) * (hidden+1) * hidden : 0;
+    const int output_weights = (hidden_layers ? (hidden+1) : (inputs+1)) * outputs;
+    const int total_weights = (hidden_weights + output_weights);
+
+    const int total_neurons = (inputs + hidden * hidden_layers + outputs);
+
+    /* Allocate extra size for weights, outputs, and deltas. */
+    const int size = sizeof(genann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
+    genann *ret = malloc(size);
+    if (!ret) return 0;
+
+    ret->inputs = inputs;
+    ret->hidden_layers = hidden_layers;
+    ret->hidden = hidden;
+    ret->outputs = outputs;
+
+    ret->total_weights = total_weights;
+    ret->total_neurons = total_neurons;
+
+    /* Set pointers. */
+    ret->weight = (double*)((char*)ret + sizeof(genann));
+    ret->output = ret->weight + ret->total_weights;
+    ret->delta = ret->output + ret->total_neurons;
+
+    genann_randomize(ret);
+
+    ret->activation_hidden = genann_act_sigmoid_cached;
+    ret->activation_output = genann_act_sigmoid_cached;
+
+    genann_init_sigmoid_lookup(ret);
+
+    return ret;
+}
+
+
+genann *genann_read(FILE *in) {
+    int inputs, hidden_layers, hidden, outputs;
+    int rc;
+
+    errno = 0;
+    rc = fscanf(in, "%d %d %d %d", &inputs, &hidden_layers, &hidden, &outputs);
+    if (rc < 4 || errno != 0) {
+        perror("fscanf");
+        return NULL;
+    }
+
+    genann *ann = genann_init(inputs, hidden_layers, hidden, outputs);
+
+    int i;
+    for (i = 0; i < ann->total_weights; ++i) {
+        errno = 0;
+        rc = fscanf(in, " %le", ann->weight + i);
+        if (rc < 1 || errno != 0) {
+            perror("fscanf");
+            genann_free(ann);
+
+            return NULL;
+        }
+    }
+
+    return ann;
+}
+
+
+genann *genann_copy(genann const *ann) {
+    const int size = sizeof(genann) + sizeof(double) * (ann->total_weights + ann->total_neurons + (ann->total_neurons - ann->inputs));
+    genann *ret = malloc(size);
+    if (!ret) return 0;
+
+    memcpy(ret, ann, size);
+
+    /* Set pointers. */
+    ret->weight = (double*)((char*)ret + sizeof(genann));
+    ret->output = ret->weight + ret->total_weights;
+    ret->delta = ret->output + ret->total_neurons;
+
+    return ret;
+}
+
+
+void genann_randomize(genann *ann) {
+    int i;
+    for (i = 0; i < ann->total_weights; ++i) {
+        double r = GENANN_RANDOM();
+        /* Sets weights from -0.5 to 0.5. */
+        ann->weight[i] = r - 0.5;
+    }
+}
+
+
+void genann_free(genann *ann) {
+    /* The weight, output, and delta pointers go to the same buffer. */
+    free(ann);
+}
+
+
+double const *genann_run(genann const *ann, double const *inputs) {
+    double const *w = ann->weight;
+    double *o = ann->output + ann->inputs;
+    double const *i = ann->output;
+
+    /* Copy the inputs to the scratch area, where we also store each neuron's
+     * output, for consistency. This way the first layer isn't a special case. */
+    memcpy(ann->output, inputs, sizeof(double) * ann->inputs);
+
+    int h, j, k;
+
+    if (!ann->hidden_layers) {
+        double *ret = o;
+        for (j = 0; j < ann->outputs; ++j) {
+            double sum = *w++ * -1.0;
+            for (k = 0; k < ann->inputs; ++k) {
+                sum += *w++ * i[k];
+            }
+            *o++ = genann_act_output(ann, sum);
+        }
+
+        return ret;
+    }
+
+    /* Figure input layer */
+    for (j = 0; j < ann->hidden; ++j) {
+        double sum = *w++ * -1.0;
+        for (k = 0; k < ann->inputs; ++k) {
+            sum += *w++ * i[k];
+        }
+        *o++ = genann_act_hidden(ann, sum);
+    }
+
+    i += ann->inputs;
+
+    /* Figure hidden layers, if any. */
+    for (h = 1; h < ann->hidden_layers; ++h) {
+        for (j = 0; j < ann->hidden; ++j) {
+            double sum = *w++ * -1.0;
+            for (k = 0; k < ann->hidden; ++k) {
+                sum += *w++ * i[k];
+            }
+            *o++ = genann_act_hidden(ann, sum);
+        }
+
+        i += ann->hidden;
+    }
+
+    double const *ret = o;
+
+    /* Figure output layer. */
+    for (j = 0; j < ann->outputs; ++j) {
+        double sum = *w++ * -1.0;
+        for (k = 0; k < ann->hidden; ++k) {
+            sum += *w++ * i[k];
+        }
+        *o++ = genann_act_output(ann, sum);
+    }
+
+    /* Sanity check that we used all weights and wrote all outputs. */
+    assert(w - ann->weight == ann->total_weights);
+    assert(o - ann->output == ann->total_neurons);
+
+    return ret;
+}
+
+
+void genann_train(genann const *ann, double const *inputs, double const *desired_outputs, double learning_rate) {
+    /* To begin with, we must run the network forward. */
+    genann_run(ann, inputs);
+
+    int h, j, k;
+
+    /* First set the output layer deltas. */
+    {
+        double const *o = ann->output + ann->inputs + ann->hidden * ann->hidden_layers; /* First output. */
+        double *d = ann->delta + ann->hidden * ann->hidden_layers; /* First delta. */
+        double const *t = desired_outputs; /* First desired output. */
+
+
+        /* Set output layer deltas. */
+        if (genann_act_output == genann_act_linear ||
+                ann->activation_output == genann_act_linear) {
+            for (j = 0; j < ann->outputs; ++j) {
+                *d++ = *t++ - *o++;
+            }
+        } else {
+            for (j = 0; j < ann->outputs; ++j) {
+                *d++ = (*t - *o) * *o * (1.0 - *o);
+                ++o; ++t;
+            }
+        }
+    }
+
+
+    /* Set hidden layer deltas, start on last layer and work backwards. */
+    /* Note that loop is skipped in the case of hidden_layers == 0. */
+    for (h = ann->hidden_layers - 1; h >= 0; --h) {
+
+        /* Find first output and delta in this layer. */
+        double const *o = ann->output + ann->inputs + (h * ann->hidden);
+        double *d = ann->delta + (h * ann->hidden);
+
+        /* Find first delta in following layer (which may be hidden or output). */
+        double const * const dd = ann->delta + ((h+1) * ann->hidden);
+
+        /* Find first weight in following layer (which may be hidden or output). */
+        double const * const ww = ann->weight + ((ann->inputs+1) * ann->hidden) + ((ann->hidden+1) * ann->hidden * (h));
+
+        for (j = 0; j < ann->hidden; ++j) {
+
+            double delta = 0;
+
+            for (k = 0; k < (h == ann->hidden_layers-1 ? ann->outputs : ann->hidden); ++k) {
+                const double forward_delta = dd[k];
+                const int windex = k * (ann->hidden + 1) + (j + 1);
+                const double forward_weight = ww[windex];
+                delta += forward_delta * forward_weight;
+            }
+
+            *d = *o * (1.0-*o) * delta;
+            ++d; ++o;
+        }
+    }
+
+
+    /* Train the outputs. */
+    {
+        /* Find first output delta. */
+        double const *d = ann->delta + ann->hidden * ann->hidden_layers; /* First output delta. */
+
+        /* Find first weight to first output delta. */
+        double *w = ann->weight + (ann->hidden_layers
+                ? ((ann->inputs+1) * ann->hidden + (ann->hidden+1) * ann->hidden * (ann->hidden_layers-1))
+                : (0));
+
+        /* Find first output in previous layer. */
+        double const * const i = ann->output + (ann->hidden_layers
+                ? (ann->inputs + (ann->hidden) * (ann->hidden_layers-1))
+                : 0);
+
+        /* Set output layer weights. */
+        for (j = 0; j < ann->outputs; ++j) {
+            *w++ += *d * learning_rate * -1.0;
+            for (k = 1; k < (ann->hidden_layers ? ann->hidden : ann->inputs) + 1; ++k) {
+                *w++ += *d * learning_rate * i[k-1];
+            }
+
+            ++d;
+        }
+
+        assert(w - ann->weight == ann->total_weights);
+    }
+
+
+    /* Train the hidden layers. */
+    for (h = ann->hidden_layers - 1; h >= 0; --h) {
+
+        /* Find first delta in this layer. */
+        double const *d = ann->delta + (h * ann->hidden);
+
+        /* Find first input to this layer. */
+        double const *i = ann->output + (h
+                ? (ann->inputs + ann->hidden * (h-1))
+                : 0);
+
+        /* Find first weight to this layer. */
+        double *w = ann->weight + (h
+                ? ((ann->inputs+1) * ann->hidden + (ann->hidden+1) * (ann->hidden) * (h-1))
+                : 0);
+
+
+        for (j = 0; j < ann->hidden; ++j) {
+            *w++ += *d * learning_rate * -1.0;
+            for (k = 1; k < (h == 0 ? ann->inputs : ann->hidden) + 1; ++k) {
+                *w++ += *d * learning_rate * i[k-1];
+            }
+            ++d;
+        }
+
+    }
+
+}
+
+
+void genann_write(genann const *ann, FILE *out) {
+    fprintf(out, "%d %d %d %d", ann->inputs, ann->hidden_layers, ann->hidden, ann->outputs);
+
+    int i;
+    for (i = 0; i < ann->total_weights; ++i) {
+        fprintf(out, " %.20e", ann->weight[i]);
+    }
+}
+
+
diff --git a/genann/genann.h b/genann/genann.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4b7383de7880fdf01cc29ba7e0b539403ae1895
--- /dev/null
+++ b/genann/genann.h
@@ -0,0 +1,108 @@
+/*
+ * GENANN - Minimal C Artificial Neural Network
+ *
+ * Copyright (c) 2015-2018 Lewis Van Winkle
+ *
+ * http://CodePlea.com
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgement in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ */
+
+
+#ifndef GENANN_H
+#define GENANN_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GENANN_RANDOM
+/* We use the following for uniform random numbers between 0 and 1.
+ * If you have a better function, redefine this macro. */
+#define GENANN_RANDOM() (((double)rand())/RAND_MAX)
+#endif
+
+struct genann;
+
+typedef double (*genann_actfun)(const struct genann *ann, double a);
+
+typedef struct genann {
+    /* How many inputs, outputs, and hidden neurons. */
+    int inputs, hidden_layers, hidden, outputs;
+
+    /* Which activation function to use for hidden neurons. Default: gennann_act_sigmoid_cached*/
+    genann_actfun activation_hidden;
+
+    /* Which activation function to use for output. Default: gennann_act_sigmoid_cached*/
+    genann_actfun activation_output;
+
+    /* Total number of weights, and size of weights buffer. */
+    int total_weights;
+
+    /* Total number of neurons + inputs and size of output buffer. */
+    int total_neurons;
+
+    /* All weights (total_weights long). */
+    double *weight;
+
+    /* Stores input array and output of each neuron (total_neurons long). */
+    double *output;
+
+    /* Stores delta of each hidden and output neuron (total_neurons - inputs long). */
+    double *delta;
+
+} genann;
+
+/* Creates and returns a new ann. */
+genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs);
+
+/* Creates ANN from file saved with genann_write. */
+genann *genann_read(FILE *in);
+
+/* Sets weights randomly. Called by init. */
+void genann_randomize(genann *ann);
+
+/* Returns a new copy of ann. */
+genann *genann_copy(genann const *ann);
+
+/* Frees the memory used by an ann. */
+void genann_free(genann *ann);
+
+/* Runs the feedforward algorithm to calculate the ann's output. */
+double const *genann_run(genann const *ann, double const *inputs);
+
+/* Does a single backprop update. */
+void genann_train(genann const *ann, double const *inputs, double const *desired_outputs, double learning_rate);
+
+/* Saves the ann. */
+void genann_write(genann const *ann, FILE *out);
+
+void genann_init_sigmoid_lookup(const genann *ann);
+double genann_act_sigmoid(const genann *ann, double a);
+double genann_act_sigmoid_cached(const genann *ann, double a);
+double genann_act_threshold(const genann *ann, double a);
+double genann_act_linear(const genann *ann, double a);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*GENANN_H*/
diff --git a/genann/minctest.h b/genann/minctest.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb3ad41817cfbc2456b17e889a0526a911114f96
--- /dev/null
+++ b/genann/minctest.h
@@ -0,0 +1,127 @@
+/*
+ *
+ * MINCTEST - Minimal C Test Library - 0.1
+ *
+ * Copyright (c) 2014, 2015, 2016 Lewis Van Winkle
+ *
+ * http://CodePlea.com
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgement in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ */
+
+
+
+/*
+ * MINCTEST - Minimal testing library for C
+ *
+ *
+ * Example:
+ *
+ *      void test1() {
+ *           lok('a' == 'a');
+ *      }
+ *
+ *      void test2() {
+ *           lequal(5, 6);
+ *           lfequal(5.5, 5.6);
+ *      }
+ *
+ *      int main() {
+ *           lrun("test1", test1);
+ *           lrun("test2", test2);
+ *           lresults();
+ *           return lfails != 0;
+ *      }
+ *
+ *
+ *
+ * Hints:
+ *      All functions/variables start with the letter 'l'.
+ *
+ */
+
+
+#ifndef __MINCTEST_H__
+#define __MINCTEST_H__
+
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+
+
+/* How far apart can floats be before we consider them unequal. */
+#define LTEST_FLOAT_TOLERANCE 0.001
+
+
+/* Track the number of passes, fails. */
+/* NB this is made for all tests to be in one file. */
+static int ltests = 0;
+static int lfails = 0;
+
+
+/* Display the test results. */
+#define lresults() do {\
+    if (lfails == 0) {\
+        printf("ALL TESTS PASSED (%d/%d)\n", ltests, ltests);\
+    } else {\
+        printf("SOME TESTS FAILED (%d/%d)\n", ltests-lfails, ltests);\
+    }\
+} while (0)
+
+
+/* Run a test. Name can be any string to print out, test is the function name to call. */
+#define lrun(name, test) do {\
+    const int ts = ltests;\
+    const int fs = lfails;\
+    const clock_t start = clock();\
+    printf("\t%-14s", name);\
+    test();\
+    printf("pass:%2d   fail:%2d   %4dms\n",\
+            (ltests-ts)-(lfails-fs), lfails-fs,\
+            (int)((clock() - start) * 1000 / CLOCKS_PER_SEC));\
+} while (0)
+
+
+/* Assert a true statement. */
+#define lok(test) do {\
+    ++ltests;\
+    if (!(test)) {\
+        ++lfails;\
+        printf("%s:%d error \n", __FILE__, __LINE__);\
+    }} while (0)
+
+
+/* Assert two integers are equal. */
+#define lequal(a, b) do {\
+    ++ltests;\
+    if ((a) != (b)) {\
+        ++lfails;\
+        printf("%s:%d (%d != %d)\n", __FILE__, __LINE__, (a), (b));\
+    }} while (0)
+
+
+/* Assert two floats are equal (Within LTEST_FLOAT_TOLERANCE). */
+#define lfequal(a, b) do {\
+    ++ltests;\
+    if (fabs((double)(a)-(double)(b)) > LTEST_FLOAT_TOLERANCE) {\
+        ++lfails;\
+        printf("%s:%d (%f != %f)\n", __FILE__, __LINE__, (double)(a), (double)(b));\
+    }} while (0)
+
+
+#endif /*__MINCTEST_H__*/
diff --git a/genann/outputs b/genann/outputs
new file mode 100644
index 0000000000000000000000000000000000000000..b00d5f10a05c2db489c38baddcf6f9751e8548f8
--- /dev/null
+++ b/genann/outputs
@@ -0,0 +1,14 @@
+test.c:208:    lequal(first->inputs, second->inputs);
+test.c:209:    lequal(first->hidden_layers, second->hidden_layers);
+test.c:210:    lequal(first->hidden, second->hidden);
+test.c:211:    lequal(first->outputs, second->outputs);
+test.c:212:    lequal(first->total_weights, second->total_weights);
+test.c:215:    for (i = 0; i < first->total_weights; ++i) {
+test.c:216:        lok(first->weight[i] == second->weight[i]);
+test.c:229:    lequal(first->inputs, second->inputs);
+test.c:230:    lequal(first->hidden_layers, second->hidden_layers);
+test.c:231:    lequal(first->hidden, second->hidden);
+test.c:232:    lequal(first->outputs, second->outputs);
+test.c:233:    lequal(first->total_weights, second->total_weights);
+test.c:236:    for (i = 0; i < first->total_weights; ++i) {
+test.c:237:        lfequal(first->weight[i], second->weight[i]);
diff --git a/genann/test.c b/genann/test.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7f895e07e21abf734d0063ee0656d89dfe80dce
--- /dev/null
+++ b/genann/test.c
@@ -0,0 +1,276 @@
+/*
+ * GENANN - Minimal C Artificial Neural Network
+ *
+ * Copyright (c) 2015-2018 Lewis Van Winkle
+ *
+ * http://CodePlea.com
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgement in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ */
+
+#include "genann.h"
+#include "minctest.h"
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+
+
+void basic() {
+    genann *ann = genann_init(1, 0, 0, 1);
+
+    lequal(ann->total_weights, 2);
+    double a;
+
+
+    a = 0;
+    ann->weight[0] = 0;
+    ann->weight[1] = 0;
+    lfequal(0.5, *genann_run(ann, &a));
+
+    a = 1;
+    lfequal(0.5, *genann_run(ann, &a));
+
+    a = 11;
+    lfequal(0.5, *genann_run(ann, &a));
+
+    a = 1;
+    ann->weight[0] = 1;
+    ann->weight[1] = 1;
+    lfequal(0.5, *genann_run(ann, &a));
+
+    a = 10;
+    ann->weight[0] = 1;
+    ann->weight[1] = 1;
+    lfequal(1.0, *genann_run(ann, &a));
+
+    a = -10;
+    lfequal(0.0, *genann_run(ann, &a));
+
+    genann_free(ann);
+}
+
+
+void xor() {
+    genann *ann = genann_init(2, 1, 2, 1);
+    ann->activation_hidden = genann_act_threshold;
+    ann->activation_output = genann_act_threshold;
+
+    lequal(ann->total_weights, 9);
+
+    /* First hidden. */
+    ann->weight[0] = .5;
+    ann->weight[1] = 1;
+    ann->weight[2] = 1;
+
+    /* Second hidden. */
+    ann->weight[3] = 1;
+    ann->weight[4] = 1;
+    ann->weight[5] = 1;
+
+    /* Output. */
+    ann->weight[6] = .5;
+    ann->weight[7] = 1;
+    ann->weight[8] = -1;
+
+
+    double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+    double output[4] = {0, 1, 1, 0};
+
+    lfequal(output[0], *genann_run(ann, input[0]));
+    lfequal(output[1], *genann_run(ann, input[1]));
+    lfequal(output[2], *genann_run(ann, input[2]));
+    lfequal(output[3], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+}
+
+
+void backprop() {
+    genann *ann = genann_init(1, 0, 0, 1);
+
+    double input, output;
+    input = .5;
+    output = 1;
+
+    double first_try = *genann_run(ann, &input);
+    genann_train(ann, &input, &output, .5);
+    double second_try = *genann_run(ann, &input);
+    lok(fabs(first_try - output) > fabs(second_try - output));
+
+    genann_free(ann);
+}
+
+
+void train_and() {
+    double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+    double output[4] = {0, 0, 0, 1};
+
+    genann *ann = genann_init(2, 0, 0, 1);
+
+    int i, j;
+
+    for (i = 0; i < 50; ++i) {
+        for (j = 0; j < 4; ++j) {
+            genann_train(ann, input[j], output + j, .8);
+        }
+    }
+
+    ann->activation_output = genann_act_threshold;
+    lfequal(output[0], *genann_run(ann, input[0]));
+    lfequal(output[1], *genann_run(ann, input[1]));
+    lfequal(output[2], *genann_run(ann, input[2]));
+    lfequal(output[3], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+}
+
+
+void train_or() {
+    double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+    double output[4] = {0, 1, 1, 1};
+
+    genann *ann = genann_init(2, 0, 0, 1);
+    genann_randomize(ann);
+
+    int i, j;
+
+    for (i = 0; i < 50; ++i) {
+        for (j = 0; j < 4; ++j) {
+            genann_train(ann, input[j], output + j, .8);
+        }
+    }
+
+    ann->activation_output = genann_act_threshold;
+    lfequal(output[0], *genann_run(ann, input[0]));
+    lfequal(output[1], *genann_run(ann, input[1]));
+    lfequal(output[2], *genann_run(ann, input[2]));
+    lfequal(output[3], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+}
+
+
+
+void train_xor() {
+    double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+    double output[4] = {0, 1, 1, 0};
+
+    genann *ann = genann_init(2, 1, 2, 1);
+
+    int i, j;
+
+    for (i = 0; i < 500; ++i) {
+        for (j = 0; j < 4; ++j) {
+            genann_train(ann, input[j], output + j, 3);
+        }
+        /* printf("%1.2f ", xor_score(ann)); */
+    }
+
+    ann->activation_output = genann_act_threshold;
+    lfequal(output[0], *genann_run(ann, input[0]));
+    lfequal(output[1], *genann_run(ann, input[1]));
+    lfequal(output[2], *genann_run(ann, input[2]));
+    lfequal(output[3], *genann_run(ann, input[3]));
+
+    genann_free(ann);
+}
+
+
+
+void persist() {
+    genann *first = genann_init(1000, 5, 50, 10);
+
+    FILE *out = fopen("persist.txt", "w");
+    genann_write(first, out);
+    fclose(out);
+
+
+    FILE *in = fopen("persist.txt", "r");
+    genann *second = genann_read(in);
+    fclose(in);
+
+    lequal(first->inputs, second->inputs);
+    lequal(first->hidden_layers, second->hidden_layers);
+    lequal(first->hidden, second->hidden);
+    lequal(first->outputs, second->outputs);
+    lequal(first->total_weights, second->total_weights);
+
+    int i;
+    for (i = 0; i < first->total_weights; ++i) {
+        lok(first->weight[i] == second->weight[i]);
+    }
+
+    genann_free(first);
+    genann_free(second);
+}
+
+
+void copy() {
+    genann *first = genann_init(1000, 5, 50, 10);
+
+    genann *second = genann_copy(first);
+
+    lequal(first->inputs, second->inputs);
+    lequal(first->hidden_layers, second->hidden_layers);
+    lequal(first->hidden, second->hidden);
+    lequal(first->outputs, second->outputs);
+    lequal(first->total_weights, second->total_weights);
+
+    int i;
+    for (i = 0; i < first->total_weights; ++i) {
+        lfequal(first->weight[i], second->weight[i]);
+    }
+
+    genann_free(first);
+    genann_free(second);
+}
+
+
+void sigmoid() {
+    double i = -20;
+    const double max = 20;
+    const double d = .0001;
+
+    while (i < max) {
+        lfequal(genann_act_sigmoid(NULL, i), genann_act_sigmoid_cached(NULL, i));
+        i += d;
+    }
+}
+
+
+int main(int argc, char *argv[])
+{
+    printf("GENANN TEST SUITE\n");
+
+    srand(100); //Repeatable test results.
+
+    lrun("basic", basic);
+    lrun("xor", xor);
+    lrun("backprop", backprop);
+    lrun("train and", train_and);
+    lrun("train or", train_or);
+    lrun("train xor", train_xor);
+    lrun("persist", persist);
+    lrun("copy", copy);
+    lrun("sigmoid", sigmoid);
+
+    lresults();
+
+    return lfails != 0;
+}