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$

3 Answers 3

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, 2020 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, 2020 at 6:26
  • $\begingroup$ Seems it is my fault, I should formulate the goal more clearly. $\endgroup$ Sep 29, 2020 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, 2020 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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