How can I find a logically equivalent formula without "implication" or "or"s? - discrete-mathematics

So I am trying to finish up my discrete math homework, but I am completely stumped as to how I am supposed to solve this problem. My teacher wants me to find a logically equivalent equation for p v q that does not include exclusive or, implication, or inclusive or (aka she wants me to use only negation and ands). I don't want any answers, for I need to do my homework myself. But please any examples or help would be GREATLY appreciated. I feel as though there is a simple way to do this going right over my head.

Using just NOTs and ANDs, you can create the NAND gate. Think of how complements relate ANDs and ORs and try and work it out for yourself before you see a big hint below.
Use De Morgan's laws to relate NANDs with ORs.
Furthermore, the NAND gate is a universal gate, which means that in principle any logic function can be realised with just the NAND gate. Try and see for yourself if you can simulate every other gate with just the NAND one.
If you really want the answer, it's below.
p OR q is equivalent to (NOT p) NAND (NOT q)

Here's a truth table for p V q:
p q p V q
T T T
T F T
F T T
F F F
We need to find an equivalent expression that gives the same final column (T, T, T, F) but using only not and and.
You can begin enumerating all possible formulas until you find one. The formula should use only p and q and not and and.
p q p and q
T T T
T F F
F T F
F F F
First thing we note is that the truth table for and gives three Fs, whereas ours needs three Ts. We can turn Ts to Fs and vice versa using negation, so maybe we guess that.
p q not(p and q)
T T F
T F T
F T T
F F T
This seems close, except we need T, T, T, F and we have F, T, T, T. We might notice that this pattern is totally backwards, and since the variables are ordered by truth value, we might guess that swapping truth values would work. To swap truth values, we use negation again:
p q not(not p and not q)
T T T
T F T
F T T
F F F
We found what we wanted. Now, I knew what the answer would be, but even if I hadn't, we would have eventually reached here by just listing out reasonable logical formulas in order. We knew:
Both symbols had to appear
Only "and" could allow both symbols to appear
The only other symbol allowed was not
not not x = x; so we don't need to duplicate
The formulas we could have blindly started writing down truth tables for is:
p and q
(not p) and q
p and (not q)
not(p and q)
not(p) and not(q)
not(not(p) and q)
not(p and (not q))
not((not p) and (not q))
At which point we could have found the answer with no insights other than the four points above.

Let's think about what the sentence p v q means.
p and q are, of course, two propositions - simple sentences that are true or false.
The sentence p v q is just saying 'p is true and/or q is true'. Basically, p v q is true when at least one of the two propositions are true.
So ask yourself the opposite: when would that sentence be false? Why, when neither of them are true! How would we express this? not p and not q
That amounts to saying that not (p or q) and not p and not q are equivalent sentences.
Which implies that not not (p or q) and not(not p and not q) are equivalent.
Now, by the double negation law, we know that two negations cancel out.
So we have p or q and not(not p and not q) are equivalent sentences.
And that is the answer you were looking for.

Related

Searching for a counterexample to a decidable predicate

It feels like the following Coq statement should be true constructively:
Require Import Decidable.
Lemma dec_search_nat_counterexample (P : nat -> Prop) (decH : forall i, decidable (P i))
: (~ (forall i, P i)) -> exists i, ~ P i.
If there were an upper bound, I'd expect to be able to show something of the form "suppose that not every i < N satisfies P i. Then there is an i < N where ~ P i". Indeed, you could actually write a function to find a minimal example by searching from zero.
Of course, there's not an upper bound for the original claim, but I feel like there should be an inductive argument to get there from the bounded version above. But I'm not clever enough to figure out how! Am I missing a clever trick? Or is there a fundamental reason that this cann't work, despite the well-orderedness of the natural numbers?
Reworked answer after Meven Lennon-Bertrand's comment
This statement is equivalent to Markov's principle with P and ~P exchanged. Since P is decidable we have P <-> (~ ~ P), so that one can do this replacement.
This paper (http://pauillac.inria.fr/~herbelin/articles/lics-Her10-markov.pdf) suggest that Markov's principle is not provable in Coq, since the author (one of the authors of Coq) suggests a new logic in this paper which allows to prove Markov's principle.
Old answer:
This is morally the "Limited Principle of Omniscience" - LPO (see https://en.wikipedia.org/wiki/Limited_principle_of_omniscience). It requires classical axioms to prove it in Coq - or you assert itself as an axiom.
See e.g.:
Require Import Coquelicot.Markov.
Check LPO.
Print Assumptions LPO.
Afair there is no standard library version of it.

Equality between two propositions nat -> nat

I am currently working in a project in coq where I need to work with lists of nat -> nat. So basically I will have a definition that takes a list (nat -> nat) and a proposition f : nat -> nat as parameters and the goal is to retrieve the index of f in the given list.
What I did is that I implemented a fixpoint going through the list and comparing each elements to f with equality =. But I found out that this was not correct and equality at such types are undecidable.
Does anyone know an alternative to solve this ? Or an easier way to retrieve the index of f in the list ?
I am not sure why you would call f : nat -> nat a proposition and not a function but in any case, unless you have more hypotheses on the contents of l, I don't think there is a solution to your problem.
As you point out, equality of functions is not decidable in general. You can only perform a finite amount of observations on them (like calling f 0 and examining the result). If you know your functions to be different enough then it might be enough to check whether they agree on a few (carefully chosen) specific values but otherwise I do not see a way out.
Perhaps is it that you oversimplified your problem/task at hand and the real problem you have does have a solution. At the moment, the problem is not related to Coq.
For the record, it seems unlikely that you really want/need this, provided that the general problem is undecidable (as Théo explained). However, for the sake of answering the question:
If you know for sure that your input list has exactly one occurrence of the function f you are looking for (where functions are identified by their pointwise equality), then all other functions of the list disagree with f at some point. In other words, for each of the other functions, there exists a k : nat such that g k ≠ f k.
Since nat is enumerable, that integer comparison is decidable, and that the list is finite, there is a terminating algorithm to solve this problem. In imperative pseudo-code:
input: a function f : nat → nat
input: a list of functions [ g[0] ; g[1] ; … ; g[n−1] ] : list (nat → nat)
start:
candidates := { 0 ; 1 ; … ; n−1 } (set of cardinal n)
k := 0
while true do:
if card candidates < 2 then:
return the only candidate
for all i in candidates do:
if f k ≠ g[i] k then:
candidates := candidates \ { i }
k := k+1
end
If the list has several occurrences of f, then the algorithm never terminates (the occurrences remain candidates forever). If there is zero or one occurrence, the algorithm terminates but there is no way of deciding whether the remaining candidate is totally equal to f.
Hence the assumption stated above is necessary for termination and correction. That’s likely not easy to implement in Coq, especially since you have to convince Coq of the termination. Good luck if that’s really what you want. ;-)

Extensionality axiom: why is it not unsound

Axiom of extensionality says that two functions are equal if their actions on each argument of the domain are equal.
Axiom func_ext_dep : forall (A : Type) (B : A -> Type) (f g : forall x, B x),
(forall x, f x = g x) -> f = g.
Equality = on both side of the theorem statement is propositional equality (a datatype with a single eq_refl constructor).
Using this axiom it could be proven that f = a + b and g = b + a are propositionally equal.
But f and g are obviously not equal as data structures.
Could you please explain what I'm missing here?
Probably that function objects don't have normal form?
EDIT: After further discussion in the comments, the actual point of confusion was this:
Doesn't match a with... = match b with gives me False right away the same way as S S Z = S Z does?
You can pattern-match on nat, you can't on functions. Dependent pattern-matching is how we can prove injectivity and disjointness of constructors, whereas the only thing we can do with a function is to apply it. (See also How do we know all Coq constructors are injective and disjoint?)
Nevertheless, I hope the rest of the answer below is still instructive.
From the comments:
AFAIU, = has a very precise meaning in Coq/CIC - syntactic equality of normal forms.
That's not right. For example we can prove the following:
Lemma and_comm : forall a b : bool, (* a && b = b && a *)
match a with
| true => b
| false => false
end = match b with
| true => a
| false => false
end.
Proof.
destruct a, b; reflexivity.
Qed.
We can only use eq_refl when the two sides are syntactically equal, but there are more reasoning rules we can apply beyond the constructors of an inductive propositions, most notably dependent pattern-matching, and, if we admit it, functional extensionality.
But f and g are obviously not equal as data structures.
This statement seems to confuse provability and truth. It's important to distinguish these two worlds. (And I'm not a logician, so take what I'm going to say with a grain of salt.)
Coq is a symbol-pushing game, with well-defined rules to construct terms of certain types. This is provability. When Coq accepts a proof, all we know is that we constructed a term following the rules.
Of course, we also want those terms and types to mean something. When we prove a proposition, we expect that to tell us something about the state of the world. This is truth. And in a way, Coq has very little say in the matter. When we read f = g, we are giving a meaning to the symbol f, a meaning to g, and also a meaning to =. This is entirely up to us (well, there are always rules to follow), and there's more than one interpretation (or "model").
The "naive model" that most people have in mind views functions as relations (also called graphs) between inputs and outputs. In this model, functional extensionality holds: a function is no more than a mapping between inputs and outputs, so two functions with the same mappings are equal. Functional extensionality is sound in Coq (we can't prove False) because there is at least one model where it is valid.
In the model you have, a function is characterized by its code, modulo some equations. (This is more or less the "syntactic model", where we interpret every expression as itself, with the minimal possible amount of semantic behavior.) Then, indeed there are functions that are extensionally equal, but with different code. So functional extentionality is not valid in this model, but that doesn't mean it's false (i.e., that we can prove its negation) in Coq, as justified previously.
f and g are not "obviously not equal", because equality, like everything else, is relative to a particular interpretation.

Unable to formulate a prover9 axiom

I'm trying to teach basic set theory to Prover9. The following definition of membership seems to work very well (the second axiom is just to make lists unordered):
member(x,[x:y]).
[x,y]=[y,x].
With this, I can have Prover9 prove 'complicated' things like member([A,B],[C,[A,B]]) and others.
However, I must be doing something wrong when I use it to define subsets:
subset(x,y) <-> (member(z,x) -> member(z,y)).
Prover9 clausifies this as subset(x,y) | -member(z,y) and uses it to prove false clauses, like subset([A],[B,C]).
What am I missing?
Your "second axiom ... just to make lists unordered" looks suspicious.
Note [x,y] is a two-element list. So your axiom is saying nothing about lists in general. Your 'complicated' examples, are still 2-element lists. So not very complicated. I think you'll be unable to prove member(A, [C, B, A])
Contrast that [x:y] in your first axiom is a 1-or-more-element list. The y might be nil, or might be any number of elements. IOW y is a list, whereas in [x,y], y is an element of a list.
See http://www.cs.unm.edu/~mccune/prover9/manual/2009-11A/, 'Clauses & Formulas' at 'list notation'.
I'd go:
member(x, [x:y]).
member(x, z) -> member(x, [y:z]).
(But that defines a bag, not a set.)
I think the quantification over variables is a red herring.
Edit: Errk. I'm wrong. So I don't know why I got this result:
The example that #Doug points to doesn't need to quant z 'inside'
the rhs of equivalence. You can just remove all the explicit
quantification, and the proof still works.
OK. Let's apply the rewrite rules per the Manual 'Clauses & Formulas' at "If non-clausal formulas are entered ...".
That definition of subset is an equivalence (aka bi-implication); rewrite as two separate axioms: 'forwards' and backwards' implications; rewrite each of those using p -> q ==> -p | q.
In the 'forwards' direction we get:
-subset(x, y) | (member(z, x) -> member(z, y)).
Doesn't matter whether the z is quantified narrow or wide.
In the 'backwards' direction:
-(member(z, x) -> member(z, y)) | subset(x, y).
Here if we quantify z narrowly around the implication, that's inside the scope of negation; and so different to quantifying across the whole formula.
Conclusion: both your definition of member( ) and of subset( ) are wrong.
BTW Are you sure you need to define member? The proof #Doug points to just takes member(x,y) as primitive.

What forms of goal in Coq are considered to be "true"?

When I prove some theorem, my goal evolves as I apply more and more tactics. Generally speaking the goal tends to split into sub goals, where the subgoals are more simple. At some final point Coq decides that the goal is proven. How this "proven" goal may look like? These goals seems to be fine:
a = a. (* Any object is identical to itself (?) *)
myFunc x y = myFunc x y. (* Result of the same function with the same params
is always the same (?) *)
What else can be here or can it be that examples are fundamentally wrong?
In other words, when I finally apply reflexivity, Coq just says ** Got it ** without any explanation. Is there any way to get more details on what it actually did or why it decided that the goal is proven?
You're actually facing a very general notion that seems not so general because Coq has some user-friendly facility for reasoning with equality in particular.
In general, Coq accepts a goal as solved as soon as it receives a term whose type is the type of the goal: it has been convinced the proposition is true because it has been convinced the type that this proposition describes is inhabited, and what convinced it is the actual witness you helped build along your proof.
For the particular case of inductive datatypes, the two ways you are going to be able to proved the proposition P a b c are:
by constructing a term of type P a b c, using the constructors of the inductive type P, and providing all the necessary arguments.
or by reusing an existing proof or an axiom in the environment whose type you can get to match P a b c.
For the even more particular case of equality proofs (equality is just an inductive datatype in Coq), the same two ways I list above degenerate to this:
the only constructor of equality is eq_refl, and to apply it you need to show that the two sides are judgementally equal. For most purposes, this corresponds to goals that look like T a b c = T a b c, but it is actually a slightly more broad notion of equality (see below). For these, all you have to do is apply the eq_refl constructor. In a nutshell, that is what reflexivity does!
the second case consists in proving that the equality holds because you have other equalities in your context, nothing special here.
Now one part of your question was: when does Coq accept that two sides of an equality are equal by reflexivity?
If I am not mistaken, the answer is when the two sides of the equality are αβδιζ-convertible.
What this grossly means is that there is a way to make them syntactically equal by repeated applications of:
α : sane renaming of non-free variables
β : computing reducible expressions
δ : unfolding definitions
ι : simplifying matches
ζ : expanding let-bound expressions
[someone please correct me if more rules apply or if I got one wrong]
For instance some of the things that are not captured by these rules are:
equality of functions that do more or less the same thing in different ways:
(fun x => 0 + x) = (fun x => x + 0)
quicksort = mergesort
equality of terms that are stuck reducing but would be equal:
forall n, 0 + n = n + 0