From b119465b09bace3e447528798bdf3b4cafeab266 Mon Sep 17 00:00:00 2001
From: Andre Maroneze <andre.maroneze@cea.fr>
Date: Tue, 2 Feb 2021 17:24:46 +0100
Subject: [PATCH] [genann] add new case study

---
 Makefile                                  |    1 +
 README.md                                 |    1 +
 frama-c                                   |    2 +-
 genann/.frama-c/GNUmakefile               |   49 +
 genann/.frama-c/genann.eva/alarms.csv     |   76 +
 genann/.frama-c/genann.eva/metrics.log    |   39 +
 genann/.frama-c/genann.eva/nonterm.log    |    0
 genann/.frama-c/genann.eva/warnings.log   |    0
 genann/.frama-c/genann.parse/framac.ast   | 2402 +++++++++++++++++++++
 genann/.frama-c/genann.parse/metrics.log  |   45 +
 genann/.frama-c/genann.parse/warnings.log |    2 +
 genann/.frama-c/path.mk                   |    1 +
 genann/LICENSE                            |   20 +
 genann/Makefile                           |   34 +
 genann/README.md                          |  154 ++
 genann/doc/e1.dot                         |    9 +
 genann/doc/e1.png                         |  Bin 0 -> 22067 bytes
 genann/example/iris.data                  |  150 ++
 genann/example/iris.names                 |   69 +
 genann/example/xor.ann                    |    1 +
 genann/example1.c                         |   41 +
 genann/example2.c                         |   71 +
 genann/example3.c                         |   39 +
 genann/example4.c                         |  119 +
 genann/genann.c                           |  405 ++++
 genann/genann.h                           |  108 +
 genann/minctest.h                         |  127 ++
 genann/outputs                            |   14 +
 genann/test.c                             |  276 +++
 29 files changed, 4254 insertions(+), 1 deletion(-)
 create mode 100644 genann/.frama-c/GNUmakefile
 create mode 100644 genann/.frama-c/genann.eva/alarms.csv
 create mode 100644 genann/.frama-c/genann.eva/metrics.log
 create mode 100644 genann/.frama-c/genann.eva/nonterm.log
 create mode 100644 genann/.frama-c/genann.eva/warnings.log
 create mode 100644 genann/.frama-c/genann.parse/framac.ast
 create mode 100644 genann/.frama-c/genann.parse/metrics.log
 create mode 100644 genann/.frama-c/genann.parse/warnings.log
 create mode 120000 genann/.frama-c/path.mk
 create mode 100644 genann/LICENSE
 create mode 100644 genann/Makefile
 create mode 100644 genann/README.md
 create mode 100644 genann/doc/e1.dot
 create mode 100644 genann/doc/e1.png
 create mode 100644 genann/example/iris.data
 create mode 100644 genann/example/iris.names
 create mode 100644 genann/example/xor.ann
 create mode 100644 genann/example1.c
 create mode 100644 genann/example2.c
 create mode 100644 genann/example3.c
 create mode 100644 genann/example4.c
 create mode 100644 genann/genann.c
 create mode 100644 genann/genann.h
 create mode 100644 genann/minctest.h
 create mode 100644 genann/outputs
 create mode 100644 genann/test.c

diff --git a/Makefile b/Makefile
index 10ebfcd4f..d856502eb 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 9e9c7550a..0fb01735f 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 086dbf677..4adb46e09 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 000000000..614826732
--- /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 000000000..d353cf06a
--- /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 000000000..c489c1d78
--- /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 000000000..e69de29bb
diff --git a/genann/.frama-c/genann.eva/warnings.log b/genann/.frama-c/genann.eva/warnings.log
new file mode 100644
index 000000000..e69de29bb
diff --git a/genann/.frama-c/genann.parse/framac.ast b/genann/.frama-c/genann.parse/framac.ast
new file mode 100644
index 000000000..2cd55aae4
--- /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 000000000..b26c37df8
--- /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 000000000..accee9a71
--- /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 000000000..57620d6d4
--- /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 000000000..5ab017c45
--- /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 000000000..427e3be71
--- /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 000000000..4e04d47af
--- /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 000000000..9e498c235
--- /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
GIT binary patch
literal 22067
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
Ir1b9pe~Bra{{R30

literal 0
HcmV?d00001

diff --git a/genann/example/iris.data b/genann/example/iris.data
new file mode 100644
index 000000000..a3490e0e0
--- /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 000000000..062b486d0
--- /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 000000000..c11a96817
--- /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 000000000..b45393c83
--- /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 000000000..fe635697e
--- /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 000000000..2ace13b45
--- /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 000000000..14de78363
--- /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 000000000..b05fa4fc7
--- /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 000000000..e4b7383de
--- /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 000000000..eb3ad4181
--- /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 000000000..b00d5f10a
--- /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 000000000..a7f895e07
--- /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;
+}
-- 
GitLab