Quero definir um pequeno registro no Coq que também inclua certas condições. Além disso quero uma definição para criar um registro de maneira fácil. Aqui está minha abordagem:
Require Import Arith.
(* Define the qn record with conditions for q and n *)
Record qn := {
q : nat;
q_ge_2 : leb 2 q = true; (* Ensuring q is greater or equal than 2 *)
n : nat;
n_ge_1 : leb 1 n = true (* Ensuring n is greater or equal than 1 *)
}.
(* A support function to create instances of qn more conveniently *)
Definition make_qn (q n: nat) (Hq : leb 2 q = true) (Hn : leb 1 n = true) : qn :=
{| q := q; q_ge_2 := Hq; n := n; n_ge_1 := Hn |}.
(* Examples of qn *)
Example qn_example1 : qn := make_qn 2 1 (eq_refl true) (eq_refl true).
Example qn_example2 : qn := make_qn 3 5 (eq_refl true) (eq_refl true).
Example qn_example3 : qn := make_qn 4 2 (eq_refl true) (eq_refl true).
Já tentei algumas abordagens diferentes - também para definir o registro qn, por exemplo, usando Prop em vez de bool.
Existe uma maneira de simplificar a make_qn
definição para incluir diretamente as provas? Por exemplo, para usá-lo como
Example qn_simple1 : qn := make_qn 2 1
Considere esta definição de
qn
(onde renomeei algumas coisas por conveniência):Com a premissa de que todas as funções em Coq devem ser totais, podemos de fato provar que não existe um "construtor de atalho
qn
" conforme sua pergunta, ou seja, que não existe uma função (total) que, dada uma and arbitrária , retorne tal que é = e = :q
n
qn
qn_q
q
qn_n
n
Aliás, uma abordagem possível para um "construtor de atalho
qn
" (conforme sua pergunta) é teroption qn
como tipo de retorno, embora, é claro, isso apenas mova a trave, pois então a necessidade passa a ser a de correspondência de padrões no retornadooption
/ provando que temos umSome
vs.None
Dito isto, uma forma de mitigar a inconveniência de ter que fornecer termos de prova todas as vezes no construtor (também mencionado por @Villetaneuse em um comentário à sua resposta) é o uso de notações com táticas , que podem de fato ser usadas para construir termos, embora não possa ser usado na correspondência de padrões (não tenho conhecimento de outras diferenças significativas, pelo menos não neste caso):
Aqui está minha tentativa de simplificar seu código.
Prop
em vez debool
porquelia
gostoProp
mais, masbool
também poderia ser mantido com outras ferramentas para provar as desigualdades (ou mesmo cálculos simples).make_qn
fora do registro, dou um nome ao construtor do registro.ltac:(tactic)
para construir termos de prova nos exemplos.Provavelmente não é perfeito (por exemplo, a igualdade para este registro precisa usar alguma forma de irrelevância de prova).
Não creio que exista uma solução mágica para construir elementos sem fornecer termos de prova.