void write(final ObjectOutput out) throws IOException {
		writeInt(length(), out);
		out.writeObject(_operations);
		out.writeObject(_terminals);

		for (ProgramGene<A> gene : _genes) {
			out.writeObject(gene.allele());
			writeInt(gene.childOffset(), out);
		}
	}
Create a new program chromosome from the given (flattened) program tree.
This method doesn't make any assumption about the validity of the given
operation tree. If the tree is not valid, it will repair it. This
behaviour allows the <em>safe</em> usage of all existing alterers.

{@snippet lang="java":
final ProgramChromosome<Double> ch = ProgramChromosome.of(
    genes,
    // If the program has more that 200 nodes, it is marked as "invalid".
    ch -> ch.length() <= 200,
    operations,
    terminals
);
}

@param genes the program genes
@param validator the chromosome validator to use
@param operations the allowed non-terminal operations
@param terminals the allowed terminal operations
@param <A> the operation type
@return a new program chromosome from the given (flattened) program tree
@throws NullPointerException if one of the parameters is {@code null}
jenetics.prog/src/main/java/io/jenetics/prog/ProgramChromosome.java