
include("fastpolys.jl")

using Main.FastPolys
using StaticArrays
using BenchmarkTools
using StaticPolynomials
using CommonSubexpressions

module NB5I

using Main.FastPolys
using StaticArrays
using StaticPolynomials
using CommonSubexpressions


const P1_1 = (1,2,3,4,5,6,7,8,9,10,)

const P2_1 = (1,1,1,2,2,3,1,1,1,2,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,)
const P2_2 = (2,3,4,3,4,4,5,6,7,5,6,7,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)

const P3_1 = (1,2,3,4,5,6,7,8,9,10,)

const P4_1 = (1,1,1,2,1,1,1,2,2,3,4,3,4,2,3,4,5,5,6,7,)
const P4_2 = (2,2,3,3,5,5,6,5,5,6,7,6,7,8,8,9,6,8,8,9,)
const P4_3 = (3,4,4,4,6,7,7,8,9,8,9,10,10,9,10,10,7,9,10,10,)

const P5_1 = (1,2,3,4,5,6,7,8,9,10,)

const P6_1 = (1,1,2,3,4,)
const P6_2 = (2,5,5,6,7,)
const P6_3 = (3,6,8,8,9,)
const P6_4 = (4,7,9,10,10,)

const P7_1 = (1,2,3,4,5,6,7,8,9,10,)

const P8_1 = (1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,1,1,1,2,2,3,4,3,4,2,3,4,)
const P8_2 = (2,2,2,2,2,2,2,3,4,2,3,4,3,4,3,4,4,4,5,5,5,5,5,5,5,6,6,5,6,7,)
const P8_3 = (3,3,3,3,3,3,5,5,5,5,6,7,5,5,6,7,6,7,6,6,6,6,7,6,7,7,7,8,8,8,)
const P8_4 = (4,4,4,4,4,4,6,6,6,8,8,9,8,8,8,9,8,9,7,7,7,8,8,8,9,8,9,9,9,9,)
const P8_5 = (5,6,7,8,9,10,7,7,7,9,10,10,9,9,10,10,10,10,8,9,10,9,9,10,10,10,10,10,10,10,)

const P9_1 = (1,2,3,4,5,6,7,8,9,10,)

const P10_1 = (1,2,3,4,5,6,7,8,9,10,)

# Irreducible secondaries for NBody=5and deg=12
 # : definitions at the beginning of the file
const IS1_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS1_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS2_1 = (1,1,1,2,2,3,5,5,6,8,)
const IS2_2 = (2,3,4,3,4,4,6,7,7,9,)
const IS2_3 = (5,6,7,8,9,10,8,9,10,10,)

const IS3_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS3_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS4_1 = (1,1,1,2,2,3,1,1,1,2,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS4_2 = (2,3,4,3,4,4,5,6,7,5,6,7,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)

const IS5_1 = (1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,8,9,10,5,5,6,7,6,7,8,9,10,8,9,10,)
const IS5_2 = (2,3,4,1,1,1,3,4,2,2,4,3,1,1,1,2,2,3,6,7,5,5,7,6,5,5,6,9,8,8,)
const IS5_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,3,4,4,8,9,8,9,10,10,6,7,7,10,10,9,)

const IS6_1 = (1,1,1,2,2,3,4,3,4,2,3,4,1,1,1,2,2,3,4,3,4,2,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,6,7,5,6,7,8,9,8,9,10,10,)
const IS6_2 = (2,2,3,1,1,1,1,1,1,3,2,2,5,5,6,5,5,6,7,6,7,8,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,5,5,8,8,9,5,5,6,7,6,7,)
const IS6_3 = (3,4,4,3,4,2,2,4,3,4,4,3,6,7,7,8,9,8,9,10,10,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,7,7,6,9,10,10,9,8,10,10,8,9,)

const IS7_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,8,9,8,9,10,10,)
const IS7_2 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,7,6,7,6,5,5,6,7,5,5,7,6,)
const IS7_3 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,9,8,10,10,8,9,)

const IS8_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS8_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS9_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS9_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS10_1 = (1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,8,9,10,5,5,6,7,6,7,8,9,10,8,9,10,)
const IS10_2 = (2,3,4,1,1,1,3,4,2,2,4,3,1,1,1,2,2,3,6,7,5,5,7,6,5,5,6,9,8,8,)
const IS10_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,3,4,4,8,9,8,9,10,10,6,7,7,10,10,9,)

const IS11_1 = (1,1,1,2,2,3,1,1,1,2,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS11_2 = (2,3,4,3,4,4,5,6,7,5,6,7,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)
const IS11_3 = (5,6,7,8,9,10,2,3,4,1,1,1,3,4,2,2,4,3,8,9,10,6,7,5,5,7,6,10,9,8,)

const IS12_1 = (1,1,1,2,2,3,4,3,4,2,3,4,1,1,1,2,2,3,4,3,4,2,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,6,7,5,6,7,8,9,8,9,10,10,)
const IS12_2 = (2,2,3,1,1,1,1,1,1,3,2,2,5,5,6,5,5,6,7,6,7,8,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,5,5,8,8,9,5,5,6,7,6,7,)
const IS12_3 = (3,4,4,3,4,2,2,4,3,4,4,3,6,7,7,8,9,8,9,10,10,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,7,7,6,9,10,10,9,8,10,10,8,9,)

const IS13_1 = (1,1,1,1,1,1,2,2,3,2,2,3,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS13_2 = (2,2,3,4,3,4,3,4,4,3,4,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)
const IS13_3 = (3,4,2,2,4,3,1,1,1,4,3,2,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,1,1,1,2,2,3,4,3,4,2,3,4,7,6,5,9,8,10,10,8,9,5,6,7,)

const IS14_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,8,9,8,9,10,10,)
const IS14_2 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,7,6,7,6,5,5,6,7,5,5,7,6,)
const IS14_3 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,9,8,10,10,8,9,)

const IS15_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS15_2 = (2,2,2,2,3,3,1,1,1,1,1,1,1,1,1,1,1,1,3,3,2,2,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,3,3,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,6,5,5,5,5,6,7,5,5,7,6,5,5,5,5,6,6,5,5,6,7,6,7,)
const IS15_3 = (3,4,3,4,4,4,3,4,2,2,4,3,3,4,2,2,4,3,4,4,4,3,4,3,5,5,5,5,6,6,5,5,6,7,6,7,5,5,6,7,6,7,8,8,8,9,8,9,2,2,3,4,3,4,2,2,3,4,3,4,3,4,3,4,4,4,3,4,3,4,4,4,6,7,5,5,7,6,6,7,5,5,7,6,5,5,5,5,6,6,9,8,9,8,8,8,7,7,7,6,7,6,8,8,8,9,8,9,6,7,6,7,7,7,9,8,9,8,8,8,)
const IS15_4 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,6,7,7,7,8,9,8,9,10,10,8,9,8,9,10,10,9,9,10,10,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,8,9,8,9,10,10,6,7,6,7,7,7,10,10,10,10,9,9,8,9,8,9,10,10,9,9,10,10,10,10,9,8,10,10,8,9,10,10,10,10,9,9,)

const IS16_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS16_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS17_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS17_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS18_1 = (1,1,1,2,2,3,1,1,1,2,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS18_2 = (2,3,4,3,4,4,5,6,7,5,6,7,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)

const IS19_1 = (1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,8,9,10,5,5,6,7,6,7,8,9,10,8,9,10,)
const IS19_2 = (2,3,4,1,1,1,3,4,2,2,4,3,1,1,1,2,2,3,6,7,5,5,7,6,5,5,6,9,8,8,)
const IS19_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,3,4,4,8,9,8,9,10,10,6,7,7,10,10,9,)

const IS20_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS20_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)
const IS20_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,1,1,1,3,4,2,2,4,3,2,3,4,1,1,1,3,4,2,2,4,3,8,9,8,9,10,10,6,7,5,5,7,6,6,7,5,5,7,6,10,10,9,8,9,8,)

const IS21_1 = (1,1,1,2,2,3,5,5,6,8,)
const IS21_2 = (2,3,4,3,4,4,6,7,7,9,)
const IS21_3 = (5,6,7,8,9,10,8,9,10,10,)

const IS22_1 = (1,1,1,2,2,3,4,3,4,2,3,4,1,1,1,2,2,3,4,3,4,2,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,6,7,5,6,7,8,9,8,9,10,10,)
const IS22_2 = (2,2,3,1,1,1,1,1,1,3,2,2,5,5,6,5,5,6,7,6,7,8,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,5,5,8,8,9,5,5,6,7,6,7,)
const IS22_3 = (3,4,4,3,4,2,2,4,3,4,4,3,6,7,7,8,9,8,9,10,10,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,7,7,6,9,10,10,9,8,10,10,8,9,)

const IS23_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS23_2 = (2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)
const IS23_3 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,7,6,7,6,5,5,9,8,10,10,8,9,9,8,10,10,8,9,5,5,6,7,6,7,)

const IS24_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,8,9,8,9,10,10,)
const IS24_2 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,7,6,7,6,5,5,6,7,5,5,7,6,)
const IS24_3 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,9,8,10,10,8,9,)

const IS25_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS25_2 = (2,2,2,2,3,3,1,1,1,1,1,1,1,1,1,1,1,1,3,3,2,2,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,3,3,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,6,5,5,5,5,6,7,5,5,7,6,5,5,5,5,6,6,5,5,6,7,6,7,)
const IS25_3 = (3,4,3,4,4,4,3,4,2,2,4,3,3,4,2,2,4,3,4,4,4,3,4,3,5,5,5,5,6,6,5,5,6,7,6,7,5,5,6,7,6,7,8,8,8,9,8,9,2,2,3,4,3,4,2,2,3,4,3,4,3,4,3,4,4,4,3,4,3,4,4,4,6,7,5,5,7,6,6,7,5,5,7,6,5,5,5,5,6,6,9,8,9,8,8,8,7,7,7,6,7,6,8,8,8,9,8,9,6,7,6,7,7,7,9,8,9,8,8,8,)
const IS25_4 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,6,7,7,7,8,9,8,9,10,10,8,9,8,9,10,10,9,9,10,10,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,8,9,8,9,10,10,6,7,6,7,7,7,10,10,10,10,9,9,8,9,8,9,10,10,9,9,10,10,10,10,9,8,10,10,8,9,10,10,10,10,9,9,)

const IS26_1 = (1,1,1,1,1,1,2,2,3,2,2,3,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS26_2 = (2,2,3,4,3,4,3,4,4,3,4,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)
const IS26_3 = (3,4,2,2,4,3,1,1,1,4,3,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,2,2,3,4,3,4,2,3,4,7,6,5,6,7,5,5,7,6,5,6,7,)
const IS26_4 = (5,5,6,7,6,7,8,9,10,8,9,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,10,6,7,5,5,7,6,10,9,8,8,9,10,9,8,10,10,8,9,10,9,8,)

const IS27_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS27_2 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,8,9,8,9,10,10,6,7,5,5,7,6,6,7,5,5,7,6,10,10,9,8,9,8,8,9,8,9,10,10,6,7,5,5,7,6,6,7,5,5,7,6,10,10,9,8,9,8,)
const IS27_3 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,7,6,7,6,5,5,9,8,10,10,8,9,9,8,10,10,8,9,5,5,6,7,6,7,)

const IS28_1 = (1,2,3,4,5,6,7,8,9,10,)

const IS29_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS29_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS30_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS30_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS31_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS31_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS32_1 = (1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,8,9,10,5,5,6,7,6,7,8,9,10,8,9,10,)
const IS32_2 = (2,3,4,1,1,1,3,4,2,2,4,3,1,1,1,2,2,3,6,7,5,5,7,6,5,5,6,9,8,8,)
const IS32_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,3,4,4,8,9,8,9,10,10,6,7,7,10,10,9,)

const IS33_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS33_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)
const IS33_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,1,1,1,3,4,2,2,4,3,2,3,4,1,1,1,3,4,2,2,4,3,8,9,8,9,10,10,6,7,5,5,7,6,6,7,5,5,7,6,10,10,9,8,9,8,)

const IS34_1 = (1,1,1,2,2,3,1,1,1,2,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS34_2 = (2,3,4,3,4,4,5,6,7,5,6,7,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)
const IS34_3 = (5,6,7,8,9,10,2,3,4,1,1,1,3,4,2,2,4,3,8,9,10,6,7,5,5,7,6,10,9,8,)

const IS35_1 = (1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,8,9,10,5,5,6,7,6,7,8,9,10,8,9,10,)
const IS35_2 = (2,3,4,1,1,1,3,4,2,2,4,3,1,1,1,2,2,3,6,7,5,5,7,6,5,5,6,9,8,8,)
const IS35_3 = (5,6,7,5,6,7,8,9,8,9,10,10,2,3,4,3,4,4,8,9,8,9,10,10,6,7,7,10,10,9,)

const IS36_1 = (1,1,1,2,2,3,4,3,4,2,3,4,1,1,1,2,2,3,4,3,4,2,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,6,7,5,6,7,8,9,8,9,10,10,)
const IS36_2 = (2,2,3,1,1,1,1,1,1,3,2,2,5,5,6,5,5,6,7,6,7,8,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,5,5,8,8,9,5,5,6,7,6,7,)
const IS36_3 = (3,4,4,3,4,2,2,4,3,4,4,3,6,7,7,8,9,8,9,10,10,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,7,7,6,9,10,10,9,8,10,10,8,9,)

const IS37_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS37_2 = (2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)
const IS37_3 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,7,6,7,6,5,5,9,8,10,10,8,9,9,8,10,10,8,9,5,5,6,7,6,7,)

const IS38_1 = (1,1,1,1,1,1,2,2,3,2,2,3,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,5,5,6,7,6,7,8,8,9,5,5,6,5,5,6,7,6,7,8,8,9,)
const IS38_2 = (2,2,3,4,3,4,3,4,4,3,4,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,6,7,7,8,9,8,9,10,10,9,10,10,)
const IS38_3 = (3,4,2,2,4,3,1,1,1,4,3,2,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,1,1,1,2,2,3,4,3,4,2,3,4,7,6,5,9,8,10,10,8,9,5,6,7,)

const IS39_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,8,9,8,9,10,10,)
const IS39_2 = (3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,4,3,4,3,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,7,6,7,6,5,5,6,7,5,5,7,6,)
const IS39_3 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,9,8,10,10,8,9,)

const IS40_1 = (1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS40_2 = (2,2,2,2,3,3,1,1,1,1,1,1,1,1,1,1,1,1,3,3,2,2,2,2,2,2,3,4,3,4,1,1,1,1,1,1,3,4,2,2,4,3,3,4,2,2,4,3,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,3,3,1,1,1,1,1,1,2,2,3,4,3,4,2,2,3,4,3,4,2,2,3,4,3,4,6,6,5,5,5,5,6,7,5,5,7,6,5,5,5,5,6,6,5,5,6,7,6,7,)
const IS40_3 = (3,4,3,4,4,4,3,4,2,2,4,3,3,4,2,2,4,3,4,4,4,3,4,3,5,5,5,5,6,6,5,5,6,7,6,7,5,5,6,7,6,7,8,8,8,9,8,9,2,2,3,4,3,4,2,2,3,4,3,4,3,4,3,4,4,4,3,4,3,4,4,4,6,7,5,5,7,6,6,7,5,5,7,6,5,5,5,5,6,6,9,8,9,8,8,8,7,7,7,6,7,6,8,8,8,9,8,9,6,7,6,7,7,7,9,8,9,8,8,8,)
const IS40_4 = (5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,6,7,6,7,7,7,8,9,8,9,10,10,8,9,8,9,10,10,9,9,10,10,10,10,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,8,9,8,9,10,10,8,9,8,9,10,10,6,7,6,7,7,7,10,10,10,10,9,9,8,9,8,9,10,10,9,9,10,10,10,10,9,8,10,10,8,9,10,10,10,10,9,9,)

const IS41_1 = (1,2,3,4,5,6,7,8,9,10,)

const IS42_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS42_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS43_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS43_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS44_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS44_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)

const IS45_1 = (1,2,3,4,5,6,7,8,9,10,)

const IS46_1 = (1,1,1,2,3,4,2,2,3,4,3,4,1,1,1,2,3,4,2,2,3,4,3,4,5,6,7,5,6,7,8,9,8,9,10,10,5,5,6,7,6,7,5,5,6,7,6,7,8,9,8,9,10,10,8,9,8,9,10,10,)
const IS46_2 = (2,3,4,1,1,1,3,4,2,2,4,3,5,6,7,5,6,7,8,9,8,9,10,10,1,1,1,2,3,4,2,2,3,4,3,4,6,7,5,5,7,6,8,9,8,9,10,10,5,5,6,7,6,7,9,8,10,10,8,9,)


# Primary invariants for NBody=5and deg=12
 # : definitions of the types at the beginning of the file
const P1 = Val((P1_1,))
const P2 = Val((P2_1,P2_2,))
const P3 = Val((P3_1,))
const P4 = Val((P4_1,P4_2,P4_3,))
const P5 = Val((P5_1,))
const P6 = Val((P6_1,P6_2,P6_3,P6_4,))
const P7 = Val((P7_1,))
const P8 = Val((P8_1,P8_2,P8_3,P8_4,P8_5,))
const P9 = Val((P9_1,))
const P10 = Val((P10_1,))
# Irreducible secondaries for NBody=5and deg=12
 # : definitions of the types at the beginning of the file
const IS1 = Val((IS1_1,IS1_2,))
const IS2 = Val((IS2_1,IS2_2,IS2_3,))
const IS3 = Val((IS3_1,IS3_2,))
const IS4 = Val((IS4_1,IS4_2,))
const IS5 = Val((IS5_1,IS5_2,IS5_3,))
const IS6 = Val((IS6_1,IS6_2,IS6_3,))
const IS7 = Val((IS7_1,IS7_2,IS7_3,))
const IS8 = Val((IS8_1,IS8_2,))
const IS9 = Val((IS9_1,IS9_2,))
const IS10 = Val((IS10_1,IS10_2,IS10_3,))
const IS11 = Val((IS11_1,IS11_2,IS11_3,))
const IS12 = Val((IS12_1,IS12_2,IS12_3,))
const IS13 = Val((IS13_1,IS13_2,IS13_3,))
const IS14 = Val((IS14_1,IS14_2,IS14_3,))
const IS15 = Val((IS15_1,IS15_2,IS15_3,IS15_4,))
const IS16 = Val((IS16_1,IS16_2,))
const IS17 = Val((IS17_1,IS17_2,))
const IS18 = Val((IS18_1,IS18_2,))
const IS19 = Val((IS19_1,IS19_2,IS19_3,))
const IS20 = Val((IS20_1,IS20_2,IS20_3,))
const IS21 = Val((IS21_1,IS21_2,IS21_3,))
const IS22 = Val((IS22_1,IS22_2,IS22_3,))
const IS23 = Val((IS23_1,IS23_2,IS23_3,))
const IS24 = Val((IS24_1,IS24_2,IS24_3,))
const IS25 = Val((IS25_1,IS25_2,IS25_3,IS25_4,))
const IS26 = Val((IS26_1,IS26_2,IS26_3,IS26_4,))
const IS27 = Val((IS27_1,IS27_2,IS27_3,))
const IS28 = Val((IS28_1,))
const IS29 = Val((IS29_1,IS29_2,))
const IS30 = Val((IS30_1,IS30_2,))
const IS31 = Val((IS31_1,IS31_2,))
const IS32 = Val((IS32_1,IS32_2,IS32_3,))
const IS33 = Val((IS33_1,IS33_2,IS33_3,))
const IS34 = Val((IS34_1,IS34_2,IS34_3,))
const IS35 = Val((IS35_1,IS35_2,IS35_3,))
const IS36 = Val((IS36_1,IS36_2,IS36_3,))
const IS37 = Val((IS37_1,IS37_2,IS37_3,))
const IS38 = Val((IS38_1,IS38_2,IS38_3,))
const IS39 = Val((IS39_1,IS39_2,IS39_3,))
const IS40 = Val((IS40_1,IS40_2,IS40_3,IS40_4,))
const IS41 = Val((IS41_1,))
const IS42 = Val((IS42_1,IS42_2,))
const IS43 = Val((IS43_1,IS43_2,))
const IS44 = Val((IS44_1,IS44_2,))
const IS45 = Val((IS45_1,))
const IS46 = Val((IS46_1,IS46_2,))


function invold(x1::SVector{10, T}) where {T}
   x2 = x1.*x1
   x3 = x2.*x1
   x4 = x3.*x1
   x5 = x4.*x1
   x6 = x5.*x1
   x7 = x6.*x1
   x8 = x7.*x1
   x9 = x8.*x1
   #------------------------------------------------
   # Primaries
   #------------------------------------------------

   # Primary invariants for NBody=5and deg=12
    # : what goes in the function for the evaluation
   P1 = fpoly((x1,) , NB5I.P1)
   P2 = fpoly((x1,x1,) , NB5I.P2)
   P3 = fpoly((x2,) , NB5I.P3)
   P4 = fpoly((x1,x1,x1,) , NB5I.P4)
   P5 = fpoly((x3,) , NB5I.P5)
   P6 = fpoly((x1,x1,x1,x1,) , NB5I.P6)
   P7 = fpoly((x4,) , NB5I.P7)
   P8 = fpoly((x1,x1,x1,x1,x1,) , NB5I.P8)
   P9 = fpoly((x5,) , NB5I.P9)
   P10 = fpoly((x6,) , NB5I.P10)



      #------------------------------------------------
      # Irreducible secondaries
      #------------------------------------------------


   # Irreducible secondaries for NBody=5and deg=12
    # : what goes in the function for the evaluation
   IS1 = fpoly((x2,x1,) , NB5I.IS1)
   IS2 = fpoly((x1,x1,x1,) , NB5I.IS2)
   IS3 = fpoly((x3,x1,) , NB5I.IS3)
   IS4 = fpoly((x2,x2,) , NB5I.IS4)
   IS5 = fpoly((x2,x1,x1,) , NB5I.IS5)
   IS6 = fpoly((x2,x1,x1,) , NB5I.IS6)
   IS7 = fpoly((x2,x1,x1,) , NB5I.IS7)
   IS8 = fpoly((x4,x1,) , NB5I.IS8)
   IS9 = fpoly((x3,x2,) , NB5I.IS9)
   IS10 = fpoly((x3,x1,x1,) , NB5I.IS10)
   IS11 = fpoly((x2,x2,x1,) , NB5I.IS11)
   IS12 = fpoly((x3,x1,x1,) , NB5I.IS12)
   IS13 = fpoly((x2,x2,x1,) , NB5I.IS13)
   IS14 = fpoly((x3,x1,x1,) , NB5I.IS14)
   IS15 = fpoly((x2,x1,x1,x1,) , NB5I.IS15)
   IS16 = fpoly((x5,x1,) , NB5I.IS16)
   IS17 = fpoly((x4,x2,) , NB5I.IS17)
   IS18 = fpoly((x3,x3,) , NB5I.IS18)
   IS19 = fpoly((x4,x1,x1,) , NB5I.IS19)
   IS20 = fpoly((x3,x2,x1,) , NB5I.IS20)
   IS21 = fpoly((x2,x2,x2,) , NB5I.IS21)
   IS22 = fpoly((x4,x1,x1,) , NB5I.IS22)
   IS23 = fpoly((x3,x2,x1,) , NB5I.IS23)
   IS24 = fpoly((x4,x1,x1,) , NB5I.IS24)
   IS25 = fpoly((x3,x1,x1,x1,) , NB5I.IS25)
   IS26 = fpoly((x2,x2,x1,x1,) , NB5I.IS26)
   IS27 = fpoly((x3,x2,x1,) , NB5I.IS27)
   IS28 = fpoly((x7,) , NB5I.IS28)
   IS29 = fpoly((x6,x1,) , NB5I.IS29)
   IS30 = fpoly((x5,x2,) , NB5I.IS30)
   IS31 = fpoly((x4,x3,) , NB5I.IS31)
   IS32 = fpoly((x5,x1,x1,) , NB5I.IS32)
   IS33 = fpoly((x4,x2,x1,) , NB5I.IS33)
   IS34 = fpoly((x3,x3,x1,) , NB5I.IS34)
   IS35 = fpoly((x3,x2,x2,) , NB5I.IS35)
   IS36 = fpoly((x5,x1,x1,) , NB5I.IS36)
   IS37 = fpoly((x4,x2,x1,) , NB5I.IS37)
   IS38 = fpoly((x3,x3,x1,) , NB5I.IS38)
   IS39 = fpoly((x5,x1,x1,) , NB5I.IS39)
   IS40 = fpoly((x4,x1,x1,x1,) , NB5I.IS40)
   IS41 = fpoly((x8,) , NB5I.IS41)
   IS42 = fpoly((x7,x1,) , NB5I.IS42)
   IS43 = fpoly((x6,x2,) , NB5I.IS43)
   IS44 = fpoly((x5,x3,) , NB5I.IS44)
   IS45 = fpoly((x9,) , NB5I.IS45)
   IS46 = fpoly((x8,x1,) , NB5I.IS46)


   return (@SVector [P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,
         IS1, IS2, IS3, IS4, IS5, IS6, IS7, IS8, IS9, IS10,
         IS11, IS12, IS13, IS14, IS15, IS16, IS17, IS18, IS19,
         IS20, IS21, IS22, IS23, IS24, IS25, IS26, IS27, IS28, IS29, IS30, IS31,
         IS32, IS33, IS34, IS35, IS36, IS37, IS38, IS39, IS40, IS41, IS42, IS43,
         IS44, IS45, IS46])
end




const PP1 = (P1_1,)
const PP2 = (P2_1,P2_2,)
const PP3 = (P3_1,)
const PP4 = (P4_1,P4_2,P4_3,)
const PP5 = (P5_1,)
const PP6 = (P6_1,P6_2,P6_3,P6_4,)
const PP7 = (P7_1,)
const PP8 = (P8_1,P8_2,P8_3,P8_4,P8_5,)
const PP9 = (P9_1,)
const PP10 = (P10_1,)


const ISS1 = (IS1_1,IS1_2,)
const ISS2 = (IS2_1,IS2_2,IS2_3,)
const ISS3 = (IS3_1,IS3_2,)
const ISS4 = (IS4_1,IS4_2,)
const ISS5 = (IS5_1,IS5_2,IS5_3,)
const ISS6 = (IS6_1,IS6_2,IS6_3,)
const ISS7 = (IS7_1,IS7_2,IS7_3,)
const ISS8 = (IS8_1,IS8_2,)
const ISS9 = (IS9_1,IS9_2,)
const ISS10 = (IS10_1,IS10_2,IS10_3,)
const ISS11 = (IS11_1,IS11_2,IS11_3,)
const ISS12 = (IS12_1,IS12_2,IS12_3,)
const ISS13 = (IS13_1,IS13_2,IS13_3,)
const ISS14 = (IS14_1,IS14_2,IS14_3,)
const ISS15 = (IS15_1,IS15_2,IS15_3,IS15_4,)
const ISS16 = (IS16_1,IS16_2,)
const ISS17 = (IS17_1,IS17_2,)
const ISS18 = (IS18_1,IS18_2,)
const ISS19 = (IS19_1,IS19_2,IS19_3,)
const ISS20 = (IS20_1,IS20_2,IS20_3,)
const ISS21 = (IS21_1,IS21_2,IS21_3,)
const ISS22 = (IS22_1,IS22_2,IS22_3,)
const ISS23 = (IS23_1,IS23_2,IS23_3,)
const ISS24 = (IS24_1,IS24_2,IS24_3,)
const ISS25 = (IS25_1,IS25_2,IS25_3,IS25_4,)
const ISS26 = (IS26_1,IS26_2,IS26_3,IS26_4,)
const ISS27 = (IS27_1,IS27_2,IS27_3,)
const ISS28 = (IS28_1,)
const ISS29 = (IS29_1,IS29_2,)
const ISS30 = (IS30_1,IS30_2,)
const ISS31 = (IS31_1,IS31_2,)
const ISS32 = (IS32_1,IS32_2,IS32_3,)
const ISS33 = (IS33_1,IS33_2,IS33_3,)
const ISS34 = (IS34_1,IS34_2,IS34_3,)
const ISS35 = (IS35_1,IS35_2,IS35_3,)
const ISS36 = (IS36_1,IS36_2,IS36_3,)
const ISS37 = (IS37_1,IS37_2,IS37_3,)
const ISS38 = (IS38_1,IS38_2,IS38_3,)
const ISS39 = (IS39_1,IS39_2,IS39_3,)
const ISS40 = (IS40_1,IS40_2,IS40_3,IS40_4,)
const ISS41 = (IS41_1,)
const ISS42 = (IS42_1,IS42_2,)
const ISS43 = (IS43_1,IS43_2,)
const ISS44 = (IS44_1,IS44_2,)
const ISS45 = (IS45_1,)
const ISS46 = (IS46_1,IS46_2,)



function _gen_sym(pows, vars)
   I = sortperm(vars)
   return Symbol(prod( "X$(v)_$(p)_x_"
                       for (v,p) in zip(vars[I], pows[I]) )[1:end-2])
end

function push_monomial!(exprs, syms, pows, vars)
   @assert length(vars) == length(pows)
   s = _gen_sym(pows, vars)
   if s in syms
      # if this monomial already exists, there is nothing to do
      # just return the generated symbol
      return s
   end
   # if the symbol does not yet exist we build it recursively
   # TODO: here, the recursion could be taken further and a proper search
   # over similar symbols could be performed, thigh might
   # speed up things further
   s1 = push_monomial!(exprs, syms, pows[1:end-1], vars[1:end-1])
   s2 = push_monomial!(exprs, syms, pows[end:end], vars[end:end])
   push!(exprs, :($(s) = $(s1)*$(s2)))
   push!(syms, s)
   return s
end

function push_polynomial!(exprs, syms, pows, vars, newsym)
   push!(exprs, :($(newsym) = 0.0))
   for n = 1:length(vars[1])
      vars_n = [ vars[m][n] for m = 1:length(pows) ]
      s = push_monomial!(exprs, syms, pows, vars_n)
      push!(exprs, :($(newsym) += $(s)))
   end
end

@generated function invnew(x1::SVector{10, T}) where {T}
   exprs = Expr[]
   syms = Symbol[]

   # start the symbol list by adding all powes x1[n]^p
   for n = 1:10
      s = _gen_sym([1], [n])
      push!(exprs, :($s = x1[$n]))
      push!(syms, s)
      for p = 2:9
         sold = _gen_sym([p-1], [n])
         snew = _gen_sym([p], [n])
         push!(exprs, :($(snew) = $(sold) * x1[$n]))
         push!(syms, snew)
      end
   end


   #------------------------------------------------
   # Primaries
   #------------------------------------------------

   # Primary invariants for NBody=5and deg=12
    # : what goes in the function for the evaluation
   push_polynomial!(exprs, syms, (1,) , NB5I.PP1, :p1)
   push_polynomial!(exprs, syms, (1,1,) , NB5I.PP2, :p2)
   push_polynomial!(exprs, syms, (2,) , NB5I.PP3, :p3)
   push_polynomial!(exprs, syms, (1,1,1,) , NB5I.PP4, :p4)
   push_polynomial!(exprs, syms, (3,) , NB5I.PP5, :p5)
   push_polynomial!(exprs, syms, (1,1,1,1,) , NB5I.PP6, :p6)
   push_polynomial!(exprs, syms, (4,) , NB5I.PP7, :p7)
   push_polynomial!(exprs, syms, (1,1,1,1,1,) , NB5I.PP8, :p8)
   push_polynomial!(exprs, syms, (5,) , NB5I.PP9, :p9)
   push_polynomial!(exprs, syms, (6,) , NB5I.PP10, :p10)

   push_polynomial!(exprs, syms, (2,1,) , NB5I.ISS1, :is1)
   push_polynomial!(exprs, syms, (1,1,1,) , NB5I.ISS2, :is2)
   push_polynomial!(exprs, syms, (3,1,) , NB5I.ISS3, :is3)
   push_polynomial!(exprs, syms, (2,2,) , NB5I.ISS4, :is4)
   push_polynomial!(exprs, syms, (2,1,1,) , NB5I.ISS5, :is5)
   push_polynomial!(exprs, syms, (2,1,1,) , NB5I.ISS6, :is6)
   push_polynomial!(exprs, syms, (2,1,1,) , NB5I.ISS7, :is7)
   push_polynomial!(exprs, syms, (4,1,) , NB5I.ISS8, :is8)
   push_polynomial!(exprs, syms, (3,2,) , NB5I.ISS9, :is9)
   push_polynomial!(exprs, syms, (3,1,1,) , NB5I.ISS10, :is10)
   push_polynomial!(exprs, syms, (2,2,1,) , NB5I.ISS11, :is11)
   push_polynomial!(exprs, syms, (3,1,1,) , NB5I.ISS12, :is12)
   push_polynomial!(exprs, syms, (2,2,1,) , NB5I.ISS13, :is13)
   push_polynomial!(exprs, syms, (3,1,1,) , NB5I.ISS14, :is14)
   push_polynomial!(exprs, syms, (2,1,1,1,) , NB5I.ISS15, :is15)
   push_polynomial!(exprs, syms, (5,1,) , NB5I.ISS16, :is16)
   push_polynomial!(exprs, syms, (4,2,) , NB5I.ISS17, :is17)
   push_polynomial!(exprs, syms, (3,3,) , NB5I.ISS18, :is18)
   push_polynomial!(exprs, syms, (4,1,1,) , NB5I.ISS19, :is19)
   push_polynomial!(exprs, syms, (3,2,1,) , NB5I.ISS20, :is20)
   push_polynomial!(exprs, syms, (2,2,2,) , NB5I.ISS21, :is21)
   push_polynomial!(exprs, syms, (4,1,1,) , NB5I.ISS22, :is22)
   push_polynomial!(exprs, syms, (3,2,1,) , NB5I.ISS23, :is23)
   push_polynomial!(exprs, syms, (4,1,1,) , NB5I.ISS24, :is24)
   push_polynomial!(exprs, syms, (3,1,1,1,) , NB5I.ISS25, :is25)
   push_polynomial!(exprs, syms, (2,2,1,1,) , NB5I.ISS26, :is26)
   push_polynomial!(exprs, syms, (3,2,1,) , NB5I.ISS27, :is27)
   push_polynomial!(exprs, syms, (7,) , NB5I.ISS28, :is28)
   push_polynomial!(exprs, syms, (6,1,) , NB5I.ISS29, :is29)
   push_polynomial!(exprs, syms, (5,2,) , NB5I.ISS30, :is30)
   push_polynomial!(exprs, syms, (4,3,) , NB5I.ISS31, :is31)
   push_polynomial!(exprs, syms, (5,1,1,) , NB5I.ISS32, :is32)
   push_polynomial!(exprs, syms, (4,2,1,) , NB5I.ISS33, :is33)
   push_polynomial!(exprs, syms, (3,3,1,) , NB5I.ISS34, :is34)
   push_polynomial!(exprs, syms, (3,2,2,) , NB5I.ISS35, :is35)
   push_polynomial!(exprs, syms, (5,1,1,) , NB5I.ISS36, :is36)
   push_polynomial!(exprs, syms, (4,2,1,) , NB5I.ISS37, :is37)
   push_polynomial!(exprs, syms, (3,3,1,) , NB5I.ISS38, :is38)
   push_polynomial!(exprs, syms, (5,1,1,) , NB5I.ISS39, :is39)
   push_polynomial!(exprs, syms, (4,1,1,1,) , NB5I.ISS40, :is40)
   push_polynomial!(exprs, syms, (8,) , NB5I.ISS41, :is41)
   push_polynomial!(exprs, syms, (7,1,) , NB5I.ISS42, :is42)
   push_polynomial!(exprs, syms, (6,2,) , NB5I.ISS43, :is43)
   push_polynomial!(exprs, syms, (5,3,) , NB5I.ISS44, :is44)
   push_polynomial!(exprs, syms, (9,) , NB5I.ISS45, :is45)
   push_polynomial!(exprs, syms, (8,1,) , NB5I.ISS46, :is46)


   push!(exprs, :((@SVector [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,
         is1, is2, is3, is4, is5, is6, is7, is8, is9, is10,
         is11, is12, is13, is14,
         is15, is16, is17, is18, is19, is20, is21, is22, is23,
         is24, is25, is26, is27, is28, is29, is30, is31, is32,
         is33, is34, is35, is36, is37, is38, is39, is40, is41,
         is42, is43, is44, is45, is46])))
   codeblock = Expr(:block, exprs...)

   quote
      $(Expr(:meta, :inline))
      @inbounds $codeblock
   end
end


@generated function invnew!(out::MVector{56,T}, x1::SVector{10, T}) where {T}
   exprs = Expr[]
   syms = Symbol[]

   # start the symbol list by adding all powes x1[n]^p
   for n = 1:10
      s = _gen_sym([1], [n])
      push!(exprs, :($s = x1[$n]))
      push!(syms, s)
      for p = 2:9
         sold = _gen_sym([p-1], [n])
         snew = _gen_sym([p], [n])
         push!(exprs, :($(snew) = $(sold) * x1[$n]))
         push!(syms, snew)
      end
   end


   #------------------------------------------------
   # Primaries
   #------------------------------------------------

   # Primary invariants for NBody=5and deg=12
    # : what goes in the function for the evaluation
   push_polynomial!(exprs, syms, (1,) , NB5I.PP1, :(out[1]))
   push_polynomial!(exprs, syms, (1,1,) , NB5I.PP2, :(out[2]))
   push_polynomial!(exprs, syms, (2,) , NB5I.PP3, :(out[3]))
   push_polynomial!(exprs, syms, (1,1,1,) , NB5I.PP4, :(out[4]))
   push_polynomial!(exprs, syms, (3,) , NB5I.PP5, :(out[5]))
   push_polynomial!(exprs, syms, (1,1,1,1,) , NB5I.PP6, :(out[6]))
   push_polynomial!(exprs, syms, (4,) , NB5I.PP7, :(out[7]))
   push_polynomial!(exprs, syms, (1,1,1,1,1,) , NB5I.PP8, :(out[8]))
   push_polynomial!(exprs, syms, (5,) , NB5I.PP9, :(out[9]))
   push_polynomial!(exprs, syms, (6,) , NB5I.PP10, :(out[10]))

   push_polynomial!(exprs, syms, (2,1,) , NB5I.ISS1, :(out[11]))
   push_polynomial!(exprs, syms, (1,1,1,) , NB5I.ISS2, :(out[12]))
   push_polynomial!(exprs, syms, (3,1,) , NB5I.ISS3, :(out[13]))
   push_polynomial!(exprs, syms, (2,2,) , NB5I.ISS4, :(out[14]))
   push_polynomial!(exprs, syms, (2,1,1,) , NB5I.ISS5, :(out[15]))
   push_polynomial!(exprs, syms, (2,1,1,) , NB5I.ISS6, :(out[16]))
   push_polynomial!(exprs, syms, (2,1,1,) , NB5I.ISS7, :(out[17]))
   push_polynomial!(exprs, syms, (4,1,) , NB5I.ISS8, :(out[18]))
   push_polynomial!(exprs, syms, (3,2,) , NB5I.ISS9, :(out[19]))
   push_polynomial!(exprs, syms, (3,1,1,) , NB5I.ISS10, :(out[20]))
   push_polynomial!(exprs, syms, (2,2,1,) , NB5I.ISS11, :(out[21]))
   push_polynomial!(exprs, syms, (3,1,1,) , NB5I.ISS12, :(out[22]))
   push_polynomial!(exprs, syms, (2,2,1,) , NB5I.ISS13, :(out[23]))
   push_polynomial!(exprs, syms, (3,1,1,) , NB5I.ISS14, :(out[24]))
   push_polynomial!(exprs, syms, (2,1,1,1,) , NB5I.ISS15, :(out[25]))
   push_polynomial!(exprs, syms, (5,1,) , NB5I.ISS16, :(out[26]))
   push_polynomial!(exprs, syms, (4,2,) , NB5I.ISS17, :(out[27]))
   push_polynomial!(exprs, syms, (3,3,) , NB5I.ISS18, :(out[28]))
   push_polynomial!(exprs, syms, (4,1,1,) , NB5I.ISS19, :(out[29]))
   push_polynomial!(exprs, syms, (3,2,1,) , NB5I.ISS20, :(out[30]))
   push_polynomial!(exprs, syms, (2,2,2,) , NB5I.ISS21, :(out[31]))
   push_polynomial!(exprs, syms, (4,1,1,) , NB5I.ISS22, :(out[32]))
   push_polynomial!(exprs, syms, (3,2,1,) , NB5I.ISS23, :(out[33]))
   push_polynomial!(exprs, syms, (4,1,1,) , NB5I.ISS24, :(out[34]))
   push_polynomial!(exprs, syms, (3,1,1,1,) , NB5I.ISS25, :(out[35]))
   push_polynomial!(exprs, syms, (2,2,1,1,) , NB5I.ISS26, :(out[36]))
   push_polynomial!(exprs, syms, (3,2,1,) , NB5I.ISS27, :(out[37]))
   push_polynomial!(exprs, syms, (7,) , NB5I.ISS28, :(out[38]))
   push_polynomial!(exprs, syms, (6,1,) , NB5I.ISS29, :(out[39]))
   push_polynomial!(exprs, syms, (5,2,) , NB5I.ISS30, :(out[40]))
   push_polynomial!(exprs, syms, (4,3,) , NB5I.ISS31, :(out[41]))
   push_polynomial!(exprs, syms, (5,1,1,) , NB5I.ISS32, :(out[42]))
   push_polynomial!(exprs, syms, (4,2,1,) , NB5I.ISS33, :(out[43]))
   push_polynomial!(exprs, syms, (3,3,1,) , NB5I.ISS34, :(out[44]))
   push_polynomial!(exprs, syms, (3,2,2,) , NB5I.ISS35, :(out[45]))
   push_polynomial!(exprs, syms, (5,1,1,) , NB5I.ISS36, :(out[46]))
   push_polynomial!(exprs, syms, (4,2,1,) , NB5I.ISS37, :(out[47]))
   push_polynomial!(exprs, syms, (3,3,1,) , NB5I.ISS38, :(out[48]))
   push_polynomial!(exprs, syms, (5,1,1,) , NB5I.ISS39, :(out[49]))
   push_polynomial!(exprs, syms, (4,1,1,1,) , NB5I.ISS40, :(out[50]))
   push_polynomial!(exprs, syms, (8,) , NB5I.ISS41, :(out[51]))
   push_polynomial!(exprs, syms, (7,1,) , NB5I.ISS42, :(out[52]))
   push_polynomial!(exprs, syms, (6,2,) , NB5I.ISS43, :(out[53]))
   push_polynomial!(exprs, syms, (5,3,) , NB5I.ISS44, :(out[54]))
   push_polynomial!(exprs, syms, (9,) , NB5I.ISS45, :(out[55]))
   push_polynomial!(exprs, syms, (8,1,) , NB5I.ISS46, :(out[56]))


   push!(exprs, :(return out))
   codeblock = Expr(:block, exprs...)

   quote
      $(Expr(:meta, :inline))
      @inbounds $codeblock
   end
end


end

using LinearAlgebra

const A20 = [ @SVector rand(20) for n = 1:10 ]
const A10 = [ @SVector rand(10) for n = 1:10 ]
const A56 = [ @SVector rand(56) for n = 1:10 ]
const X = [ @SVector rand(10) for n = 1:10 ]
function runN(f, A)
   s = 0.0
   for n = 1:length(A)
      s += dot(A[n], f(X[n]))
   end
   return s
end

@info("Old Invariants Code")
@btime runN($(Main.NB5I.invold), $A56)
@btime runN($(Main.NB5I.invold), $A56)

x = @SVector rand(10)
Main.NB5I.invnew(x) ≈ Main.NB5I.invold(x)

@info("New Invariants Code")
@btime runN($(Main.NB5I.invnew), $A56)
@btime runN($(Main.NB5I.invnew), $A56)


J = @MVector zeros(56)
Main.NB5I.invnew!(J, x) ≈ Main.NB5I.invold(x)
invnewin = let J=@MVector zeros(56)
   x -> Main.NB5I.invnew!(J, x)
end

@info("Inplace Invariants Code")
@btime runN($invnewin, $A56)
@btime runN($invnewin, $A56)



##

#
# @btime runN($invnewin, $x, 10)
#
# @info("New Invariants Inline")
# @btime Main.NB5I.invnew!($J, $x)
# @btime Main.NB5I.invnew!($J, $x)


# Main.NB5I.invstp(x) ≈ Main.NB5I.invold(x)
# @info("StaticPolynomials")
# @btime Main.NB5I.invstp($x)
# @btime Main.NB5I.invstp($x)
#
# Main.NB5I.invstp2(x) ≈ Main.NB5I.invold(x)
# @btime Main.NB5I.invstp2($x)
# @btime Main.NB5I.invstp2($x)

# using Profile
# f(ff, x) = (for n = 1:10_000_000; ff(x); end)
# @profile f(Main.NB5I.invstp, x)
# Profile.print()
