Reputation: 1041
Hi I am trying to understand a part of code which is written by someone else. This is the definition of the proc:
proc defState {state_id attribute object_id value place args} {
global state_list state_objs state_attr_vals state_attr_id
# Build up record of defined states and perform error checking
if {[member $state_id $state_list]} {
put-error "ERROR: State $state_id is being defined twice"
#exit-steve
}
set state_list "$state_id $state_list"
if {![info exists state_attr_vals(${object_id},${attribute})]} {
set state_objs($object_id) $place
set state_attr_vals(${object_id},${attribute}) $value
} elseif {[member $value $state_attr_vals(${object_id},${attribute})]} {
put-error "WARNING: Multiple states with same object/attribute/value: $state_id"
} else {
set state_attr_vals(${object_id},${attribute}) \
"$value $state_attr_vals(${object_id},${attribute})"
}
set state_attr_id(${object_id},${attribute},${value}) $state_id
defSteveText $state_id goal "this should be generated by NL"
sp "top-ps*elaborate*state*add-to-current-state*$state_id
(state <s> ^problem-space.name top-ps
^current-state <cs>)
-->
(<cs> ^${state_id} <obj> + &, <n-obj> + &)
(<obj> ^id $state_id ^name $state_id
^type state
^polarity positive
^object-id $object_id
^attribute $attribute
^value $value
^negation <n-obj>)
(<n-obj> ^id $state_id ^name $state_id
^type state
^polarity negative
^object-id $object_id
^attribute $attribute
^value $value
^negation <obj>)"
;##### START TEMP GLUE #########
sp "top-ps*elaborate*state*test*goal*$state_id*positive
(state <s> ^problem-space.name top-ps
^current-state <cs>
^io.input-link.perception <p>
^mental-state <m>)
(<cs> ^${state_id} <pos>)
(<pos> ^polarity positive
^negation <neg>)
($place ^${object_id}_$attribute $value)
-->
(<neg> ^satisfied false + <)
(<pos> ^satisfied true + <)"
sp "top-ps*elaborate*state*test*goal*$state_id*negative
(state <s> ^problem-space.name top-ps
^current-state <cs>
^io.input-link.perception <p>
^mental-state <m>)
(<cs> ^${state_id} <neg>)
(<neg> ^polarity negative
^negation <pos>)
($place ^${object_id}_$attribute \{<val> <> $value <> *unknown* \})
-->
(<pos> ^satisfied false + <)
(<neg> ^satisfied true + <)"
sp "top-ps*elaborate*state*test*goal*$state_id*unknown
(state <s> ^problem-space.name top-ps
^current-state <cs>
^io.input-link.perception <p>
^mental-state <m>)
(<cs> ^${state_id} <neg>)
(<neg> ^polarity negative
^negation <pos>)
($place ^${object_id}_$attribute *unknown*)
-->
(<pos> ^satisfied unknown + <)
(<neg> ^satisfied unknown + <)"
global simulator_name
set sim_state ${object_id}_$attribute
if {[send $simulator_name "memberp ${sim_state} \$SceneAttributes"]} {
#echo "$state_sim already defined"
} else {
send $simulator_name "defSceneAttr $sim_state $sim_state symbol"
}
;##### END TEMP GLUE #########
And the implementation of the proc is given as follows:
defState bird-safe health bird healthy <p> \
:concerns {{sgt 25.0}} \
:initialize *unknown* \
:probability 0.55 \
:sim-object *none*
So what I do not understand is how does 'health', 'bird' and 'healthy' in the defState implementation corresponds to the variables in the proc definition.
And what is 'p' there?
I understand that it might be a confusing and probably vague question. But if anyone can help me that would be really great!
Thanks.
Upvotes: 1
Views: 160
Reputation: 71538
Well, if that's all there is to the proc
, there's not much going on.
You are passing some arguments to the proc
, which accepts 5 'standard' variables:
state_id
attribute
object_id
value
place
and any more variables on top of the 5 first will go in args
.
When calling the proc
, you are passing those strings into the variables above:
bird-safe
health
bird
healthy
<p>
:concerns {{sgt 25.0}} :initialize *unknown* :probability 0.55 :sim-object *none*
Of course, since $args
is a list, you will get those elements if you enumerate them:
:concerns
{sgt 25.0}
:initialize
*unknown*
:probability
0.55
:sim-object
*none*
Thus, in the proc
, you will have the above strings in the variables I listed earlier. You can see them if you use puts
within the proc
, and the results would be:
puts $state_id ;# gives => bird-safe
puts $attribute ;# gives => health
puts $object_id ;# gives => bird
puts $value ;# gives => healthy
puts $place ;# gives => <p>
puts $args ;# gives => :concerns {{sgt 25.0}} :initialize *unknown* :probability 0.55 :sim-object *none*
By default, variables are separated by space (the number of spaces doesn't matter, so I'm a bit confused as to why there's so much space between bird-safe
and health
), and it should be easy to see how each string gets into which variable.
global
is used to enable the use of variables existing in the global namespace or make local variables (those created in the proc) available to the global namespace. in your example, it is doing this for four variables: state_list
, state_objs
, state_attr_vals
and state_attr_id
.
For instance, if the variable state_list
exists in the global namespace, you will be able to access it within the proc. Without global state_list
being mentioned, you will get an error saying that the variable state_list
doesn't exists if you try to use it.
As for what is <p>
, well, it's just a string for what has been described in your question and nothing meaningful with limited information.
As per the addition to your question, you are calling other functions in the #TEMP GLUE#
part. For example, you will first have the substitution of variables, meaning this:
sp "top-ps*elaborate*state*test*goal*$state_id*positive
(state <s> ^problem-space.name top-ps
^current-state <cs>
^io.input-link.perception <p>
^mental-state <m>)
(<cs> ^${state_id} <pos>)
(<pos> ^polarity positive
^negation <neg>)
($place ^${object_id}_$attribute $value)
-->
(<neg> ^satisfied false + <)
(<pos> ^satisfied true + <)"
Will become this (I added ;# ^^^
to show the substitutions):
sp "top-ps*elaborate*state*test*goal*bird-safe*positive
;# ^^^^^^^^^
(state <s> ^problem-space.name top-ps
^current-state <cs>
^io.input-link.perception <p>
^mental-state <m>)
(<cs> ^bird-safe <pos>)
;# ^^^^^^^^^
(<pos> ^polarity positive
^negation <neg>)
($place ^bird_health healthy)
;# ^^^^ ^^^^^^ ^^^^^^^
-->
(<neg> ^satisfied false + <)
(<pos> ^satisfied true + <)"
Do you see how $state_id
became bird-safe
, ${object_id}_$attribute $value
became bird_health healthy
? The value of those variables were all defined at the beginning of the proc.
Note that ${abc}
is basically the same as $abc
. The advantage of using ${abc}
is that you can specify the exact variable name.
If you have a variable named abc
with value xyz
and use $abc_d
to output xyz_d
, tcl will look for the variable abc_d
and say that the variable abc_d
doesn't exists.
By using the braces, you explicitly tell Tcl that the variable name is abc
instead of abc_d
.
Upvotes: 2