Difference between revisions of "MetaIndex..Do"

Line 2: Line 2:
 
[[category:Meta-Inference Functions]]
 
[[category:Meta-Inference Functions]]
  
(new to 4.0 -- available starting 4.0.0.35)
 
  
= MetaIndex I := expr Do body =
+
== MetaIndex I := expr Do body ==
  
This declaration creates a local index object that does not evaluate its index elements when performing associative lookup, such as with [[Subscript]] or @[I=x].   
+
This declaration creates a local index object that does not evaluate its index elements when performing associative lookup, such as with [[Subscript]] or [[Subscript-Slice_Operator|@[I=x]]].   
  
A MetaIndex..Do declaration is identical to a [[Index..Do]] declaration except that the local index object created as the [[MetaOnly]] attribute set to 1.
+
A [[MetaIndex..Do]] declaration is identical to a [[Index..Do]] declaration except that the local index object created as the [[MetaOnly]] attribute set to 1.
  
 
Local indexes declared using MetaIndex are used in [[Meta-Inference]], and are a topic for advanced Analytica expert modelers.  For most modeling tasks, use [[Index..Do]].
 
Local indexes declared using MetaIndex are used in [[Meta-Inference]], and are a topic for advanced Analytica expert modelers.  For most modeling tasks, use [[Index..Do]].
  
= When to use =
+
== When to use ==
  
MetaIndex is most useful when performing [[Meta-Inference|meta-inference]] -- i.e. reasoning about variables. For example, if you want to work on a list of objects. If you used a simple Index, referring to that index will cause each variable mentioned to be evaluated. You usually don't need or want them to be evaluated when looking at the model structure, so a MetaIndex would be useful. See [[Meta-Inference|meta-inference]] to learn more about this advanced topic.
+
MetaIndex is most useful when performing [[Meta-Inference|meta-inference]] -- i.e. reasoning about variables. For example, if you want to work on a list of objects. If you used a simple Index, referring to that index will cause each variable mentioned to be evaluated. You usually don't need or want them to be evaluated when looking at the model structure, so a [[MetaIndex]] would be useful. See [[Meta-Inference|meta-inference]] to learn more about this advanced topic.
  
= Controlling the Index Name =
+
== Controlling the Index Name ==
  
 
It is possible to control the index name, which may be different from the local variable name referenced in the body.  The index name can even be computed dynamically.  The syntax for doing this is:
 
It is possible to control the index name, which may be different from the local variable name referenced in the body.  The index name can even be computed dynamically.  The syntax for doing this is:
  
  MetaIndex J / nameExpr := seqExpr do bodyExpr
+
:<big>MetaIndex J / nameExpr := seqExpr do bodyExpr</big>
  
Here nameExpr is evaluated and must result in a text string that contains a valid identifier.  The nameExpr is then used in the [[A.I]] notation.  The local name, J here, can be referenced within bodyExpr.   
+
Here «nameExpr» is evaluated and must result in a text string that contains a valid identifier.  The «nameExpr» is then used in the [[A.I]] notation.  The local name, «J» here, can be referenced within «bodyExpr».   
  
One instance where this control over the name is required is when you write a user-defined function that creates an N-dimensional array, where the dimensionality, N, is not known in advance.  Here you must loop over 1..N, creating a new local index during each iteration, but with a separate name each time.
+
One instance where this control over the name is required is when you write a user-defined function that creates an N-dimensional array, where the dimensionality, ''N'', is not known in advance.  Here you must loop over ''1..N'', creating a new local index during each iteration, but with a separate name each time.
  
= Examples =
+
== Examples ==
 
+
=== Sorting Objects ===
== Sorting Objects ==
 
  
 
The following creates a list of objects in module Report_A, sorted by identifier:
 
The following creates a list of objects in module Report_A, sorted by identifier:
  
MetaIndex objs := contains of Report_A;
+
:<code>MetaIndex objs := contains of Report_A;</code>
var v := objs;
+
:<code>var v := objs;</code>
Index Items := ['Identifier','Title','Description','Definition'];
+
:<code>Index Items := ['Identifier', 'Title', 'Description', 'Definition'];</code>
var a := Items;
+
:<code>var a := Items;</code>
var info := a of v;
+
:<code>var info := a of v;</code>
MetaIndex sortedObjects := sortIndex( info[Items='Identifier'] );
+
:<code>MetaIndex sortedObjects := sortIndex( info[Items = 'Identifier']);</code>
info[ objs = sortedObjects ]
+
:<code>info[ objs = sortedObjects]</code>
 
 
The first line is the salient one in this example.  Had this used the [[Index..Do]] declaration, rather than the [[MetaIndex..Do]] declaration, the variables in Report_A would have been evaluated when info[objs=sortedObject] was encountered (they would be evaluated only the first time an associative lookup on that index occurs).  Here the evaluation is avoided.
 
  
== Avoiding An Ambiguity ==
+
The first line is the salient one in this example.  Had this used the [[Index..Do]] declaration, rather than the [[MetaIndex..Do]] declaration, the variables in <code>Report_A</code> would have been evaluated when <code>info[objs = sortedObject]</code> was encountered (they would be evaluated only the first time an associative lookup on that index occurs).  Here the evaluation is avoided.
  
Associative lookup using an Index can be ambiguous if it contains a variable whose value is an atom. MetaIndex avoids that ambiguity. For example:
+
=== Avoiding An Ambiguity ===
  
Variable A := 5
+
Associative lookup using an Index can be ambiguous if it contains a variable whose value is an atom. [[MetaIndex]] avoids that ambiguity. For example:
Variable B := 2
 
Variable C := Handle(A)
 
Index I := [C, A, B, 2]
 
MetaIndex J := [A, B, 2, C]
 
  
@[I=2] &rarr; 3          { Ambiguous, could be 3 or 4, first is returned }
+
:<code>Variable A := 5</code>
@[J=2] &rarr; 4          { not ambiguous }
+
:<code>Variable B := 2</code>
 +
:<code>Variable C := Handle(A)</code>
 +
:<code>Index I := [C, A, B, 2]</code>
 +
:<code>MetaIndex J := [A, B, 2, C]</code>
  
@[I=Handle(A)] &rarr; { Ambiguous, could be 1 or 2 }
+
:<code>@[I = 2] &rarr; 3          { Ambiguous, could be 3 or 4, first is returned }</code>
@[J=Handle(A)] &rarr; { not ambiguous }
+
:<code>@[J = 2] &rarr; 4          { not ambiguous }</code>
  
= See Also =
+
:<code>@[I = Handle(A)] &rarr; 1  { Ambiguous, could be 1 or 2 }</code>
 +
:<code>@[J = Handle(A)] &rarr; 2  { not ambiguous }</code>
  
 +
== See Also ==
 
* [[Index..Do]]
 
* [[Index..Do]]
 
* [[MetaOnly]] attribute
 
* [[MetaOnly]] attribute
* [[Meta-Index]]
+
* [[MetaIndex]]
 
* [[Subscript/Slice Operator]]
 
* [[Subscript/Slice Operator]]
* [[MetaVar..Do]], [[LocalAlias..Do]]
+
* [[MetaVar..Do]]
 +
* [[LocalAlias..Do]]

Revision as of 00:39, 9 January 2016


MetaIndex I := expr Do body

This declaration creates a local index object that does not evaluate its index elements when performing associative lookup, such as with Subscript or @[I=x].

A MetaIndex..Do declaration is identical to a Index..Do declaration except that the local index object created as the MetaOnly attribute set to 1.

Local indexes declared using MetaIndex are used in Meta-Inference, and are a topic for advanced Analytica expert modelers. For most modeling tasks, use Index..Do.

When to use

MetaIndex is most useful when performing meta-inference -- i.e. reasoning about variables. For example, if you want to work on a list of objects. If you used a simple Index, referring to that index will cause each variable mentioned to be evaluated. You usually don't need or want them to be evaluated when looking at the model structure, so a MetaIndex would be useful. See meta-inference to learn more about this advanced topic.

Controlling the Index Name

It is possible to control the index name, which may be different from the local variable name referenced in the body. The index name can even be computed dynamically. The syntax for doing this is:

MetaIndex J / nameExpr := seqExpr do bodyExpr

Here «nameExpr» is evaluated and must result in a text string that contains a valid identifier. The «nameExpr» is then used in the A.I notation. The local name, «J» here, can be referenced within «bodyExpr».

One instance where this control over the name is required is when you write a user-defined function that creates an N-dimensional array, where the dimensionality, N, is not known in advance. Here you must loop over 1..N, creating a new local index during each iteration, but with a separate name each time.

Examples

Sorting Objects

The following creates a list of objects in module Report_A, sorted by identifier:

MetaIndex objs := contains of Report_A;
var v := objs;
Index Items := ['Identifier', 'Title', 'Description', 'Definition'];
var a := Items;
var info := a of v;
MetaIndex sortedObjects := sortIndex( info[Items = 'Identifier']);
info[ objs = sortedObjects]

The first line is the salient one in this example. Had this used the Index..Do declaration, rather than the MetaIndex..Do declaration, the variables in Report_A would have been evaluated when info[objs = sortedObject] was encountered (they would be evaluated only the first time an associative lookup on that index occurs). Here the evaluation is avoided.

Avoiding An Ambiguity

Associative lookup using an Index can be ambiguous if it contains a variable whose value is an atom. MetaIndex avoids that ambiguity. For example:

Variable A := 5
Variable B := 2
Variable C := Handle(A)
Index I := [C, A, B, 2]
MetaIndex J := [A, B, 2, C]
@[I = 2] → 3 { Ambiguous, could be 3 or 4, first is returned }
@[J = 2] → 4 { not ambiguous }
@[I = Handle(A)] → 1 { Ambiguous, could be 1 or 2 }
@[J = Handle(A)] → 2 { not ambiguous }

See Also

Comments


You are not allowed to post comments.