(* Generated by coq-of-rust *)
Require Import CoqOfRust.CoqOfRust.

(*
fn main() {
    // `n` will take the values: 1, 2, ..., 100 in each iteration
    for n in 1..101 {
        if n % 15 == 0 {
            println!("fizzbuzz");
        } else if n % 3 == 0 {
            println!("fizz");
        } else if n % 5 == 0 {
            println!("buzz");
        } else {
            println!("{}", n);
        }
    }
}
*)
Definition main (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
  match ε, τ, α with
  | [], [], [] =>
    ltac:(M.monadic
      (M.read (|
        M.use
          (M.match_operator (|
            M.alloc (|
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::collect::IntoIterator",
                  Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "i32" ],
                  [],
                  "into_iter",
                  []
                |),
                [
                  Value.StructRecord
                    "core::ops::range::Range"
                    [
                      ("start", Value.Integer IntegerKind.I32 1);
                      ("end_", Value.Integer IntegerKind.I32 101)
                    ]
                ]
              |)
            |),
            [
              fun γ =>
                ltac:(M.monadic
                  (let iter := M.copy (| γ |) in
                  M.loop (|
                    ltac:(M.monadic
                      (let~ _ :=
                        M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::iterator::Iterator",
                                Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "i32" ],
                                [],
                                "next",
                                []
                              |),
                              [ iter ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |)));
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::option::Option::Some",
                                    0
                                  |) in
                                let n := M.copy (| γ0_0 |) in
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ :=
                                          M.use
                                            (M.alloc (|
                                              BinOp.eq (|
                                                BinOp.Wrap.rem (|
                                                  M.read (| n |),
                                                  Value.Integer IntegerKind.I32 15
                                                |),
                                                Value.Integer IntegerKind.I32 0
                                              |)
                                            |)) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        let~ _ :=
                                          let~ _ :=
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_function (| "std::io::stdio::_print", [] |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.path "core::fmt::Arguments",
                                                      "new_const",
                                                      []
                                                    |),
                                                    [
                                                      M.alloc (|
                                                        Value.Array
                                                          [ M.read (| Value.String "fizzbuzz
" |) ]
                                                      |)
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            |) in
                                          M.alloc (| Value.Tuple [] |) in
                                        M.alloc (| Value.Tuple [] |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ :=
                                                  M.use
                                                    (M.alloc (|
                                                      BinOp.eq (|
                                                        BinOp.Wrap.rem (|
                                                          M.read (| n |),
                                                          Value.Integer IntegerKind.I32 3
                                                        |),
                                                        Value.Integer IntegerKind.I32 0
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  let~ _ :=
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_function (|
                                                          "std::io::stdio::_print",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "core::fmt::Arguments",
                                                              "new_const",
                                                              []
                                                            |),
                                                            [
                                                              M.alloc (|
                                                                Value.Array
                                                                  [
                                                                    M.read (|
                                                                      Value.String "fizz
"
                                                                    |)
                                                                  ]
                                                              |)
                                                            ]
                                                          |)
                                                        ]
                                                      |)
                                                    |) in
                                                  M.alloc (| Value.Tuple [] |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ :=
                                                          M.use
                                                            (M.alloc (|
                                                              BinOp.eq (|
                                                                BinOp.Wrap.rem (|
                                                                  M.read (| n |),
                                                                  Value.Integer IntegerKind.I32 5
                                                                |),
                                                                Value.Integer IntegerKind.I32 0
                                                              |)
                                                            |)) in
                                                        let _ :=
                                                          M.is_constant_or_break_match (|
                                                            M.read (| γ |),
                                                            Value.Bool true
                                                          |) in
                                                        let~ _ :=
                                                          let~ _ :=
                                                            M.alloc (|
                                                              M.call_closure (|
                                                                M.get_function (|
                                                                  "std::io::stdio::_print",
                                                                  []
                                                                |),
                                                                [
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path
                                                                        "core::fmt::Arguments",
                                                                      "new_const",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.alloc (|
                                                                        Value.Array
                                                                          [
                                                                            M.read (|
                                                                              Value.String "buzz
"
                                                                            |)
                                                                          ]
                                                                      |)
                                                                    ]
                                                                  |)
                                                                ]
                                                              |)
                                                            |) in
                                                          M.alloc (| Value.Tuple [] |) in
                                                        M.alloc (| Value.Tuple [] |)));
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let~ _ :=
                                                          let~ _ :=
                                                            M.alloc (|
                                                              M.call_closure (|
                                                                M.get_function (|
                                                                  "std::io::stdio::_print",
                                                                  []
                                                                |),
                                                                [
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path
                                                                        "core::fmt::Arguments",
                                                                      "new_v1",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.alloc (|
                                                                        Value.Array
                                                                          [
                                                                            M.read (|
                                                                              Value.String ""
                                                                            |);
                                                                            M.read (|
                                                                              Value.String "
"
                                                                            |)
                                                                          ]
                                                                      |);
                                                                      M.alloc (|
                                                                        Value.Array
                                                                          [
                                                                            M.call_closure (|
                                                                              M.get_associated_function (|
                                                                                Ty.path
                                                                                  "core::fmt::rt::Argument",
                                                                                "new_display",
                                                                                [ Ty.path "i32" ]
                                                                              |),
                                                                              [ n ]
                                                                            |)
                                                                          ]
                                                                      |)
                                                                    ]
                                                                  |)
                                                                ]
                                                              |)
                                                            |) in
                                                          M.alloc (| Value.Tuple [] |) in
                                                        M.alloc (| Value.Tuple [] |)))
                                                  ]
                                                |)))
                                          ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |) in
                      M.alloc (| Value.Tuple [] |)))
                  |)))
            ]
          |))
      |)))
  | _, _, _ => M.impossible "wrong number of arguments"
  end.

Axiom Function_main : M.IsFunction "for_and_range_inclusive_to_exclusive::main" main.
