Reputation: 166
I'm following trough the software foundations books for working with Coq. I'm currently at the Tactics chapter and I'm stuck on the forall_exists_challenge.
I would like to negate the test
predicate using negb
but I receive the error The term "test" has type "X -> bool" while it is expected to have type "bool".
Fixpoint forallb {X : Type} (test : X -> bool) (l : list X) : bool :=
match l with
| [] => true
| h :: t => test h && forallb test t
end.
Example test_forallb_1 : forallb oddb [1;3;5;7;9] = true.
Proof. simpl. reflexivity. Qed.
Example test_forallb_2 : forallb negb [false;false] = true.
Proof. simpl. reflexivity. Qed.
Example test_forallb_3 : forallb evenb [0;2;4;5] = false.
Proof. simpl. reflexivity. Qed.
Example test_forallb_4 : forallb (eqb 5) [] = true.
Proof. simpl. reflexivity. Qed.
Fixpoint existsb {X : Type} (test : X -> bool) (l : list X) : bool :=
match l with
| [] => false
| h :: t => test h || forallb test t
end.
Example test_existsb_1 : existsb (eqb 5) [0;2;3;6] = false.
Proof. simpl. reflexivity. Qed.
Example test_existsb_2 : existsb (andb true) [true;true;false] = true.
Proof. simpl. reflexivity. Qed.
Example test_existsb_3 : existsb oddb [1;0;0;0;0;3] = true.
Proof. simpl. reflexivity. Qed.
Example test_existsb_4 : existsb evenb [] = false.
Proof. simpl. reflexivity. Qed.
Definition existsb' {X : Type} (test : X -> bool) (l : list X) : bool :=
negb (forallb (negb test) l).
Example test_existsb_1' : existsb' (eqb 5) [0;2;3;6] = false.
Proof. simpl. reflexivity. Qed.
Theorem existsb_existsb' : forall (X : Type) (test : X -> bool) (l : list X),
existsb test l = existsb' test l.
Proof. (* FILL IN HERE *) Admitted.
I expect I could be able to negate a predicate in some way but I can't seem to quite figure out how.
Upvotes: 0
Views: 256
Reputation: 10474
As the error message says, negb
expects a single boolean, rather than a whole predicate. The simplest way to make a new predicate using negb
would be something like fun x => negb (test x)
. Note that now (test x)
actually does have type bool
so it can be fed to negb
.
Alternatively, you could make a notation for function composition (I don't think such a notation exists in the standard library, though I don't know about Software Foundations). For example, Notation "f 'o' g" := (fun x => f (g x)) (at level 20).
(you might need to change the level to avoid conflicts with existing notations). Then you'd be able to do negb o test
.
A third solution, if you expect to be negating predicates a lot and don't want to go as far as a function composition notation, would be to make a new function that negates a boolean predicate instead of negating a boolean. For example, Definition neg_pred {X: Type} (pred: X -> bool): X -> bool := fun x => negb (pred x).
. Then you can simply use neg_pred test
.
Upvotes: 2