1
$\begingroup$

I want a rule that would transform, for example, And[i,F[j,k],l,G[m,F[j,k],n],p] into And[i,F[j,k],l,G[m,T,n],p], where F, G and T are either just symbols or, say, defined by F[u_,v_]:=Or[F1[Or[Not[u],v],F2[v]] or G[x_,y_,z_]:=Or[G1[x,y],G2[z,x]] or T=H[False,True] or something even more complicated.

I have defined the following rule:

And[u___, x_, v___, y_, w___] :> And[u, x, v, y //. x -> T, w]

It never changes any expression. How should I do it properly?

$\endgroup$
1
$\begingroup$

Try this:

expr = And[i, F[j, k], l, G[m, F[j, k], n], p];
MapAt[ReplaceAll[#, F[j, k] -> T] &, expr, {4, 2}]

(*  i && F[j, k] && l && G[m, T, n] && p   *)

Have fun!

$\endgroup$
1
  • $\begingroup$ Sorry if this is not clear from the question, but any instances of such situation are needed. More precisely, whenever I have And[e1,...,en] which is not further simplifiable, and e1, ..., en are any expressions whatsoever, I want every occurrence of each ei in all of the other ej to be replaced by T. $\endgroup$ – მამუკა ჯიბლაძე Sep 28 '20 at 12:07
1
$\begingroup$
ClearAll[F]
in = And[i, F[j, k], l, G[m, F[j, k], n], p]
i && F[j, k] && l && G[m, F[j, k], n] && p
in2 = And[i, F[j, k], l, G[m, F[j, k], n], Nest[H, F[1], 5] + p]
i && F[j, k] && l && G[m, F[j, k], n] && p + H[H[H[H[H[F[1]]]]]]

1. You can use Replace with level specification {2, ∞}:

Replace[in, F[__] -> T, {2, ∞}]
i && F[j, k] && l && G[m, T, n] && p
Replace[in2, F[__] -> T, {2, ∞}]
i && F[j, k] && l && G[m, T, n] && p + H[H[H[H[H[T]]]]]

2. Alternatively, use TagSetDelayed to define behavior of F inside expressions with designated heads:

ClearAll[F];
F /: (head : G | H)[a___, F[__], b___] := head[a, T, b];

in
i && F[j, k] && l && G[m, T, n] && p
in2
i && F[j, k] && l && G[m, T, n] && p + H[H[H[H[H[T]]]]]
$\endgroup$
3
  • $\begingroup$ Thanks, this should work. Except that could not I encounter F on other levels too? And, in the second version, it will only work in G. $\endgroup$ – მამუკა ჯიბლაძე Sep 29 '20 at 6:26
  • $\begingroup$ Seems it is my fault, I should formulate the goal more clearly. $\endgroup$ – მამუკა ჯიბლაძე Sep 29 '20 at 6:32
  • 1
    $\begingroup$ @მამუკაჯიბლაძე, you can use the second approach more generally as (i) ClearAll[F]; F /: Except[And, head_][a___, F[__], b___] := head[a, T, b];in or as (ii) ClearAll[F]; F /: (head : G | H)[a___, F[__], b___] := head[a, T, b];in $\endgroup$ – kglr Sep 29 '20 at 6:40
0
$\begingroup$

Myself I tried something as general as possible. It would be great if somebody could optimize this, I feel it is far from perfect.

step[list_] := Module[{ul = Union[list], l, newl = {}, k, res},
  l = Length[ul];
  For[k = 1, k <= l, k++,
   AppendTo[newl, 
    ul[[k]] /. Table[ul[[j]] -> T, {j, Complement[Range[l], {k}]}]
    ]
   ];
  res = And @@ newl;
  Return[If[Head[res] === And, 
    Table[res[[k]], {k, Length[res]}], {res}]]
  ]
stab[list_] := FixedPoint[step, list]
myAnd[u___] := And @@ stab[{u}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.