How to formalize the definition of likeness/similarity between relations in Coq? - logic

I am reading the book Introduction to Mathematics Philosophy by B.Russell and trying to formalize the definitions. Whereas I got stuck on proving the equivalence between the two definitions of similarity posed in the book.
Here are the text quoted from the book. (context)
1) Defining similarity directly:
We may define two relations P and Q as “similar,” or as having
“likeness,” when there is a one-one relation S whose domain is the
field of P and whose converse domain is the field of Q, and which is
such that, if one term has the relation P to another, the correlate of
the one has the relation Q to the correlate of the other, and vice
versa.
Here's my comprehension of the above text:
Inductive similar {X} (P : relation X) (Q : relation X) : Prop :=
| similar_intro : forall (S : relation X),
one_one S ->
(forall x, field P x <-> domain S x) ->
(forall x y z w, P x y -> S x z -> S y w -> Q z w) ->
(forall x y z w, Q z w -> S x z -> S y w -> P x y) ->
similar P Q.
2) Defining similarity through the concept of 'correlator':
A relation S is said to be a “correlator” or an “ordinal correlator”
of two relations P and Q if S is one-one, has the field of Q for its
converse domain, and is such that P is the relative product of S and Q
and the converse of S.
Two relations P and Q are said to be “similar,” or to have “likeness,”
when there is at least one correlator of P and Q.
My definition to this is:
Inductive correlator {X} (P Q : relation X) : relation X -> Prop :=
| correlator_intro : forall (S : relation X),
one_one S ->
(forall x, field P x <-> domain S x) ->
(forall x y, relative_product (relative_product S Q) (converse S) x y <-> P x y) ->
correlator P Q S.
Inductive similar' {X} (P Q : relation X) : Prop :=
| similar'_intro : forall S, correlator P Q S -> similar' P Q.
But I couldn't prove that similar is equivalent to similar', where did I make the mistake? Thanks a lot.

Related

How do you use the Ring solver in Cubical Agda?

I have started playing around with Cubical Agda. Last thing I tried doing was building the type of integers (assuming the type of naturals is already defined) in a way similar to how it is done in classical mathematics (see the construction of integers on wikipedia). This is
data dInt : Set where
_⊝_ : ℕ → ℕ → dInt
canc : ∀ a b c d → a + d ≡ b + c → a ⊝ b ≡ c ⊝ d
trunc : isSet (dInt)
After doing that, I wanted to define addition
_++_ : dInt → dInt → dInt
(x ⊝ z) ++ (u ⊝ v) = (x + u) ⊝ (z + v)
(x ⊝ z) ++ canc a b c d u i = canc (x + a) (z + b) (x + c) (z + d) {! !} i
...
I am now stuck on the part between the two braces. A term of type x + a + (z + d) ≡ z + b + (x + c) is asked. Not wanting to prove this by hand, I wanted to use the ring solver made in Cubical Agda. But I could never manage to make it work, even trying to set it up for simple ring equalities like x + x + x ≡ 3 * x.
How can I make it work ? Is there a minimal example to make it work for naturals ? There is a file NatExamples.agda in the library, but it makes you have to rewrite your equalities in a convoluted way.
You can see how the solver for natural numbers is supposed to be used in this file in the cubical library:
Cubical/Tactics/NatSolver/Examples.agda
Note that this solver is different from the solver for commutative rings, which is designed for proving equations in abstract rings and is explained here:
Cubical/Tactics/CommRingSolver/Examples.agda
However, if I read your problem correctly, the equality you want to prove requires the use of other propositional equalities in Nat. This is not supported by any solver in the cubical library (as far as I know, also the standard library doesn't support it). But of course, you can use the solver for all the steps that don't use other equalities.
Just in case you didn't spot this: here is a definition of the integers in math-style using the SetQuotients of the cubical library. SetQuotients help you to avoid the work related to your third constructor trunc. This means you basically just need to show some constructions are well defined as you would in 'normal' math.
I've successfully used the ring solver for exactly the same problem: defining Int as a quotient of ℕ ⨯ ℕ. You can find the complete file here, the relevant parts are the following:
Non-cubical propositional equality to path equality:
open import Cubical.Core.Prelude renaming (_+_ to _+̂_)
open import Relation.Binary.PropositionalEquality renaming (refl to prefl; _≡_ to _=̂_) using ()
fromPropEq : ∀ {ℓ A} {x y : A} → _=̂_ {ℓ} {A} x y → x ≡ y
fromPropEq prefl = refl
An example of using the ring solver:
open import Function using (_$_)
import Data.Nat.Solver
open Data.Nat.Solver.+-*-Solver
using (prove; solve; _:=_; con; var; _:+_; _:*_; :-_; _:-_)
reorder : ∀ x y a b → (x +̂ a) +̂ (y +̂ b) ≡ (x +̂ y) +̂ (a +̂ b)
reorder x y a b = fromPropEq $ solve 4 (λ x y a b → (x :+ a) :+ (y :+ b) := (x :+ y) :+ (a :+ b)) prefl x y a b
So here, even though the ring solver gives us a proof of _=̂_, we can use _=̂_'s K and _≡_'s reflexivity to turn that into a path equality which can be used further downstream to e.g. prove that Int addition is representative-invariant.

Coq: apply transitivity with substitution

I want to proof this lemma in Coq:
a : Type
b : Type
f : a -> b
g : a -> b
h : a -> b
______________________________________(1/1)
(forall x : a, f x = g x) ->
(forall x : a, g x = h x) -> forall x : a, f x = h x
I know that Coq.Relations.Relation_Definitions defines transitivity for relations:
Definition transitive : Prop := forall x y z:A, R x y -> R y z -> R x z.
Simply using the proof tactic apply transitivity obviously fails. How can I apply the transitivity lemma to the goal above?
The transitivity tactic requires an argument, which is the intermediate term that you want to introduce into the equality. First call intros (that's almost always the first thing to do in a proof) to have the hypotheses nicely in the environment. Then you can say transitivity (g x) and you're left with two immediate applications of an assumption.
intros.
transitivity (g x); auto.
You can also make Coq guess which intermediate term to use. This doesn't always work, because sometimes Coq finds a candidate that doesn't work out in the end, but this case is simple enough and works immediately. The lemma that transitivity applies is eq_trans; use eapply eq_trans to leave a subterm open (?). The first eauto chooses a subterm that works for the first branch of the proof, and here it also works in the second branch of the proof.
intros.
eapply eq_trans.
eauto.
eauto.
This can be abbreviated as intros; eapply eq_trans; eauto. It can even be abbreviated further to
eauto using eq_trans.
eq_trans isn't in the default hint database because it often leads down an unsuccessful branch.
Ok, I was on the wrong track. Here is the proof of the lemma:
Lemma fun_trans : forall (a b:Type) (f g h:a->b),
(forall (x:a), f x = g x) ->
(forall (x:a), g x = h x) ->
(forall (x:a), f x = h x).
Proof.
intros a b f g h f_g g_h x.
rewrite f_g.
rewrite g_h.
trivial.
Qed.

Find unique tuples in a relation represented by a BDD

Let's suppose I use a BDD to represent the set of tuples in a relation. For simplicity consider tuples with 0 or 1 values. For instance:
R = {<0,0,1>, <1,0,1>, <0,0,0>} represent a ternary relation in a BDD with three variables, say x, y and z (one for each tuple's element). What I want is to implement an operation that given a bdd like for R and a cube C returns the subset of R that contains unique tuples when the variables in C are abstracted.
For instance, if C contains the variable x (which represents the first element in each tuple) the result of the function must be {<0,0,0>}. Notice that when x is abstracted away tuples <0,0,1> and <1,0,1> become "the same".
Now suppose R = {<0,0,1>, <1,0,1>, <0,0,0>, <1,0,0>} and we want to abstract x again. In this case I would expect the constant false as result because there is no unique tuple in R after abstracting x.
Any help is highly appreciated.
This could be done in three simple steps:
Make two BDDs with restricted value of the variable you want to abstract:
R[x=0] = restrict R with x = 0
R[x=1] = restrict R with x = 1
Apply XOR operation to this new BDDs
Q = R[x=0] xor R[x=1]
Enumerate all models of Q
Applying this to your examples:
R = {<0,0,1>, <1,0,1>, <0,0,0>} = (¬x ∧ ¬y ∧ z) ∨ (x ∧ ¬y ∧ z) ∨ (¬x ∧ ¬y ∧ ¬z)
R[x=1] = {<0,1>} = (¬y ∧ z)
R[x=0] = {<0,1>,<0,0>} = (¬y ∧ z) ∨ (¬y ∧ ¬z)
Q = R[x=1] xor R[x=0] = (¬y ∧ ¬z)
Intuition here is that XOR will cancel entries that occur in both BDDs.
This is easily (but with exponential complexity) generalized to the case with several abstracted variables.

Can I represent a Red-black tree as binary leaf tree?

I've been playing around with RB tree implementation in Haskell but having difficulty changing it a bit so the data is only placed in the leaves, like in a binary leaf tree:
/+\
/ \
/+\ \
/ \ c
a b
The internal nodes would hold other information e.g. size of tree, in addition to the color of the node (like in a normal RB tree but the data is held in the leaves ony). I am also not needed to sort the data being inserted. I use RB only to get a balanced tree as i insert data but I want to keep the order in which data is inserted.
The original code was (from Okasaki book):
data Color = R | B
data Tree a = E | T Color (Tree a ) a (Tree a)
insert :: Ord a => a -> Tree a -> Tree a
insert x s = makeBlack (ins s)
where ins E = T R E x E
ins (T color a y b)
| x < y = balance color (ins a) y b
| x == y = T color a y b
| x > y = balance color a y (ins b)
makeBlack (T _ a y b) = T B a y b
I changed it to: (causing Exception:Non-exhaustive patterns in function ins)
data Color = R | B deriving Show
data Tree a = E | Leaf a | T Color Int (Tree a) (Tree a)
insert :: Ord a => a -> Set a -> Set a
insert x s = makeBlack (ins s)
where
ins E = T R 1 (Leaf x) E
ins (T _ 1 a E) = T R 2 (Leaf x) a
ins (T color y a b)
| 0 < y = balance color y (ins a) b
| 0 == y = T color y a b
| 0 > y = balance color y a (ins b)
makeBlack (T _ y a b) = T B y a b
The original balance function is:
balance B (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance B (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance B a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance B a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance color a x b = T color a x b
which i changed a bit as is obvious from my code above.
Thanks in advance for help :)
EDIT: for the kind of representation I'm looking, Chris Okasaki has suggested I use the binary random access list, as described in his book. An alternative would be to simply adapt the code in Data.Set, which is implemented as weight balanced trees.
Assuming you meant insert :: a -> Tree a -> Tree a, then your error probably stems from having no clause for ins (Leaf a).

How do I write ∀x ( P(x) and Q(x) ) in Coq?

I'm trying out Coq, but I'm not completely sure what I'm doing. Is:
Theorem new_theorem : forall x, P:Prop /\ Q:Prop
Equivalent to:
∀x ( P(x) and Q(x) )
Edit: I think they are.
Are you having problems with the syntax?
$ coqtop
Welcome to Coq 8.1pl3 (Dec. 2007)
Coq < Section Test.
Coq < Variable X:Set.
X is assumed
Coq < Variables P Q:X -> Prop.
P is assumed
Q is assumed
Coq < Theorem forall_test: forall x:X, P(x) /\ Q(x).
1 subgoal
X : Set
P : X -> Prop
Q : X -> Prop
============================
forall x : X, P x /\ Q x
forall_test <
Well, to answer your question:
Section test.
Variable A : Type. (* assume some universe A *)
Variable P Q : A -> Prop. (* and two predicates over A, P and Q *)
Goal forall x, P x /\ Q x. (* Ax, ( P(x) and Q(x) ) *)
End test.

Resources