Section BR.
Inductive BR :=
| mkBR : R -> (R -> R -> R) -> (nat -> R) -> BR.
(** I need to define the notation outside again as wel **)
Notation "'{{' const ',' bop ',' fn  '}}'" :=
(mkBR const bop fn) (at level 30).
(** Semantics of evaluating a BR. It's too convenient to be able to `Opaque` and `Transparent` this to give it up *)
Definition evalBR (br: BR) (n: nat): R :=
match br with
| mkBR r0 binop f =>
let
vals : list R := map f (seq 1 n)
in
fold_left binop vals r0
end.
(** semantics of evaluating a BR *)
Global Instance loopVariantBR : LoopVariant BR R :=
{
evalAtIx (br: BR) (n: nat) := evalBR br n
}.
Class ToBR A : Type  :=
{
toBR : A -> BR
}.
Global Instance liftConstantToBR : ToBR R :=
{
toBR (c: R) := mkBR c plus (const zero)
}.
Global Instance liftBRToBR: ToBR BR :=
{
toBR br := br
}.

Lemma liftConstant_eval: forall (n: nat) (r: R),
evalAtIx (toBR r)  n = r.