Adding a tree to a list of trees within a loop [duplicate]

I'm trying to write a function which for a list of trees checks if a given tree is isomorphic with any of the listed, and if not - adds it to the list. I tried to use both Append and AppendTo, but they don't work ( I checked for non-isomorphic trees, and whole loop is executed, but nothing is added to the list).
Append doesn't seem to work at all (I mean outside of the loop), and AppendTo works outside, but doesn't work in loop.
What can be a problem here?

checkIsomorph[outList_, seedling_] :=
For[i = 1, i <= Length[outList], i++,
If[IsomorphicGraphQ[outList[[i]], seedling], Break[],
If[i == Length[outList], AppendTo[outList, seedling],
Continue[]]]]

-

marked as duplicate by Sjoerd C. de Vries, Öskå, Mr.Wizard♦Jul 17 '14 at 23:51

it would be nice if you give the input values you're using for testing the code, if append to is working outside the problem might be with If check if mathematica goes through the conditions. – Raymond Ghaffarian Shirazi Jul 16 '14 at 21:50
outList is just 3 random trees (with 10 vertices), and seedling is another random tree (also with 10 vertices). Mathematica goes through if - I added instructions to print a word in both cases (in inner If), and they are printed – RobertWalenty Jul 16 '14 at 21:58
try outLast=Insert[outList,seedling,Length[outList]] if it doesn't work, please add the whole code so I can test it myself. – Raymond Ghaffarian Shirazi Jul 16 '14 at 22:16
You should really go through some basic Mathematica tutorials first, it works very differently than you think it does. For your question at hand take a look at this post (and the whole thread in general!) – sebhofer Jul 16 '14 at 22:41
@RaymondGhaffarianShirazi - still does not work. When I rewrite it as you suggest I get message that lhs and rhs are "not the same shape" - I think that I cannot simply use "=" operator here. About the code - this is everything except declaration of outList and seedling. – RobertWalenty Jul 16 '14 at 23:22

You need non-standard evaluation for what you are trying to do. AppendTo needs the name (a symbol) of the list you are trying munge and has the attribute HoldFirst for that reason. For your function to pass that name to AppendTo, it must be given the HoldFirst attribute, too, and you must take care to ensure the unevaluated symbol gets passed to AppendTo.

Try this

data = RandomGraph[{5, 5}, 3];
checked = {};

SetAttributes[checkIsomorph, HoldFirst];
checkIsomorph[outList_Symbol, seedling_] :=
(For[i = 1, i <= Length[outList], i++,
If[IsomorphicGraphQ[outList[[i]], seedling], Return[True]]];
AppendTo[Unevaluated @ outList, seedling];
False)


First evaluation

checkIsomorph[checked, data[[1]]]

False

checked


Second evaluation

checkIsomorph[checked, data[[1]]]

True

-

Functional code is often encouraged over procedural code by experienced Mathematica users. For learning purposes, here's such a version:

checkIsomorph[start_: {}] := Module[{outList, check},
outList = start;
Function[
{seedling},
If[
(check = FreeQ[outList, _?(IsomorphicGraphQ[seedling, #] &)]),
AppendTo[outList, seedling]
];
check
]
]


Test:

graphs = RandomGraph[{5, 5}, 20];
func = checkIsomorph[];
selected = func /@ graphs
(* Out: {True, True, True, False, True, False, True, False, False, False,
False, False, False, False, False, False, True, False, False, False} *)


To retrieve the graphs that were added to the list (which is hidden from the global scope) you can use Pick:

Pick[graphs,selected]


I consider the fact that you can't access the list of selected graphs directly a feature. One of the advantages with functional programming is that it doesn't produce side effects (i.e. pollution of the global scope.)

-