I'm trying to use Coq for some simple kinds of philosophical predicate logic. Suppose, for instance, that I wanted to express the statement "if a being is human, it is not perfect" in Coq. I will first have to define what the terms 'being', 'human', and 'perfect' are. The natural approach, it seems, is to define the first as a type, and others as unary predicates of that type.
Inductive being : Type :=
| b : nat -> being.
Inductive human : being -> Prop :=
| h : forall ( b : being ), human b.
Inductive perfect : being -> Prop :=
| p : forall ( b : being ), perfect b.
(being is indexed with numbers to ensure there are multiple distinct beings.)
With this definition, the statement can be expressed as
Lemma humans_are_imperfect :
forall ( b : being ), human b -> ~ perfect b.
Admitted.
The problem with this approach is that it allows proofs of nonsense, such as
Lemma humans_are_perfect :
forall ( b : being ), human b -> perfect b.
intros b H. apply ( p b ). Qed.
Obviously, there is a problem with the definition of human and perfect, because it indescriminately takes any being and asserts its humanity and perfection. What is needed is a definition of human and perfect that only specifies their types, while remaining ambiguous about which beings they apply to.
This problem could be avoided altogether if the truth condition of perfect was built into its definition, e.g. the constructor only took nonhuman beings as arguments. But supplying all information upfront like that is not always feasible in philosophical arguments. Very often you have to take some type or predicate as a given, and slowly build up its details with further premises.
I have a feeling that what I'm trying to do does not fit very well into the inductive basis of Coq. Maybe I'm better off learning a logic programming language like Prolog, but hopefully I'm wrong.