Quando provo com Coq (ou Rocq), descubro que, às vezes, se uma hipótese é "P" e outra é "P -> para todo x, Q x", não consigo fazer de "para todo x, Q x" uma nova premissa pelo modus ponens.
Aqui está um exemplo:
Theorem post_forall: forall (X: Type) (P: Prop) (Q: X -> Prop),
(P -> forall x, Q x) -> forall x, P -> Q x.
Proof.
(*
Here is a correct proof:
intros X P Q.
intros H.
intros y.
intros H1.
generalize dependent y.
apply H.
apply H1.
Qed.
*)
intros X P Q.
intros H.
intros y.
intros H1.
generalize dependent y.
apply H in H1.
(** STUCK HERE,
But Why cannot we do this???
They look the same.
*)
Admitted.
A prova ficará presa na linha "aplicar H em H1" e Coq retornará "Não foi possível encontrar uma instância para a variável x".
Mas "x" precisa ser instanciado? Parece desnecessário. Qual é a diferença entre as duas provas?
Perguntei ao DeepSeek e ao ChatGPT. Nenhum deles conseguiu fornecer uma resposta satisfatória.
Também imaginei que poderia ser o problema da ocorrência de variáveis no antecedente. Mas, se fosse, a tática de "generalizar dependente" deveria ter falhado.
Veja a documentação : uma solução simples é usar
eapply H in H1
, ou simplesmente concluir a prova comexact (H H1)
.Alternativamente, observe que você realmente não precisa de táticas aqui: toda a prova é apenas
fun X P Q H x p => H p x
.O comportamento que você está procurando está disponível , mas você precisa usar a
specialize
tática, e ela substituirá sua implicação em vez de sua consequência [ referência ].Exemplo com algum contexto de prova omitido:
specialize (H H1)
Eu também estou confuso. Acho que você encontrou uma peculiaridade em "apply". Já vi restrições semelhantes ao raciocínio sobre quantificações internas documentadas em outros recursos de versões mais antigas. (Especificamente no CPDT, se alguém se lembra...)
O módulo pones é
A => B
, aqui você tem(forall x, A -> B x) => (A => forall x, B x
). Não é a mesma coisa. Claro que o módulo abre implica isso, mas não se aplica diretamente. Se você quiser usar o módulo pones, precisa introduzir todas as variáveis primeiro.