1

Suppose I have the following tactic to check if a term is the literal zero:

Ltac isZero x :=
  match x with
  | O => constr:true
  | _ => constr:false
  end.

Goal Set.
  let isz := isZero O in pose isz.
  (* adds true to the context *)

Now imagine that I want the tactic to accept a bit more; maybe any term that is convertible with zero. If this was a tactic acting on the goal, I would do

Ltac isZero x :=
  match x with
  | ?v => unify v 0; constr:true
  | _  => constr:false
  end.

but this fails for a tactic producing terms:

Error: Value is a term. Expected a tactic. 

How can I check for convertibility in a tactic producing terms? In this specific example reducing x or computing it (let xx := eval compute in x) may work, but in more complex example the cost of computing could be prohibitive, especially as I would need to reduce the two terms of the comparison.

PS: For reference, the unsimplified issue is that I'm trying to efficiently lookup a key probably matching a value in an FMap built by sequences of calls to add, and the tactic looks like

Ltac find_key value :=
  match fmap with
  | add ?k value _ => constr:(Some k)
  | add _ _ ?m => find_key value m
  | _ => constr:None
  end

With this implementation, if instead of value the map contains a term convertible to value but not syntactically equal to it, the tactic will incorrectly return None.

Clément
  • 12,299
  • 15
  • 75
  • 115

1 Answers1

1

You can try to construct a term that triggers the conversion check; for instance:

Goal 2 + 2 = 4.

match goal with
| |- ?a = ?b =>
  let e := constr:(eq_refl a : a = b) in
  idtac "equal"
| |- _ => idtac "not equal"
end.

Normally, this prints "equal". However, if you replace 4 by, say, 3 in the goal above, the inner branch fails, printing "not equal".

Arthur Azevedo De Amorim
  • 23,012
  • 3
  • 33
  • 39
  • Can't you use the `unify` tactic? https://coq.inria.fr/refman/Reference-Manual010.html#hevea_tactic155 – Ptival Oct 10 '15 at 06:04
  • @Ptival, my question showed an example using unify, which doesn't work :) (in Arthur's example it would, though; but it has side effects, too) – Clément Oct 10 '15 at 18:36