I have following definitions: (definition of positive integers as a subtype of nat)
Definition Z_pos_filter (p: nat) : bool :=
if (beq_nat p 0) then false else
Your definition of Z_pos_mult is too complicated. It relies on dependent pattern matching right from the start. I advise to use this kind of dependent pattern matching only for proofs, not for definitions.
Here is an alternative definition. Not that it fixes the returned value before doing any proof.
Definition Z_pos_mult (p q : Z_pos) : Z_pos.
exists (Z_pos__N p * Z_pos__N q).
destruct p as [p ph]; destruct q as [q qh].
unfold Z_pos_filter in ph, qh |- *; simpl.
destruct (p =? 0) eqn: ph'; try discriminate.
destruct (q =? 0) eqn: qh'; try discriminate.
rewrite beq_nat_false_iff in ph'.
rewrite beq_nat_false_iff in qh'.
destruct (p * q =? 0) eqn:pqh'; auto.
rewrite beq_nat_true_iff in pqh'.
destruct p; destruct q; try solve[discriminate | case ph'; auto | case qh'; auto].
Defined.
With this definition, the proof you request is easy to write.
Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof.
intros [p ph] [q qh]; unfold Z_pos_mult; simpl; auto.
Qed.
In principle, the proof for your code is also possible, but this is exceedingly difficult.