6
$\begingroup$

I created this function:

AddStone[board_Graph, v_, s : white | black | empty] := 
   PropertyValue[{board, v}, VertexState] = s

This function should change the VertexState property of vertex v in graph board to one of white, black, or empty. That's simple enough, right? Then I created a graph:

board = GridGraph[{5, 5}];

But then if I execute:

AddStone[board, 8, white]

I get an error:

"Set::setraw: Cannot assign to raw object PropertyValue[{ ... ,8},VertexState]=white."

where the "..." stands for an image of the graph board, which I obviously need not draw here.

In the Documentation for PropertyValue it is stated that one can set properties this way. In fact, the code

PropertyValue[{board, 4}, VertexState] = white

does work without issuing any messages.

$\endgroup$
0

1 Answer 1

5
$\begingroup$

By default, a function evaluates it's arguments before plugging them into the function definition, so in effect AddStone is trying to set the property of the value of board instead of board itself. To get around this you could set the attribute HoldFirst which tells a function to substitute the unevaluated form of the first argument into the right-hand side. So for example

Clear[AddStone];
SetAttributes[AddStone, HoldFirst];
AddStone[board_ /; Head[board] === Graph, v_, s : (white | black | empty)] :=   
   (PropertyValue[{board, v}, VertexState] = s)

board = GridGraph[{5, 5}];

AddStone[board, 8, white]

PropertyValue[{board, 8}, VertexState]
$\endgroup$
9
  • $\begingroup$ An almost identical answer so I deleted mine. Just 1 minute difference... $\endgroup$ May 20, 2012 at 17:36
  • $\begingroup$ It works. But then I tried using board_Graph instead of board_ /; Head[board] === Graph and it didn't work. Why? $\endgroup$
    – a06e
    May 20, 2012 at 18:01
  • 1
    $\begingroup$ @becko Because with HoldFirst you're now not sending a Graph but a symbol referring to a Graph, which isn't the same. $\endgroup$ May 20, 2012 at 18:24
  • $\begingroup$ @SjoerdC.deVries Got it. $\endgroup$
    – a06e
    May 20, 2012 at 18:37
  • 1
    $\begingroup$ @becko But Set does have the attribute HoldFirst, so in PropertyValue[....] = new, the whole left-hand side is held, including the Graph object. $\endgroup$
    – Heike
    May 22, 2012 at 8:22

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.