code: public static <A> ProgramChromosome<A> of(
  		final ISeq<ProgramGene<A>> genes,
  		final Predicate<? super ProgramChromosome<A>> validator,
  		final ISeq<? extends Op<A>> operations,
  		final ISeq<? extends Op<A>> terminals
  	) {
  		final TreeNode<Op<A>> program = Program.toTree(genes, terminals);
  		return of(program, validator, operations, terminals);
  	}
docs: 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 alterer.
  
  <pre>{@code
  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
  );
  }</pre>
  
  @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}