I'm trying to convert this piece of pseudocode to SMT-LIB language, but I got stuck.
List function my_fun(int x) { list = nil for(i in 1 to x): if(some_condition_on_i) list.concat(i) return list }
what I've done so far is this:
(declare-const l1 (List Int)) (define-fun my_fun ((x Int)) (List Int) (forall ((t Int)) (ite (and (some_condition_on_t) (< t x)) (insert t l1) l1 ) ) ) )
which I know it is wrong, and does not work. can you help me to understand how can I do this?
SMT-LIB models logic, where variables are always immutable; your code, on the other hand, appears to be imperative, i.e. variables such as list
and i
are mutable. This crucial difference will be the biggest challenge in encoding your program and the challenge of reasoning about imperative programs has sparked research tools such as Dafny, Boogie, or Viper
Here are a few pointers:
(insert t l1)
represents a new list, obtained by inserting t
into l1
. It will not modify l1
(and there is no way to modify l1 since it is a logical variable) - A logical forall is a boolean formula (it evaluates to true or false), it is not a statement that you can execute (e.g. for its side effects)
If the value of x
were statically known (i.e. if it were 5
), then you could unroll the loop (here in pseudo-code):
l0 := Nil l1 := ite(condition(1), insert(1, l0), l0) l2 := ite(condition(2), insert(2, l1), l1) ... l4 := ite(condition(4), insert(4, l3), l3)
- If the value of
x
isn't statically known then you'll most likely either need a loop invariant or work with fix points in order to account for an unknown number of loop iterations