How to define Xor in Coq and prove its properties -
this should easy question. i'm new coq.
i want define exclusive or in coq (which best of knowledge not predefined). important part allow multiple propositions (e.g. xor b c d).
i need 2 properties:
(xor a1 a2 ... an)/\~a1 -> xor a2... (xor a1 a2 ... an)/\a1 -> ~a2/\.../\~an
i'm having trouble defining function undefined number of variables. tried define hand two, three, 4 , 5 variables (that's how many need). proving properties pain , seems inefficient.
given second property, assume definition of exclusive or @ higher arities “exactly 1 of these propositions true” (and not “an odd number of these propositions true” or “at least 1 of these propositions true , @ least 1 false”, other possible generalizations).
this exclusive or not associative property. means can't define higher-arity xor xor(a1,…,an)=xor(a1,xor(a2,…)). need global definition, , means type constructor must take list of arguments (or other data structure, list obvious choice).
inductive xor : list prop -> prop := …
you have 2 reasonable choices: build definition of xor inductively first principles, or invoke list predicate. list predicate “there unique element in list matching predicate”. since standard list library not define predicate, , defining harder defining xor, we'll build xor inductively.
the argument list, let's break down cases:
- xor of empty list false;
- xor of list
(cons l)
true iff either of these 2 conditions met:- a true , none of elements of l true;
- a false , 1 of elements of l true.
this means need define auxiliary predicate on lists of propositions, nand
, characterizing lists of false propositions. there many possibilities here: fold /\
operator, induct hand, or call list predicate (again, not in standard list library). i'll induct hand, folding /\
reasonable choice.
require import list. inductive nand : list prop -> prop := | nand_nil : nand nil | nand_cons : forall (a:prop) l, ~a -> nand l -> nand (a::l). inductive xor : list prop -> prop := | xor_t : forall (a:prop) l, -> nand l -> xor (a::l) | xor_f : forall (a:prop) l, ~a -> xor l -> xor (a::l). hint constructors nand xor.
the properties want prove simple corollaries of inversion properties: given constructed type, break down possibilities (if have xor
, it's either xor_t
or xor_f
). here's manual proof of first; second similar.
lemma xor_tail : forall l, xor (a::l) -> ~a -> xor l. proof. intros. inversion_clear h. contradiction. assumption. qed.
another set of properties you're want equivalences between nand
, built-in conjunction. example, here's proof nand (a::nil)
equivalent ~a
. proving nand (a::b::nil)
equivalent ~a/\~b
, on merely more of same. in forward direction, once more inversion property (analyse possible constructors of nand
type). in backward direction, simple application of constructors.
lemma nand1 : forall a, nand (a::nil) <-> ~a. proof. split; intros. inversion_clear h. assumption. constructor. assumption. constructor. qed.
you're need substitution , rearrangement properties @ point. here few key lemmas may want prove (these shouldn't difficult, induct on right stuff):
forall a1 b2 l, (a1<->a2) -> (xor (a1::l) <-> xor (a2::l))
forall k l1 l2, (xor l1 <-> xor l2) -> (xor (k++l1) <-> xor (k++l2))
forall k b l, xor (k++a::b::l) <-> xor (k::b::a::l)
forall k l m n, xor (k++l++m++n) <-> xor (k++m++l++n)
Comments
Post a Comment