(** THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS *)
(** [paper] *)
Require Import Primitives.
Import Primitives.
Require Import Coq.ZArith.ZArith.
Require Import List.
Import ListNotations.
Local Open Scope Primitives_scope.
Module Paper.

(** [paper::ref_incr]:
    Source: 'tests/src/paper.rs', lines 7:0-9:1
    Visibility: public *)
Definition ref_incr (x : i32) : result i32 :=
  i32_add x 1%i32.

(** [paper::test_incr]:
    Source: 'tests/src/paper.rs', lines 12:0-16:1
    Visibility: public *)
Definition test_incr : result unit :=
  x <- ref_incr 0%i32; massert (x s= 1%i32)
.

(** Unit test for [paper::test_incr] *)
Check (test_incr)%return.

(** [paper::choose]:
    Source: 'tests/src/paper.rs', lines 19:0-25:1
    Visibility: public *)
Definition choose
  {T : Type} (b : bool) (x : T) (y : T) : result (T * (T -> (T * T))) :=
  if b
  then let back := fun (x1 : T) => (x1, y) in Ok (x, back)
  else let back := fun (y1 : T) => (x, y1) in Ok (y, back)
.

(** [paper::test_choose]:
    Source: 'tests/src/paper.rs', lines 28:0-36:1
    Visibility: public *)
Definition test_choose : result unit :=
  p <- choose true 0%i32 0%i32;
  let (z, choose_back) := p in
  z1 <- i32_add z 1%i32;
  _ <- massert (z1 s= 1%i32);
  let (x, y) := choose_back z1 in
  _ <- massert (x s= 1%i32);
  massert (y s= 0%i32)
.

(** Unit test for [paper::test_choose] *)
Check (test_choose)%return.

(** [paper::List]
    Source: 'tests/src/paper.rs', lines 40:0-43:1
    Visibility: public *)
Inductive List_t (T : Type) :=
| List_Cons : T -> List_t T -> List_t T
| List_Nil : List_t T
.

Arguments List_Cons { _ }.
Arguments List_Nil { _ }.

(** [paper::list_nth_mut]:
    Source: 'tests/src/paper.rs', lines 47:0-60:1
    Visibility: public *)
Fixpoint list_nth_mut
  {T : Type} (l : List_t T) (i : u32) : result (T * (T -> List_t T)) :=
  match l with
  | List_Cons x tl =>
    if i s= 0%u32
    then let back := fun (t : T) => List_Cons t tl in Ok (x, back)
    else (
      i1 <- u32_sub i 1%u32;
      p <- list_nth_mut tl i1;
      let (x1, list_nth_mut_back) := p in
      let back :=
        fun (t : T) => let tl1 := list_nth_mut_back t in List_Cons x tl1
      in
      Ok (x1, back))
  | List_Nil => Fail_ Failure
  end
.

(** [paper::sum]:
    Source: 'tests/src/paper.rs', lines 62:0-71:1
    Visibility: public *)
Fixpoint sum (l : List_t i32) : result i32 :=
  match l with
  | List_Cons x tl => i <- sum tl; i32_add x i
  | List_Nil => Ok 0%i32
  end
.

(** [paper::test_nth]:
    Source: 'tests/src/paper.rs', lines 74:0-79:1
    Visibility: public *)
Definition test_nth : result unit :=
  p <-
    list_nth_mut (List_Cons 1%i32 (List_Cons 2%i32 (List_Cons 3%i32 List_Nil)))
      2%u32;
  let (x, list_nth_mut_back) := p in
  x1 <- i32_add x 1%i32;
  let l := list_nth_mut_back x1 in
  i <- sum l;
  massert (i s= 7%i32)
.

(** Unit test for [paper::test_nth] *)
Check (test_nth)%return.

(** [paper::call_choose]:
    Source: 'tests/src/paper.rs', lines 82:0-88:1
    Visibility: public *)
Definition call_choose (p : (u32 * u32)) : result u32 :=
  let (px, py) := p in
  p1 <- choose true px py;
  let (pz, choose_back) := p1 in
  pz1 <- u32_add pz 1%u32;
  let (px1, _) := choose_back pz1 in
  Ok px1
.

End Paper.
