{-
Given a loop guard and body, unroll the loop
a constant number of times
Used when we can't find a fixed-point invariant
-}
unrollLoop :: Expression -> Statement -> Statement
unrollLoop guard body = helper unrollDepth (Assert $ LNot guard)
  where
    helper 0 accum = accum
    helper i accum = helper (i-1) $
      ifelse guard
        (body `Seq` accum ) (Skip)


{-
Given program postconditions and parameters (for a multi-function program), a top-level statement,
a loop guard and body, and a post-condition, use fixpoint iteration,
up to a constant number of iterations,
to try to infer an invariant for the loop

The top-level statement is used to find free variables and their types
for generating a Z3 expression.
The Z3 program is invoked to test if two conditions are "equal"
-}
unrollLoop :: Expression -> Statement -> Statement
unrollLoop guard body = helper unrollDepth (Assert $ LNot guard)
  where
    helper 0 accum = accum
    helper i accum = helper (i-1) $
      ifelse guard
        (body `Seq` accum ) (Skip)


{-
Given program postconditions and parameters (for a multi-function program), a top-level statement,
a loop guard and body, and a post-condition, use fixpoint iteration,
up to a constant number of iterations,
to try to infer an invariant for the loop

The top-level statement is used to find free variables and their types
for generating a Z3 expression.
The Z3 program is invoked to test if two conditions are "equal"
-}
unrollLoop guard body = helper unrollDepth (Assert $ LNot guard)
  where
    helper 0 accum = accum
    helper i accum = helper (i-1) $
      ifelse guard
        (body `Seq` accum ) (Skip)


{-
Given program postconditions and parameters (for a multi-function program), a top-level statement,
a loop guard and body, and a post-condition, use fixpoint iteration,
up to a constant number of iterations,
to try to infer an invariant for the loop

The top-level statement is used to find free variables and their types
for generating a Z3 expression.
The Z3 program is invoked to test if two conditions are "equal"
-}