# How may I define e.g. Tilde[x,y] to have certain properties?

I would like to define, e.g., the Tilde[x,y] operator to have certain properties, and then investigate whether certain expressions involving that operator are True or not. For example, if I specify that x~x for all x, and I specify that x~y implies y~x, and I specify that x~y && y~z implies x~z, is it true that x~y && x~z implies y~z? That sort of thing.

I'm not sure how to specify the properties of Tilde[x,y] and not sure how to test a statement for truth, although I guess Simplify[] might work.

Any help would be welcome,

Thanks

Paul Reiser

Note that "~" is used in Mathematica for infix form of operators and it isn't the same as Tilde which could be inputted as [Esc]~[Esc]

ClearAll@Tilde

Tilde /: Tilde[x_, x_] := True

SetAttributes[Tilde, Orderless]

Tilde /: Tilde[x_, y_ ] && Tilde[y_, z_ ] := Tilde[x, z]


I added one more defenition to Tilde for the case when x, y are not the same

• Ah, good - that's just what I needed, thank you. The above three conditions on the Tilde[] operator should make it an equivalence relationship, but I try to show that by e.g. TrueQ[(x~y)=>(x==y)] and it returns False. (I'm using escaped ~ and ->). I will play around, trying to find out where I go wrong here, but if you have a quick answer, that would help. - Paul Reiser Jun 12, 2015 at 20:33
• really I don't understand what this syntax means TrueQ[(x~y)=>(x==y)] and Mathematica does so too) to check if the behavior of Tilde is similar to Equal some other test is requared, and I just noticed that Tilde doesn't knows what to do if x and y are unequal
– k_v
Jun 13, 2015 at 9:49
• I am having some trouble with the ~ operator as defined. It is known that if a binary operator is reflexive (x~x), symmetric (x~y=>y~x) and transitive ((x~y)&&(y~z)) => (x~z) then it is an equivalence (==). I would like to specify ~ as reflexive, symmetric, and transitive, and see that it gives a truth table identical to ==. For example, I woul like to replace "==" with "~" and get the same truth table for this: MatrixForm[Assuming[{a == b, a == c, a != d},Simplify[Table[x == y, {x, {a, b, c, d}}, {y, {a, b, c, d}}]]]] Jun 13, 2015 at 23:50
• look for update
– k_v
Jun 14, 2015 at 8:04
• This is still not right. I would like to specify Tilde as reflexive (a~a), symmetric (a~b=b~a) and transitive (a~b && b~c=>a~c) and have it behave then as an equivalence relationship. Right now, Jun 22, 2015 at 17:54

Here is an answer that is about as klugy as it can be, but very explicitly implements a binary relation. A binary relation on a list of variables (V) is a subset (S) of the set of all pairs {Vi,Vj}. V and S are external to all functions. There are three Boolean properties: reflexive, symmetric and transitive. Tilde[a,b] inserts {a,b} into S, and makes any other insertions necessary to assure that the properties that are True are obeyed by the binary relation. TildeTilde[a,b] tests whether {a,b} is a member of S. Tilde[a,b] is analogous to the Set[a,b] or "=" operator, TildeTilde[a,b] is analogous to the Equal[a,b] or "==" operator. Any more elegant solution would be greatly appreciated.

Tilde[a_, b_] := Module[{Change, SS},
If[Length[S] == 0, S = {{a, b}}, S = Append[S, {a, b}]];
If[Length[V] == 0, V = {a, b}, V = Union[Flatten[{V, a, b}]]];
SS = S;
Change = True;
While[Change, {
Change = False;
If[reflexive, SS = MakeReflexive[S]];
If[S != SS, Change = True];
S = SS;
If[symmetric, SS = MakeSymmetric[S]];
If[S != SS, Change = True];
S = SS;
If[transitive, SS = MakeTransitive[S]];
If[S != SS, Change = True];
S = SS;
}];
]

TildeTilde[a_, b_] := MemberQ[S, {a, b}]

MakeReflexive[S_] := Module[{n, nV, i, SS},   (* {a,a} True *)
SS = S;
n = Length[SS];
If[n > 0, {
nV = Length[V];
For[i = 1, i <= nV, i++, SS = Append[SS, {V[[i]], V[[i]]}]];
SS = Union[SS];  (* Remove duplicates *)
}];
SS
]

MakeSymmetric[S_] := Module[{n, i, SS},   (* {a,b} in S => {b,a} in S *)
SS = S;
n = Length[SS];
If[n > 0, {
For[i = 1, i <= n, i++, SS = Append[SS, {S[[i, 2]], S[[i, 1]]}]];
SS = Union[SS];  (* Remove duplicates *)
}];
SS
]

MakeTransitive[S_] := Module[{SS, n, i, j},  (* {a,c} in S and {c,b} in S => {a,b} in S *)
SS = S;
n = Length[SS];
If[n > 0, {
For[i = 1, i <= n, i++, {For[j = 1, j <= n, j++,
If[S[[i, 2]] == S[[j, 1]],
SS = Append[SS, {S[[i, 1]], S[[j, 2]]}]];
]}];
SS = Union[SS];  (* Remove duplicates *)
}];
SS
]

STable[S_] := Module[{n, i, j, table}, (* Generate truth table for binary relation *)
n = Length[V];
table = Array["?" &, {n, n}];
For[i = 1, i <= n, i++, {For[j = 1, j <= n, j++, {
If[V[[i]] \[TildeTilde] V[[j]], table[[i, j]] = 1,
table[[i, j]] = 0, table[[]] = "?"];
}]}];
MatrixForm[table]
]


So now I can test that a reflexive, symmetric, transitive binary relation yields an equivalence truth table:

Clear[a, b, c, d, e, f, x, y, S, V, reflexive, symmetric, transitive]
reflexive = True;
symmetric = True;
transitive = True;
V = {x, y}; (* include variables that might not be related to any other variable *)
a \[Tilde] b;
a \[Tilde] c;
d \[Tilde] e;
f \[Tilde] f;
Print["V=", V];
Print["S=", S];
STable[S]