Я работаю над доказательством корректности компилятора в основах языка программирования и часами чесал в затылке, прежде чем сдаться и применить это решение, которое я нашел в сети (https://github.com/haklabbeograd/software-Foundation-coq-shops/blob/master/Imp.v ). Я попытался адаптировать свою функцию (первый s_execute), но она все равно не сработает, чтобы доказать приведенную ниже лемму (работает только последняя реализация). Кроме того, я могу заставить онлайн-решение работать только тогда, когда я запускаю его в его файле, а не в моем (все определения одинаковы, за исключением instr vs sinstr, а переменные определены немного по-другому). Почему это так (в частности, почему ошибка объединения возникает только в первом решении)? Кроме того, в книге сказано:
Помните, что в спецификации не указано, что делать при обнаружении инструкции [SPlus], [SMinus] или [SMult], если стек содержит менее tw элементов. (Чтобы упростить доказательство правильности, возможно, вам будет полезно вернуться и изменить свою реализацию!)
Какое определение автор намеревается изменить, чтобы сделать это правильным?
Fixpoint s_execute (st : state) (stack : list nat)
(prog : list instr)
: list nat :=
match prog with
| [] => stack
| x :: xs => match x, stack with
| (SPush n), ys => s_execute st (n :: ys) xs
| (SLoad x), ys => s_execute st ((st x) :: ys) xs
| SPlus, y1 :: y2 :: ys => s_execute st ((y1 + y2) :: ys) xs
| SMinus, y1 :: y2 :: ys => s_execute st ((y2 - y1) :: ys) xs
| SMult, y1 :: y2 :: ys => s_execute st ((y2 * y1) :: ys) xs
| _, _ => stack
end
end.
Fixpoint s_execute (st : state) (stack : list nat)
(prog : list instr)
: list nat :=
let newstack :=
match prog with
| [] => stack
| (SPush n)::_ => n::stack
| (SLoad id)::_ => (st id)::stack
| SPlus::_ => match stack with
| n::(m::rest) => (m+n)::rest
| _ => stack
end
| SMinus::_ => match stack with
| n::m::rest => (m-n)::rest
| _ => stack
end
| SMult::_ => match stack with
| n::m::rest => (m*n)::rest
| _ => stack
end
end in
match prog with
| [] => stack
| instr::rest => s_execute st newstack rest
end.
Приведенная ниже лемма работает только со второй реализацией, хотя обе соответствуют приведенным примерам s_execute (1 | 2).
Lemma s_execute_app : forall st p1 p2 stack,
s_execute st stack (p1 ++ p2) = s_execute st (s_execute st stack p1) p2.
intros st p1.
induction p1.
intros; reflexivity.
intros.
apply IHp1.
Qed.