private static <A> ProgramChromosome<A> create(
		final Tree<? extends Op<A>, ?> program,
		final Predicate<? super ProgramChromosome<A>> validator,
		final ISeq<? extends Op<A>> operations,
		final ISeq<? extends Op<A>> terminals
	) {
		final ISeq<ProgramGene<A>> genes = FlatTreeNode.ofTree(program).stream()
			.map(n -> new ProgramGene<>(
				n.value(), n.childOffset(), operations, terminals))
			.collect(ISeq.toISeq());

		return new ProgramChromosome<>(genes, validator, operations, terminals);
	}
Create a new chromosome from the given operation tree (program).

@param program the operation tree
@param validator the chromosome validator. A typical validator would
       check the size of the tree and if the tree is too large, mark it
       at <em>invalid</em>. The <em>validator</em> may be {@code null}.
@param operations the allowed non-terminal operations
@param terminals the allowed terminal operations
@param <A> the operation type
@return a new chromosome from the given operation tree
@throws NullPointerException if one of the given arguments is {@code null}
@throws IllegalArgumentException if the given operation tree is invalid,
        which means there is at least one node where the operation arity
        and the node child count differ.
jenetics.prog/src/main/java/io/jenetics/prog/ProgramChromosome.java