# Thread[] seems to reset changes made with Manipulate[]

Recently I have been working on group theory and I have found checking for associativity for specific Cayley tables to be rather tedious so I wrote a program to do it for me. Most of the time I would make the Cayley tables first and then run the program to check if it is associative. However, I recently decided to put it all together into one Manipulate[] to speed up my productivity. By doing so though, things got a little glitchy. The problem I am having is with creating the rules. I think I managed to narrowed it down to one line of code(?) and so below is my code without the actual function for checking associativity, only the part which seems to make the program to malfunction.

alphabet = "IABCDEFGHJKLMNOPQRSTUVWXYZ";

Manipulate[
aList = StringJoin[#] & /@Tuples[Table[StringTake[alphabet, {n}], {n, letters}], {2}];
bList = Table["I",{letters},{letters}];
rules = Thread[aList -> Flatten[bList]]; (*If I comment out this line everything works fine*)
Row[{Grid[
Prepend[Map[Flatten[#] &,
Transpose[{Table[StringTake[alphabet, {n}], {n, letters}],
Table[With[{n = n, m = m},
PopupMenu[Dynamic[bList[[n, m]]],
Table[StringTake[alphabet, {o}], {o, letters}]]], {n,
letters}, {m, letters}]}]],
Prepend[Table[StringTake[alphabet, {n}], {n, letters}], ""]],
Dividers -> {2 -> True, 2 -> True}], Spacer[50],
Dynamic[bList]}], {letters, 1, 8, 1}]


When I run this program and set a value for a particular element in the grid; bList will update, but quickly switch back to it's initial state. However if I remove

rules = Thread[aList -> Flatten[bList]];


the value changes as it should. I tried placing Dynamic[] in various places without success. I'm not sure how to proceed, so any help on how to fix the problem would be greatly appreciated.

-

## 2 Answers

Does using RuleDelayed

rules = Thread[aList :> Flatten[bList]]


work for what you need?

EDIT: Although changing Rule to RuleDelayed solves the issue of dynamic updating of bList, rules=Thread[aList :> Flatten[bList]] does not produce the desired rule. Replacing this line with

 rules = (aList[[#]] :> Flatten[bList][[#]]) & /@ Range[Length[aList]];


produces the desired rule mapping elements of aList to elements of bList:

Manipulate[
aList = StringJoin[#] & /@
Tuples[Table[StringTake[alphabet, {n}], {n, letters}], {2}];
bList = Table["I", {letters}, {letters}];
rules = (aList[[#]] :> Flatten[bList][[#]]) & /@ Range[Length[aList]];
Column[{Grid[Prepend[Map[Flatten[#] &,
Transpose[{Table[StringTake[alphabet, {n}], {n, letters}],
Table[With[{n = n, m = m}, PopupMenu[Dynamic[bList[[n, m]]],
Table[StringTake[alphabet, {o}], {o, letters}]]], {n,
letters}, {m, letters}]}]],
Prepend[Table[StringTake[alphabet, {n}], {n, letters}], ""]],
Dividers -> {2 -> True, 2 -> True}],
Spacer[50],
Column[{Dynamic[aList], Dynamic[bList // MatrixForm],
Dynamic["II" /. rules], Dynamic["AB" /. rules]}]}],
{letters, 1, 8, 1}]


-
Same answer as mine - only you provide the picture, too... (+1) – Jens Aug 6 '12 at 2:13
@Jens , yes ... and about 2 minutes before yours :) – kglr Aug 6 '12 at 2:18
Thanks. However the rules doesn't seem to work if I try the simple ("II"/.rules). Instead it returns bList. – E.O. Aug 6 '12 at 3:00
@E.O., does  Dynamic["II" /. rules] produce what you need? – kglr Aug 6 '12 at 7:15
@E.O., I added an alternative approach that uses Map and RuleDelayed combination instead of Thread[...]. – kglr Aug 6 '12 at 9:17

I think what you want is for the rule to update all elements of aList when bList changes due to a change in letters. To achieve this, you have to make the assignment into a RuleDelayed:

alphabet = "IABCDEFGHJKLMNOPQRSTUVWXYZ";

Manipulate[
aList = StringJoin[#] & /@
Tuples[Table[StringTake[alphabet, {n}], {n, letters}], {2}];
bList = Table["I", {letters}, {letters}];
rules = Thread[
aList :>
Flatten[bList]]; (*If I comment out this line everything works fine*)
Row[{Grid[
Prepend[Map[Flatten[#] &,
Transpose[{Table[StringTake[alphabet, {n}], {n, letters}],
Table[With[{n = n, m = m},
PopupMenu[Dynamic[bList[[n, m]]],
Table[StringTake[alphabet, {o}], {o, letters}]]], {n,
letters}, {m, letters}]}]],
Prepend[Table[StringTake[alphabet, {n}], {n, letters}], ""]],
Dividers -> {2 -> True, 2 -> True}], Spacer[50],
Dynamic[bList]}], {letters, 1, 8, 1}]


The only change with respect to your original code is that I defined

rules = Thread[aList :> Flatten[bList]]


where :> is RuleDelayed.

-