Hi! I am trying to write a function that executes boolean operations in a stack program. So far I have got the code bellow but, for some reason, executeBool
doesn’t work. Coq shows the error “Cannot guess decreasing argument of fix” but I’m not quite sure why since it seems a bit “obvious” that is it program
.
Inductive insStBool : Type :=
| SBPush : Z -> insStBool
| SBLoad : string -> insStBool
| SBNeg : insStBool
| SBCon : insStBool
| SBDis : insStBool
| SBEq : insStBool
| SBLt : insStBool
| SBSkip : nat -> insStBool.
Definition getVal (s:string) (st:M.t Z) : Z :=
match (find s st) with
| Some val => val
| None => 0
end.
Fixpoint executeBool (state:M.t Z) (stack:list Z) (program:list insStBool) : list Z :=
match program with
| nil => stack
| (SBPush n)::l => executeBool state (n::stack) l
| (SBLoad x)::l => executeBool state ((getVal x state)::stack) l
| (SBNeg)::l => match stack with
| nil => nil
| 0::st => executeBool state (1::st) l
| _::st => executeBool state (0::st) l
end
| (SBCon)::(SBSkip n)::l => match stack with
| nil => nil
| 0::st => executeBool state (0::st) ((SBSkip n)::l)
| _::st => executeBool state st l
end
| (SBDis)::(SBSkip n)::l => match l with
| nil => nil
| m::k =>
match stack with
| nil => nil
| 0::st => executeBool state st l
| _::st => executeBool state (1::st) ((SBSkip n)::l)
end
end
| (SBSkip n)::m::l => match n with
| 0%nat => executeBool state stack (m::l)
| (S k) => executeBool state stack ((SBSkip k)::l)
end
| (SBEq)::l => match stack with
| nil => nil
| n::nil => nil
| n::m::st => match (m - n) with
| 0 => executeBool state (1::st) l
| _ => executeBool state (0::st) l
end
end
| (SBLt)::l => match stack with
| nil => nil
| n::nil => nil
| n::m::st => match (m - n) with
| Z.pos x => executeBool state (1::st) l
| _ => executeBool state (0::st) l
end
end
| _ => nil
end.
Why does this happen? No matter how much I change the function, I keep getting it… Is there any way to fix it? Thank you!