Require Import binstretching.
Definition root_items : list N := ( [] )%N.
Definition lb_T := (
( nd []  5 [[
( nd [5]  3 [[
( nd [8]  3 [[
( lf [11] [10;10;10;10;9] [ [9;5]; [10;3]; [10;3]; [10]; [10] ]) ]]);
( nd [5;3]  3 [[
( lf [6;5] [14;14;14;14] [ [14]; [14]; [14]; [14]; [5;3;3] ]);
( nd [5;3;3]  3 [[
( lf [6;5;3] [14;14;14;14] [ [14]; [14]; [14]; [14]; [5;3;3;3] ]);
( nd [5;3;3;3]  2 [[
( nd [7;3;3;3]  4 [[
( nd [11;3;3;3]  2 [[
( nd [13;3;3;3]  6 [[
( lf [13;9;3;3] [10;10;10;10] [ [10;4]; [6;5;3]; [10;2;2]; [10;3]; [10;3] ]) ]]);
( nd [11;5;3;3]  3 [[
( lf [11;8;3;3] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [5;4;3;2]; [11;2] ]);
( lf [11;6;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [4;3;3;2] ]);
( lf [11;5;3;3;3] [8;8;8;8;8] [ [8;3;3]; [8;5]; [8;3;2]; [8;3;2]; [8;4] ]) ]]);
( lf [11;3;3;3;2] [9;9;9;9;8] [ [9;3;2]; [9;3;2]; [8;5]; [9;4]; [9;3] ]) ]]);
( nd [7;7;3;3]  2 [[
( nd [9;7;3;3]  4 [[
( nd [13;7;3;3]  6 [[
( nd [13;13;3;3]  6 [[
( lf [13;13;9;3] [10;10;10] [ [6;4;4]; [6;5;3]; [10;2;2]; [10;3]; [10;3] ]) ]]);
( lf [13;9;7;3] [12;12;12] [ [6;4;4]; [5;3;3;3]; [12;2]; [12;2]; [12] ]);
( nd [13;7;6;3;3]  6 [[
( lf [13;12;7;3;3] [8;8;8;8] [ [8;6]; [8;3;3]; [6;5;3]; [8;4;2]; [8;4;2] ]);
( lf [13;9;7;6;3] [13;13] [ [6;4;2;2]; [13]; [13]; [6;3;3]; [5;4;3] ]) ]]) ]]);
( lf [11;9;3;3] [10;10;10;10] [ [10;2;2]; [5;4;4]; [10;3]; [10;3]; [10;3] ]);
( lf [9;7;7;3] [12;12;12] [ [4;4;3;2]; [5;3;3;2]; [12]; [12]; [12] ]);
( nd [9;7;4;3;3]  2 [[
( lf [9;9;4;3;3] [10;10;10;10] [ [10;4]; [10;2;2]; [5;4;3;2]; [10;3]; [10;3] ]);
( lf [9;7;6;3;3] [13;13;13] [ [5;3;3;3]; [4;4;2;2;2]; [13]; [13]; [13] ]);
( lf [9;7;5;4;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;3]; [4;4;2;2;2] ]) ]]) ]]);
( lf [7;7;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;2;2]; [4;3;3] ]);
( nd [7;7;3;3;2]  4 [[
( nd [11;7;3;3;2]  2 [[
( nd [13;7;3;3;2]  6 [[
( lf [13;13;3;3;2] [9;9;9;8] [ [6;5;3]; [9;3;2]; [9;3;2]; [8;4;2]; [9;4] ]);
( lf [13;9;7;3;2] [12;12;12] [ [6;4;4]; [5;3;3;3]; [12;2]; [12;2]; [12;2] ]);
( lf [13;8;7;3;3] [12;12;12] [ [6;4;4]; [5;3;3;3]; [12;2]; [12;2]; [12;2] ]) ]]);
( lf [11;9;3;3;2] [10;10;10;10] [ [10;4]; [10;2;2]; [5;4;3;2]; [10;3]; [10;3] ]);
( lf [11;7;5;3;2] [14;14;14] [ [14]; [14]; [14]; [5;3;3;3]; [4;4;2;2;2] ]) ]]);
( lf [7;7;7;3;2] [12;12;12] [ [4;4;3;2]; [5;3;3;2]; [12]; [12]; [12] ]);
( lf [7;7;6;3;3] [13;13;13] [ [13]; [13]; [13]; [4;4;3;2]; [5;3;3;2] ]) ]]) ]]);
( nd [7;4;3;3;3]  2 [[
( nd [9;4;3;3;3]  6 [[
( lf [15;4;3;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;5]; [8;3;2] ]);
( lf [10;9;3;3;3] [10;10;10;10] [ [10;4]; [6;5;3]; [10;2;2]; [10;3]; [10;3] ]);
( lf [9;9;4;3;3] [10;10;10;10] [ [10;4]; [6;5;3]; [10;2;2]; [10;3]; [10;3] ]) ]]);
( nd [7;6;3;3;3]  6 [[
( lf [12;7;3;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;5]; [8;3;2] ]);
( lf [9;7;6;3;3] [13;13;13] [ [5;4;3;2]; [6;3;3;2]; [13]; [13]; [13] ]) ]]);
( nd [7;5;4;3;3]  6 [[
( lf [13;5;4;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;5]; [8;3;2] ]);
( lf [11;7;4;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;5]; [8;3;2] ]);
( lf [10;7;5;3;3] [14;14;14] [ [14]; [14]; [14]; [5;4;3;2]; [6;3;3;2] ]);
( lf [9;7;5;4;3] [14;14;14] [ [14]; [14]; [14]; [5;4;3;2]; [6;3;3;2] ]) ]]) ]]) ]]);
( nd [5;5;3;3]  2 [[
( nd [7;5;3;3]  2 [[
( nd [9;5;3;3]  1 [[
( nd [10;5;3;3]  2 [[
( nd [12;5;3;3]  2 [[
( nd [14;5;3;3]  5 [[
( lf [14;10;3;3] [10;10;10;9] [ [10;2;2]; [10;2;2]; [9;3;2]; [10;3;1]; [5;5;3] ]);
( nd [14;8;5;3]  6 [[
( nd [14;14;5;3]  5 [[
( lf [14;14;10;3] [10;10;9] [ [6;5;3]; [10;2;2]; [10;2;2]; [9;3;2]; [5;5;3;1] ]);
( lf [14;14;8;5] [14;14] [ [14]; [14]; [5;5;2;2]; [5;3;3;2;1]; [6;3;2;2] ]);
( lf [14;14;5;5;3] [14;14] [ [14]; [14]; [5;5;2;2]; [5;3;3;2;1]; [6;3;2;2] ]) ]]);
( lf [14;11;8;3] [11;11;11] [ [11;3]; [5;5;2;2]; [6;3;3;2]; [11;2;1]; [11;2] ]);
( lf [14;9;8;5] [14;14] [ [14]; [14]; [5;3;2;2]; [5;3;2;2]; [6;3;2;1] ]);
( lf [14;8;6;5;3] [14;14] [ [14]; [14]; [5;3;2;2]; [5;3;2;2]; [6;3;2;1] ]) ]]);
( nd [14;5;5;3;3]  7 [[
( lf [14;12;5;3;3] [8;8;8;8] [ [8;3;3]; [8;2;2;2]; [7;5;2]; [8;3;2;1]; [8;5] ]);
( lf [14;10;5;5;3] [14;14] [ [14]; [14]; [7;3;2;1]; [5;3;2;2]; [5;3;2;2] ]) ]]) ]]);
( nd [12;7;3;3]  7 [[
( nd [14;12;3;3]  7 [[
( lf [14;12;10;3] [10;10;9] [ [10;2;2]; [10;2;2]; [9;3;2]; [7;3;3]; [7;5;1] ]);
( nd [14;12;7;3;3]  7 [[
( lf [14;14;12;3;3] [8;8;8] [ [7;7]; [8;3;3]; [8;2;2;2]; [7;5;2]; [8;3;2;1] ]);
( lf [14;12;10;7;3] [12;12] [ [7;3;2;2]; [7;5;2]; [12;2]; [12;2]; [7;3;3;1] ]) ]]) ]]);
( lf [12;10;7;3] [12;12;12] [ [7;3;2;2]; [12;2]; [12;2]; [5;3;3;2]; [12;1] ]);
( lf [12;7;7;3;3] [12;12;12] [ [7;3;2;2]; [12;2]; [12;2]; [5;3;3;2]; [12;1] ]) ]]);
( lf [12;5;5;3] [14;14;14] [ [14]; [14]; [14]; [3;3;2;2;2;1]; [5;3;2;2] ]);
( lf [12;5;3;3;2] [9;9;9;9;8] [ [9;3;2]; [9;3;2]; [9;3;2]; [9;2;2;1]; [8;5] ]) ]]);
( nd [10;7;3;3]  3 [[
( nd [13;7;3;3]  6 [[
( nd [13;13;3;3]  6 [[
( lf [13;13;9;3] [10;10;10] [ [10;2;2]; [6;3;3;2]; [6;5;2;1]; [10;3]; [10;3] ]) ]]);
( lf [13;9;7;3] [12;12;12] [ [6;3;3;2]; [12;2]; [12;2]; [5;3;3;2]; [12;1] ]);
( nd [13;7;6;3;3]  6 [[
( lf [13;12;7;3;3] [8;8;8;8] [ [8;3;3]; [8;3;3]; [8;2;2;2]; [6;6;2]; [8;5;1] ]);
( lf [13;9;7;6;3] [13;13] [ [13]; [13]; [6;3;2;2]; [6;3;2;2]; [5;3;3;1] ]) ]]) ]]);
( lf [10;10;3;3] [10;10;10;9] [ [10;2;2]; [10;3]; [5;3;3;2]; [10;2;1]; [9;3] ]);
( lf [10;7;6;3] [13;13;13] [ [13]; [13]; [13]; [3;3;3;2;2]; [5;3;2;2;1] ]);
( nd [10;7;3;3;3]  4 [[
( lf [14;7;3;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;2;2;2]; [8;4;2]; [8;5;1] ]);
( lf [11;10;3;3;3] [9;9;9;9] [ [9;3;2]; [9;3;2]; [9;2;2]; [9;3;1]; [5;4;3] ]);
( lf [10;7;7;3;3] [12;12;12] [ [4;3;3;2;2]; [12;2]; [5;3;3;2]; [12;1]; [12] ]) ]]) ]]);
( lf [10;5;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;2;2]; [3;3;2;2;1] ]);
( lf [10;5;3;3;2] [9;9;9;9;9] [ [9;5]; [9;3;2]; [9;3;2]; [9;2;2]; [9;3;1] ]) ]]);
( nd [9;6;3;3]  3 [[
( nd [12;6;3;3]  7 [[
( nd [13;12;3;3]  7 [[
( lf [13;12;10;3] [10;10;9] [ [10;2;2]; [9;3;2]; [7;3;3]; [10;3]; [7;5;1] ]) ]]);
( nd [12;10;6;3]  9 [[
( lf [15;12;10;3] [10;10;9] [ [9;3;2]; [9;3;2]; [7;5;2]; [10;3;1]; [10;3] ]);
( lf [12;12;10;6] [13;13] [ [7;3;2;2]; [13]; [13]; [5;3;3;2]; [9;3;1] ]);
( lf [12;10;9;6;3] [13;13] [ [7;3;2;2]; [13]; [13]; [5;3;3;2]; [9;3;1] ]) ]]);
( nd [12;7;6;3;3]  7 [[
( lf [14;12;6;3;3] [8;8;8;8] [ [7;7]; [8;3;3]; [8;3;3]; [8;2;2;2]; [8;5;1] ]);
( lf [12;10;7;6;3] [13;13] [ [13]; [13]; [5;3;3;2]; [7;3;2;1]; [7;3;2] ]) ]]) ]]);
( lf [9;9;3;3] [10;10;10;10] [ [10;3]; [10;3]; [5;3;3;2]; [10;2;1]; [10;2] ]);
( lf [9;6;6;3] [13;13;13] [ [13]; [13]; [13]; [5;3;2;2]; [3;3;3;2;1] ]);
( nd [9;6;3;3;3]  5 [[
( lf [14;6;3;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;2;2;2]; [8;5;1]; [8;5] ]);
( lf [11;9;3;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;2;2;2]; [8;5;1]; [8;5] ]);
( lf [9;8;6;3;3] [13;13;13] [ [5;3;3;3]; [5;3;2;2;2]; [13;1]; [13]; [13] ]) ]]) ]]);
( nd [9;5;4;3]  3 [[
( nd [12;5;4;3]  7 [[
( nd [12;12;4;3]  7 [[
( lf [12;12;11;3] [10;10;9] [ [10;2;2]; [9;3;2]; [7;3;3]; [10;3]; [7;5;1] ]);
( lf [12;12;10;4] [10;10;9] [ [10;2;2]; [9;3;2]; [7;3;3]; [10;3]; [7;5;1] ]) ]]);
( nd [12;11;5;3]  9 [[
( lf [14;12;11;3] [10;10;9] [ [9;3;2]; [9;3;2]; [7;5;2]; [10;3;1]; [10;3] ]);
( lf [12;12;11;5] [14;14] [ [14]; [14]; [7;3;2;2]; [5;3;3;2]; [9;3;1] ]);
( lf [12;11;9;5;3] [14;14] [ [14]; [14]; [7;3;2;2]; [5;3;3;2]; [9;3;1] ]) ]]);
( nd [12;10;5;4]  9 [[
( lf [14;12;10;4] [10;10;9] [ [9;3;2]; [9;3;2]; [7;5;2]; [10;3;1]; [10;3] ]);
( lf [13;12;10;5] [14;14] [ [14]; [14]; [7;3;2;2]; [5;3;3;2]; [9;3;1] ]);
( lf [12;10;9;5;4] [14;14] [ [14]; [14]; [7;3;2;2]; [5;3;3;2]; [9;3;1] ]) ]]);
( nd [12;7;5;4;3]  7 [[
( lf [14;12;5;4;3] [8;8;8;8] [ [7;7]; [8;3;3]; [8;3;3]; [8;2;2;2]; [8;5;1] ]);
( lf [12;11;7;5;3] [14;14] [ [14]; [14]; [5;3;3;2]; [7;3;2;1]; [7;3;2] ]);
( lf [12;10;7;5;4] [14;14] [ [14]; [14]; [5;3;3;2]; [7;3;2;1]; [7;3;2] ]) ]]) ]]);
( lf [9;8;4;3] [11;11;11;11] [ [5;3;3;3]; [11;3]; [11;2;1]; [11;2]; [11;2] ]);
( lf [9;7;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;2;2]; [3;3;3;2;1] ]);
( lf [9;6;5;4] [14;14;14] [ [14]; [14]; [14]; [5;3;2;2]; [3;3;3;2;1] ]);
( nd [9;5;4;3;3]  4 [[
( lf [13;5;4;3;3] [8;8;8;8;8] [ [8;3;3]; [8;4;2]; [8;3;2;1]; [8;5]; [8;3;2] ]);
( lf [9;9;4;3;3] [10;10;10;10] [ [10;2;2]; [5;4;3;2]; [10;3;1]; [10;3]; [10;3] ]);
( lf [9;8;5;3;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;2]; [5;3;3;2;1] ]);
( lf [9;7;5;4;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;2]; [5;3;3;2;1] ]) ]]) ]]);
( nd [9;5;3;3;1]  4 [[
( lf [13;5;3;3;1] [9;9;9;9;9] [ [9;5]; [9;3;2]; [9;3;2]; [9;3;2]; [9;4;1] ]);
( lf [9;9;3;3;1] [10;10;10;10] [ [10;2;2]; [10;3]; [10;3]; [10;2;1]; [5;4;3] ]);
( lf [9;7;5;3;1] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;1]; [5;3;2;2] ]);
( lf [9;5;5;3;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;1]; [5;3;2;2] ]) ]]) ]]);
( lf [7;7;3;3] [12;12;12;12] [ [5;3;3;3]; [12;2]; [12;2]; [12;2]; [12] ]);
( lf [7;5;5;3] [14;14;14] [ [14]; [14]; [14]; [3;3;2;2]; [5;3;2] ]);
( nd [7;5;3;3;2]  5 [[
( nd [12;5;3;3;2]  9 [[
( nd [14;12;3;3;2]  9 [[  ]]);
( nd [12;12;5;3;2]  9 [[
( nd [12;12;12;5;2]  9 [[  ]]) ]]);
( nd [12;11;5;3;3]  9 [[  ]]) ]]);
( nd [10;7;3;3;2]  9 [[
( nd [16;10;3;3;2]  9 [[  ]]);
( nd [12;10;7;3;2]  9 [[
( nd [12;12;10;7;2]  9 [[  ]]) ]]);
( nd [11;10;7;3;3]  9 [[  ]]) ]]);
( nd [8;7;5;3;2]  14 [[
( nd [17;8;7;5;2]  14 [[  ]]);
( nd [16;8;7;5;3]  14 [[  ]]) ]]);
( nd [7;7;5;3;3]  14 [[
( nd [17;7;7;5;3]  14 [[
( lf [17;17;7;7;5]  [14] [ [14]; [14]; [14]; [5;3;3;2]; [5;3;2;2] ]) ]]) ]]) ]]) ]]);
( lf [5;5;5;3] [14;14;14] [ [14]; [14]; [14]; [3;3;2;2]; [5;3] ]);
( nd [5;5;3;3;2]  5 [[
( nd [10;5;3;3;2]  9 [[
( nd [14;10;3;3;2]  9 [[  ]]);
( nd [12;10;5;3;2]  9 [[
( nd [12;12;10;5;2]  14 [[
( lf [16;12;12;10;5]  [14] [ [14]; [14]; [9;3;2]; [9;3;2]; [5;5;3] ]) ]]) ]]);
( nd [11;10;5;3;3]  9 [[  ]]) ]]);
( nd [8;5;5;3;2]  14 [[
( nd [17;8;5;5;2]  14 [[  ]]);
( nd [16;8;5;5;3]  14 [[  ]]) ]]);
( lf [7;5;5;3;3] [14;14;14] [ [14]; [14]; [14]; [5;3;2;2]; [5;3;3] ]) ]]) ]]);
( nd [5;3;3;3;2]  1 [[
( nd [6;3;3;3;2]  2 [[
( nd [8;3;3;3;2]  6 [[
( lf [14;3;3;3;2] [9;9;9;9;8] [ [8;6]; [9;5]; [9;3;2]; [9;3;2]; [9;3;1] ]);
( lf [9;8;3;3;2] [11;11;11;11] [ [6;5;3]; [11;3]; [11;3]; [11;2;1]; [11;2] ]);
( lf [8;8;3;3;3] [11;11;11;11] [ [6;5;3]; [11;3]; [11;3]; [11;2;1]; [11;2] ]) ]]);
( nd [6;5;3;3;2]  5 [[
( nd [11;5;3;3;2]  9 [[
( nd [14;11;3;3;2]  9 [[  ]]);
( nd [12;11;5;3;2]  9 [[
( nd [12;12;11;5;2]  14 [[
( lf [16;12;12;11;5]  [14] [ [14]; [14]; [9;3;2]; [9;3;2]; [5;5;3;1] ]) ]]) ]]);
( nd [11;11;5;3;3]  9 [[  ]]) ]]);
( nd [10;6;3;3;2]  9 [[
( nd [15;10;3;3;2]  9 [[  ]]);
( nd [12;10;6;3;2]  9 [[
( nd [12;12;10;6;2]  14 [[
( lf [16;12;12;10;6]  [14] [ [14]; [14]; [9;3;2]; [9;3;2]; [5;5;3;1] ]) ]]) ]]);
( nd [11;10;6;3;3]  9 [[  ]]) ]]);
( nd [8;6;5;3;2]  14 [[
( nd [17;8;6;5;2]  14 [[  ]]);
( nd [16;8;6;5;3]  14 [[  ]]) ]]);
( lf [7;6;5;3;3] [14;14;14] [ [14]; [14]; [14]; [5;3;2;2]; [5;3;3;1] ]) ]]);
( nd [6;4;3;3;3]  6 [[
( lf [12;4;3;3;3] [8;8;8;8;8] [ [8;6]; [8;5]; [8;3;2]; [8;3;2]; [8;3;1] ]);
( nd [10;6;3;3;3]  4 [[
( lf [14;6;3;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;3;2;1]; [8;5] ]);
( lf [10;10;3;3;3] [9;9;9;9] [ [9;3;2]; [9;4]; [6;5;2]; [9;3;1]; [9;3] ]);
( lf [10;7;6;3;3] [13;13;13] [ [5;4;3;2]; [6;3;3;2]; [13;1]; [13]; [13] ]) ]]);
( nd [9;6;4;3;3]  4 [[
( lf [13;6;4;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;3;2;1]; [8;5] ]);
( lf [10;9;4;3;3] [10;10;10;10] [ [10;4]; [6;5;3]; [10;2;2]; [10;3;1]; [10;3] ]);
( lf [9;8;6;3;3] [13;13;13] [ [5;4;3;2]; [6;3;3;2]; [13;1]; [13]; [13] ]);
( lf [9;7;6;4;3] [13;13;13] [ [5;4;3;2]; [6;3;3;2]; [13;1]; [13]; [13] ]) ]]) ]]) ]]);
( nd [5;4;3;3;2]  5 [[
( lf [10;4;3;3;2] [9;9;9;9;9] [ [9;5]; [9;5]; [9;3;2]; [9;3;1]; [9;3] ]);
( nd [9;5;3;3;2]  4 [[
( lf [13;5;3;3;2] [9;9;9;9;8] [ [9;5]; [9;5]; [8;3;3]; [9;3;2]; [9;4;1] ]);
( lf [9;9;3;3;2] [10;10;10;10] [ [5;5;4]; [10;3]; [10;3]; [10;3]; [10;2;1] ]);
( lf [9;7;5;3;2] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [5;4;3;1] ]);
( lf [9;6;5;3;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [5;4;3;1] ]) ]]);
( nd [8;5;4;3;2]  4 [[
( lf [12;5;4;3;2] [9;9;9;9;8] [ [9;5]; [9;5]; [8;3;3]; [9;3;2]; [9;4;1] ]);
( lf [9;8;4;3;2] [11;11;11;11] [ [5;5;4]; [11;3]; [11;3]; [11;3]; [11;2;1] ]);
( lf [8;8;5;3;2] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [5;4;3;1] ]);
( lf [8;7;5;4;2] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [5;4;3;1] ]);
( lf [8;6;5;4;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [5;4;3;1] ]) ]]);
( nd [7;5;4;3;3]  6 [[
( lf [13;5;4;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;3;2;1]; [8;5]; [8;5] ]);
( lf [11;7;4;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;3;2;1]; [8;5]; [8;5] ]);
( lf [10;7;5;3;3] [14;14;14] [ [14]; [14]; [14]; [6;3;3;2]; [5;5;3;1] ]);
( lf [9;7;5;4;3] [14;14;14] [ [14]; [14]; [14]; [6;3;3;2]; [5;5;3;1] ]) ]]) ]]);
( nd [5;3;3;3;3]  6 [[
( lf [11;3;3;3;3] [8;8;8;8;8] [ [8;6]; [8;5]; [8;3;2]; [8;3;1]; [8;3] ]);
( nd [9;5;3;3;3]  4 [[
( lf [13;5;3;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;5]; [8;3;2]; [8;4;1] ]);
( lf [9;9;3;3;3] [10;10;10;10] [ [10;4]; [6;5;2;1]; [10;3]; [10;3]; [10;3] ]);
( lf [9;7;5;3;3] [14;14;14] [ [14]; [14]; [14]; [5;4;3;2]; [6;3;3;1] ]) ]]) ]]) ]]) ]]) ]]) ]]) ]]) ]]))%N
.

(* Record list. *)
Definition lb_R_1 : RecordN := (
[recN [9;9;5;5;3;3;3;2;2;1] (
( nd [15;11;10;3;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;1] (
( nd [15;12;10;3;2]  9 [[
( nd [15;12;12;10;2]  9 [[  ]]) ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;1] (
( nd [14;11;11;3;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;1] (
( nd [14;12;11;3;2]  9 [[
( nd [14;12;12;11;2]  9 [[  ]]) ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2] (
( nd [14;11;10;3;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2] (
( nd [14;12;10;3;2]  9 [[
( nd [14;12;12;10;2]  9 [[  ]]) ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;2] (
( nd [12;11;10;7;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;2] (
( nd [16;11;10;3;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;2] (
( nd [16;12;10;3;2]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;2] (
( nd [12;12;11;5;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;2] (
( nd [14;12;11;3;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;2] (
( nd [14;12;12;3;2]  9 [[  ]])
); (* End of record entry. *)
recN [5;3;3] (
( nd [8;3]  3 [[
( lf [11;3] [10;10;10;10;9] [ [9;5]; [10;3]; [10;3]; [10;3]; [10] ]);
( lf [8;6] [14;14;14;14] [ [14]; [14]; [14]; [14]; [5;3;3;3] ]) ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;1] (
( nd [15;12;11;10;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;1] (
( nd [14;12;11;11;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2] (
( nd [14;12;11;10;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;2] (
( nd [16;12;11;10;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;2] (
( nd [16;12;12;10;2]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;2] (
( nd [14;12;12;11;3]  9 [[  ]])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;2] (
( nd [14;12;12;12;2]  9 [[  ]])
); (* End of record entry. *)
recN [5;3;3;3] (
( nd [8;3;3]  3 [[
( lf [11;3;3] [10;10;10;10;9] [ [9;5]; [10;3]; [10;3]; [10;3]; [10;3] ]);
( nd [8;6;3]  1 [[
( nd [9;6;3]  5 [[
( nd [14;6;3]  6 [[
( lf [14;12;3] [10;10;10;9] [ [9;5]; [6;5;3]; [10;3;1]; [10;3]; [10;3] ]);
( lf [14;9;6] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ]);
( lf [14;6;6;3] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ]) ]]);
( lf [11;9;3] [10;10;10;10] [ [5;5;3]; [10;3]; [10;3]; [10;3]; [10;1] ]);
( lf [9;6;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;1]; [5;3;3] ]) ]]);
( nd [8;7;3]  5 [[
( nd [13;7;3]  6 [[
( lf [13;13;3] [10;10;10;9] [ [9;5]; [6;5;3]; [10;3;1]; [10;3]; [10;3] ]);
( lf [13;9;7] [12;12;12] [ [5;3;3;3]; [6;5;3]; [12;1]; [12]; [12] ]) ]]);
( lf [12;8;3] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [5;5;3]; [11;1] ]);
( lf [8;8;7] [12;12;12] [ [12]; [12]; [12]; [5;3;3;1]; [5;3;3] ]);
( lf [8;7;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;1]; [5;3;3] ]) ]]);
( nd [8;6;4]  5 [[
( nd [13;6;4]  6 [[
( lf [13;12;4] [10;10;10;9] [ [9;5]; [6;5;3]; [10;3;1]; [10;3]; [10;3] ]);
( lf [13;10;6] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ]);
( lf [13;6;6;4] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ]) ]]);
( lf [11;8;4] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [5;5;3]; [11;1] ]);
( lf [8;6;5;4] [14;14;14] [ [14]; [14]; [14]; [5;3;3;1]; [5;3;3] ]) ]]);
( nd [8;6;3;1]  5 [[
( nd [13;6;3;1]  6 [[
( lf [13;12;3;1] [10;10;10;9] [ [9;5]; [6;5;3]; [10;3;1]; [10;3]; [10;3] ]);
( lf [13;9;6;1] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ]);
( lf [13;6;6;3;1] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ]) ]]);
( lf [11;8;3;1] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [5;5;3]; [11;1] ]);
( lf [8;8;6;1] [13;13;13] [ [13]; [13]; [13]; [5;3;3;1]; [5;3;3] ]);
( lf [8;6;6;3] [13;13;13] [ [13]; [13]; [13]; [5;3;3;1]; [5;3;3] ]);
( lf [8;6;5;3;1] [14;14;14] [ [14]; [14]; [14]; [5;3;3;1]; [5;3;3] ]) ]]) ]]);
( nd [8;3;3;3]  2 [[
( nd [10;3;3;3]  2 [[
( nd [12;3;3;3]  8 [[
( lf [12;11;3;3] [10;10;10;9] [ [9;5]; [8;3;3]; [10;2;2]; [10;3]; [10;3] ]);
( nd [12;8;3;3;3]  7 [[
( nd [15;12;3;3;3]  7 [[
( lf [15;12;10;3;3] [9;9;9] [ [7;7]; [9;5]; [8;3;3]; [9;3;2]; [9;3;2] ]) ]]);
( lf [12;10;8;3;3] [11;11;11] [ [8;3;3]; [11;3]; [11;3]; [7;5;2]; [11;2] ]) ]]) ]]);
( nd [10;5;3;3]  4 [[
( lf [10;9;3;3] [10;10;10;10] [ [10;2;2]; [10;3]; [10;3]; [10;3]; [5;4;3] ]);
( lf [10;7;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [4;3;3;2] ]);
( nd [10;5;4;3;3]  2 [[
( lf [12;5;4;3;3] [8;8;8;8;8] [ [8;3;3]; [8;4;2]; [8;5]; [8;3;2]; [8;3;2] ]);
( nd [10;7;4;3;3]  2 [[
( lf [12;7;4;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;2;2;2]; [8;4;2]; [8;5] ]);
( lf [10;9;4;3;3] [10;10;10;10] [ [10;4]; [5;3;3;3]; [10;2;2]; [10;2;2]; [10;3] ]);
( nd [10;7;6;3;3]  3 [[
( nd [13;7;6;3;3]  6 [[
( lf [13;13;6;3;3] [8;8;8;8] [ [8;3;3]; [8;3;3]; [6;5;3]; [8;2;2;2]; [8;4;2] ]);
( lf [13;12;7;3;3] [8;8;8;8] [ [8;3;3]; [8;3;3]; [6;5;3]; [8;2;2;2]; [8;4;2] ]);
( lf [13;9;7;6;3] [13;13] [ [13]; [13]; [6;3;2;2]; [5;3;3;2]; [4;3;3;2] ]) ]]);
( lf [10;10;6;3;3] [9;9;9;9] [ [9;3;2]; [9;3;2]; [9;3;2]; [9;3;2]; [5;4;3] ]);
( lf [10;9;7;3;3] [12;12;12] [ [12;2]; [12;2]; [12;2]; [4;3;3;3]; [5;3;3;2] ]);
( lf [10;7;6;6;3] [13;13] [ [13]; [13]; [4;3;2;2]; [3;3;3;2]; [5;3;2] ]) ]]);
( nd [10;7;5;4;3]  3 [[
( nd [13;7;5;4;3]  6 [[
( lf [13;13;5;4;3] [8;8;8;8] [ [8;3;3]; [8;3;3]; [6;5;3]; [8;2;2;2]; [8;4;2] ]);
( lf [13;11;7;4;3] [8;8;8;8] [ [8;3;3]; [8;3;3]; [6;5;3]; [8;2;2;2]; [8;4;2] ]);
( lf [13;10;7;5;3] [14;14] [ [14]; [14]; [6;3;2;2]; [5;3;3;2]; [4;3;3;2] ]);
( lf [13;9;7;5;4] [14;14] [ [14]; [14]; [6;3;2;2]; [5;3;3;2]; [4;3;3;2] ]) ]]);
( lf [10;10;5;4;3] [9;9;9;9] [ [9;3;2]; [9;3;2]; [9;3;2]; [9;3;2]; [5;4;3] ]);
( lf [10;8;7;4;3] [12;12;12] [ [12;2]; [12;2]; [12;2]; [4;3;3;3]; [5;3;3;2] ]);
( lf [10;7;7;5;3] [14;14] [ [14]; [14]; [4;3;2;2]; [3;3;3;2]; [5;3;2] ]);
( lf [10;7;6;5;4] [14;14] [ [14]; [14]; [4;3;2;2]; [3;3;3;2]; [5;3;2] ]) ]]) ]]);
( lf [10;6;5;3;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;2]; [5;3;3;2] ]);
( lf [10;5;5;4;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;2]; [5;3;3;2] ]) ]]) ]]);
( lf [10;3;3;3;2] [9;9;9;9;9] [ [9;5]; [9;3;2]; [9;3;2]; [9;3]; [9;3] ]) ]]);
( nd [8;5;3;3]  4 [[
( nd [12;5;3;3]  2 [[
( nd [12;7;3;3]  2 [[
( nd [14;7;3;3]  7 [[
( nd [14;14;3;3]  7 [[
( lf [14;14;10;3] [10;10;9] [ [7;7]; [10;4]; [5;3;3;3]; [10;2;2]; [9;3;2] ]);
( nd [14;14;7;3;3]  5 [[
( lf [14;14;12;3;3] [8;8;8] [ [8;3;3]; [8;3;3]; [8;4;2]; [7;5;2]; [7;5;2] ]);
( lf [14;14;8;7;3] [12;12] [ [5;3;3;3]; [7;4;3]; [7;5;2]; [12;2]; [12;2] ]) ]]) ]]);
( lf [14;10;7;3] [12;12;12] [ [5;3;3;3]; [7;4;3]; [12;2]; [12;2]; [12;2] ]);
( lf [14;7;7;3;3] [12;12;12] [ [5;3;3;3]; [7;4;3]; [12;2]; [12;2]; [12;2] ]) ]]);
( lf [12;9;3;3] [10;10;10;10] [ [10;2;2]; [5;4;3;2]; [10;3]; [10;3]; [10;3] ]);
( lf [12;7;5;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2;2]; [5;3;3;2] ]);
( nd [12;7;3;3;2]  7 [[
( lf [14;12;3;3;2] [9;9;9;8] [ [8;3;3]; [9;3;2]; [9;3;2]; [7;5;2]; [9;4] ]);
( lf [12;10;7;3;2] [12;12;12] [ [5;3;3;3]; [7;4;3]; [12;2]; [12;2]; [12;2] ]);
( lf [12;9;7;3;3] [12;12;12] [ [5;3;3;3]; [7;4;3]; [12;2]; [12;2]; [12;2] ]) ]]) ]]);
( lf [12;5;5;3] [14;14;14] [ [14]; [14]; [14]; [5;3;3;2]; [4;3;3;2] ]);
( lf [12;5;3;3;2] [9;9;9;9;8] [ [9;5]; [8;3;3]; [9;3;2]; [9;3;2]; [9;4] ]) ]]);
( lf [9;8;3;3] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [11;2]; [5;4;3] ]);
( lf [8;7;5;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;2]; [5;3;3] ]);
( nd [8;5;4;3;3]  3 [[
( lf [11;5;4;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;5]; [8;3;2]; [8;4] ]);
( lf [8;8;4;3;3] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [11;3]; [5;4;3;2] ]);
( lf [8;7;5;3;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;3]; [5;3;3;2] ]);
( lf [8;6;5;4;3] [14;14;14] [ [14]; [14]; [14]; [4;3;3;3]; [5;3;3;2] ]) ]]) ]]);
( nd [8;3;3;3;2]  5 [[
( lf [13;3;3;3;2] [9;9;9;9;8] [ [9;5]; [9;5]; [8;3;3]; [9;3;2]; [9;3] ]);
( lf [8;8;3;3;2] [11;11;11;11] [ [11;3]; [11;3]; [11;3]; [5;5;3]; [11;2] ]);
( nd [8;7;3;3;3]  4 [[
( lf [12;7;3;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;4;2]; [8;5]; [8;5] ]);
( lf [11;8;3;3;3] [8;8;8;8;8] [ [8;3;3]; [8;3;3]; [8;4;2]; [8;5]; [8;5] ]);
( lf [8;7;7;3;3] [12;12;12] [ [5;3;3;3]; [5;4;3;2]; [12]; [12]; [12] ]) ]]) ]]) ]]) ]])
); (* End of record entry. *)
recN [14;14;5;5;3;3;3;2;2;1] (
( lf [17;16;8;6;5]  [14] [ [14]; [14]; [14]; [5;3;2;2]; [5;3;3;1] ])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;1] (
( nd [12;11;10;6;3]  14 [[
( lf [17;12;11;10;6]  [14] [ [14]; [14]; [9;3;2]; [9;3;2]; [5;5;3;1] ]) ]])
); (* End of record entry. *)
recN [9;9;9;9;5;5;3;3;3;2;2;1] (
( lf [15;12;12;11;10]  [9] [ [9;5]; [9;5]; [9;3;2]; [9;3;2]; [9;3;1] ])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2;1] (
( nd [12;11;11;5;3]  14 [[
( lf [17;12;11;11;5]  [14] [ [14]; [14]; [9;3;2]; [9;3;2]; [5;5;3;1] ]) ]])
); (* End of record entry. *)
recN [9;9;9;9;5;5;3;3;3;2;2;1] (
( lf [14;12;12;11;11]  [9] [ [9;5]; [9;5]; [9;3;2]; [9;3;2]; [9;3;1] ])
); (* End of record entry. *)
recN [14;14;5;5;3;3;3;2;2] (
( lf [17;16;8;5;5]  [14] [ [14]; [14]; [14]; [5;3;2;2]; [5;3;3] ])
); (* End of record entry. *)
recN [9;9;5;5;3;3;3;2;2] (
( nd [12;11;10;5;3]  14 [[
( lf [17;12;11;10;5]  [14] [ [14]; [14]; [9;3;2]; [9;3;2]; [5;5;3] ]) ]])
); (* End of record entry. *)
recN [9;9;9;9;5;5;3;3;3;2;2] (
( lf [14;12;12;11;10]  [9] [ [9;5]; [9;5]; [9;3;2]; [9;3;2]; [9;3] ])
); (* End of record entry. *)
recN [14;14;5;5;3;3;3;2;2;2] (
( lf [17;16;8;7;5]  [14] [ [14]; [14]; [14]; [5;3;3;2]; [5;3;2;2] ])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;2] (
( lf [12;12;11;10;7]  [14] [ [14]; [5;5;2;2]; [9;3;2]; [9;3]; [9;3] ])
); (* End of record entry. *)
recN [9;9;9;9;5;5;3;3;3;2;2;2] (
( lf [16;12;12;11;10]  [9] [ [9;5]; [9;5]; [9;3;2]; [9;3;2]; [9;3;2] ])
); (* End of record entry. *)
recN [9;9;9;5;5;3;3;3;2;2;2] (
( lf [12;12;12;11;5]  [14] [ [14]; [5;5;2;2]; [9;3;2]; [9;3]; [9;3] ])
); (* End of record entry. *)
recN [9;9;9;9;5;5;3;3;3;2;2;2] (
( lf [14;12;12;12;11]  [9] [ [9;5]; [9;5]; [9;3;2]; [9;3;2]; [9;3;2] ])
); (* End of record entry. *)
recN [7;7;5;3;3;3;3;2;2;2;1] (
( lf [12;12;7;4;3] [8;8;8;8] [ [7;7]; [8;3;3]; [8;3;3]; [8;2;2;2]; [8;5;1] ])
); (* End of record entry. *)
recN [7;7;5;3;3;3;3;2;2;2;1] (
( lf [13;12;7;3;3] [8;8;8;8] [ [7;7]; [8;3;3]; [8;3;3]; [8;2;2;2]; [8;5;1] ])
); (* End of record entry. *)
recN [6;6;5;3;3;3;3;2;2;2;2;1] (
( lf [13;13;6;3;3] [8;8;8;8] [ [8;3;3]; [8;3;3]; [8;2;2;2]; [6;6;2]; [8;5;1] ])
); (* End of record entry. *)
recN [5;4;4;3;3;3;2;2;2] (
( lf [11;7;4;3;3] [8;8;8;8;8] [ [8;3;3]; [8;4;2]; [8;4;2]; [8;5]; [8;3;2] ])
); (* End of record entry. *)
recN [6;6;5;4;4;3;3;3;2;2] (
( lf [13;13;6;3;3] [8;8;8;8] [ [8;6]; [8;3;3]; [6;5;3]; [8;4;2]; [8;4;2] ])
); (* End of record entry. *)
recN [6;5;4;3;3;3;2;2] (
( lf [13;6;3;3;3] [8;8;8;8;8] [ [8;6]; [8;3;3]; [8;4;2]; [8;5]; [8;3;2] ])
); (* End of record entry. *)
recN [5;4;3;3;3;3;2;2] (
( nd [14;5;3;3]  6 [[
( nd [14;11;3;3]  10 [[
( nd [14;13;11;3]  10 [[
( nd [14;13;13;11]  11 [[
( lf [14;13;13;11;11] [8] [ [10;4]; [8;3;3]; [6;5;3]; [11;3]; [10;2;2] ]) ]]);
( lf [14;13;11;10;3] [9;9] [ [10;4]; [6;5;3]; [9;3;2]; [9;3;2]; [10;3] ]) ]]);
( lf [14;11;10;3;3] [9;9;9] [ [6;5;3]; [9;3;2]; [9;3;2]; [9;4]; [10;3] ]) ]]);
( nd [14;9;5;3]  5 [[
( nd [14;14;5;3]  5 [[
( lf [14;14;10;3] [10;10;9] [ [9;5]; [10;4]; [5;3;3;3]; [6;5;3]; [10;2;2] ]);
( lf [14;14;8;5] [14;14] [ [14]; [14]; [5;4;3;2]; [6;3;3;2]; [5;5;3] ]);
( lf [14;14;5;5;3] [14;14] [ [14]; [14]; [5;4;3;2]; [6;3;3;2]; [5;5;3] ]) ]]);
( lf [14;10;9;3] [10;10;10] [ [10;2;2]; [6;4;3]; [5;5;3]; [10;3]; [10;3] ]);
( lf [14;9;8;5] [14;14] [ [14]; [14]; [5;4;2;2]; [6;3;3]; [5;3;3] ]);
( lf [14;9;5;5;3] [14;14] [ [14]; [14]; [5;4;2;2]; [6;3;3]; [5;3;3] ]) ]]);
( nd [14;6;5;3;3]  7 [[
( lf [14;13;5;3;3] [8;8;8;8] [ [8;6]; [8;3;3]; [8;3;3]; [8;4;2]; [7;5;2] ]);
( lf [14;12;6;3;3] [8;8;8;8] [ [8;6]; [8;3;3]; [8;3;3]; [8;4;2]; [7;5;2] ]);
( lf [14;10;6;5;3] [14;14] [ [14]; [14]; [7;3;2;2]; [6;3;3]; [5;4;3] ]) ]]) ]])
); (* End of record entry. *)
recN [6;5;5;3;3;3;3;1] (
( lf [13;7;6;3] [13;13;13] [ [5;3;3;3]; [6;5;3]; [13;1]; [13]; [13] ])
); (* End of record entry. *)
recN [5;5;3;3;3;3;1] (
( lf [9;8;6] [13;13;13] [ [13]; [13]; [13]; [5;3;3;1]; [5;3;3] ])
)])%N.

Definition lb_R : RecordN := (lb_R_1)%N.


Load LFindLoad.
From lfind Require Import LFind.
From QuickChick Require Import QuickChick.
From adtind Require Import goal33.

Derive Show for natural.

              Derive Arbitrary for natural.

              Instance Dec_Eq_natural : Dec_Eq natural.

              Proof. dec_eq. Qed.

Lemma conj4synthconj2 : forall  (lv0 : natural), (@eq natural (plus Zero (plus lv0 Zero)) lv0).
Admitted.
QuickChick conj4synthconj2.


Require Import Coq.Strings.String.
Require Import Coq.micromega.Lia.
Require Import Poulet4.P4light.Syntax.Typed.
Require Import Poulet4.P4light.Syntax.Syntax.
Require Import Poulet4.P4light.Syntax.Value.
Require Import Poulet4.P4light.Semantics.Semantics.
Require Import Poulet4.P4light.Architecture.V1ModelTarget.
Require Import Poulet4.P4light.Syntax.P4Notations.
Require Import Poulet4.Utils.P4Arith.
Require Import ProD3.core.Coqlib.
Require Import ProD3.core.Hoare.
Require Import ProD3.core.Modifies.
Require Import ProD3.core.FuncSpec.
Require Import ProD3.core.AssertionNotations.
Require Import ProD3.core.ExtPred.
Require Import BinNat.
Require Import BinInt.
Open Scope Z_scope.
(* Require Import Hammer.Tactics.Tactics.
Require Import Hammer.Plugin.Hammer. *)

Section V1ModelSpec.

Context [tags_t: Type] [tags_t_inhabitant : Inhabitant tags_t].
Notation Val := (@ValueBase bool).
Notation Sval := (@ValueBase (option bool)).
(* Notation ValSet := (@ValueSet tags_t). *)
Notation Lval := ValueLvalue.

Notation ident := string.
Notation path := (list ident).
Notation Expression := (@Expression tags_t).
Notation argument := (@argument tags_t).

Instance target : @Target tags_t Expression := V1Model.

Variable ge : genv.

Open Scope func_spec.

Definition register_read_spec (p : path) (reg_s : register_static) : func_spec :=
  WITH,
    PATH p
    MOD None []
    WITH (reg : register) (i : Z) (H : (0 <= i < snd reg_s)%Z)
    (HR: snd reg_s <= 2 ^ 32),
      PRE
        (ARG [ValBaseBit (to_loptbool 32%N i)]
        (MEM []
        (EXT [ExtPred.singleton p (ObjRegister reg)])))
      POST
        (ARG_RET [eval_val_to_sval (Znth i reg)] ValBaseNull
        (MEM []
        (EXT []))).

Lemma register_read_body : forall (p : path) (reg_s : register_static),
  PathMap.get p (ge_ext ge) = Some (EnvRegister reg_s) ->
  func_sound ge (FExternal "register" "read") nil (register_read_spec p reg_s).
Proof.
  intros. unfold register_read_spec. simpl. split; repeat intro.
  - red in H0. destruct H0. do 2 red in H0. inv H0. inv H7. inv H5. red. inv H1.
    inv H5. inv H7. inv H4. inv H8. simpl in H0. inv H0. simpl. red.
    split; [|split]; auto.
    + inv H14. inv H10. apply Members.Forall2_bit_refine_Some_same' in H3.
      subst. apply Forall2_ndetbit in H1. subst. rewrite bit_from_to_bool in H7.
      constructor. 2: constructor. destruct H2. red in H1. red in H1. simpl in H1.
      destruct H1. simpl in H1. rewrite H6 in H1. inv H1. simpl in H. rewrite H in H5. inv H5.
      simpl in x1. assert ((-1 <? index) && (index <? size) = true). {
        apply andb_true_intro. pose proof (BitArith.upper_bound_ge_1 32). split.
        - rewrite Z.ltb_lt. cut (0 <= index < BitArith.upper_bound 32).
          1: intros; lia. inv H7. unfold BitArith.mod_bound. apply Zdiv.Z_mod_lt. lia.
        - rewrite Z.ltb_lt. cut (index <= x0). 1: lia. inv H7.
          unfold BitArith.mod_bound. apply Zdiv.Zmod_le; lia. } rewrite H1 in H11.
      subst. rewrite val_to_sval_iff in H8. inversion H7. subst index. simpl in x2.
      clear -H8 x1 x2. unfold BitArith.mod_bound, BitArith.upper_bound in H8.
      change (2 ^ Z.of_N 32) with (Z.pow_pos 2 32) in H8.
      rewrite Zdiv.Zmod_small in H8 by lia. rewrite H8.
      apply SvalRefine.sval_refine_refl.
    + repeat intro. inv H0. constructor.
    + destruct H2; split; auto.
  - red. split; simpl; auto. repeat intro. inv H0. simpl. inv H7. simpl in H0. inv H0. auto.
Qed.

(* We need to say v is a definite value, right? *)
Definition register_write_spec (p : path) (reg_s : register_static) : func_spec :=
  WITH,
    PATH p
    MOD None [p]
    WITH (reg : register) (i : Z) (v : Val) (H : (0 <= i < snd reg_s)%Z)
    (HR: snd reg_s <= 2 ^ 32),
      PRE
        (ARG [ValBaseBit (to_loptbool 32%N i); eval_val_to_sval v]
        (MEM []
        (EXT [ExtPred.singleton p (ObjRegister reg)])))
      POST
        (ARG_RET [] ValBaseNull
        (MEM []
        (EXT [ExtPred.singleton p (ObjRegister (upd_Znth i reg v))]))).

Lemma register_write_body : forall (p : path) (reg_s : register_static),
  PathMap.get p (ge_ext ge) = Some (EnvRegister reg_s) ->
  func_sound ge (FExternal "register" "write") nil (register_write_spec p reg_s).
Proof.
  intros. unfold register_write_spec. simpl. split; repeat intro.
  - red in H0. destruct H0. do 2 red in H0. inv H0. inv H7. inv H8. inv H5.
    inv H1. inv H6. inv H8. inv H10. inv H5. simpl in H9. inv H9. simpl in H0.
    inv H0. simpl in H. rewrite H in H8. clear H. inv H8. simpl in *. red.
    split; [|split].
    + inv H15. constructor.
    + repeat intro. inv H. constructor.
    + red. destruct H2. split; auto. red. red. simpl. split; auto.
      apply Members.Forall2_bit_refine_Some_same' in H3. subst.
      apply Forall2_ndetbit in H1. subst. rewrite bit_from_to_bool in H14.
      assert ((-1 <? index) && (index <? size) = true). {
        apply andb_true_intro. pose proof (BitArith.upper_bound_ge_1 32). split.
        - rewrite Z.ltb_lt. cut (0 <= index < BitArith.upper_bound 32).
          1: intros; lia. inv H14. unfold BitArith.mod_bound. apply Zdiv.Z_mod_lt. lia.
        - rewrite Z.ltb_lt. cut (index <= x0). 1: lia. inv H14.
          unfold BitArith.mod_bound. apply Zdiv.Zmod_le; lia. } rewrite H1 in H16.
      subst. simpl. rewrite PathMap.get_set_same. f_equal.
      apply exec_val_eval_val_to_sval_eq in H4. 2: intros s1 s2 Hs; now inv Hs.
      subst. apply sval_to_val_eval_val_to_sval_eq in H6.
      2: intros s1 s2 Hs; now inv Hs. subst x1. do 2 red in H0. simpl in H0.
      destruct H0 as [? _]. simpl in H0. rewrite H9 in H0. inv H0. inv H14.
      unfold BitArith.mod_bound, BitArith.upper_bound.
      change (2 ^ Z.of_N 32) with (Z.pow_pos 2 32).
      rewrite Zdiv.Zmod_small by lia. auto.
  - red. split; simpl; auto. repeat intro. inv H0. simpl. inv H7. simpl in H0. inv H0.
    destruct ((-1 <? index) && (index <? size)); subst; auto.
    rewrite PathMap.get_set_diff; auto. intro. apply H1. subst.
    apply in_scopes_In. now left.
Qed.

End V1ModelSpec.

#[export] Hint Extern 5 (func_modifies _ _ _ _ _) =>
  (refine (proj2 (register_read_body _ _ _ _)); reflexivity) : func_specs.
#[export] Hint Extern 5 (func_modifies _ _ _ _ _) =>
  (refine (proj2 (register_write_body _ _ _ _)); reflexivity) : func_specs.

(*
Several issues:
- out of bounds for i
- to_lbool/to_loptbool is N-to-1 mapping, diffcult to automate
=> also a problem in semantics.v
- are v and i assumed to be bounded in post_condition?
*)