Function Repository Resource:

FlattenAmbiguityList

Source Notebook

Restructure an expression with nested AmbiguityList expressions into a single flat AmbiguityList

Contributed by: Andrew Steinacher

ResourceFunction["FlattenAmbiguityList"][expr]

restructures expr as a single AmbiguityList.

ResourceFunction["FlattenAmbiguityList"][expr, n]

limits to no more than n possibilities.

ResourceFunction["FlattenAmbiguityList"][expr, n, crit]

limits to no more than n possibilities pi for which crit[pi] is True.

Examples

Basic Examples (2) 

AmbiguityList is often only wrapped around the ambiguous part of an expression:

In[1]:=
bessel12 = N@SemanticInterpretation["bessel(1,2)", AmbiguityFunction -> All]
Out[1]=

By moving the arguments inside the listed functions, all possible values can be computed directly:

In[2]:=
N@ResourceFunction["FlattenAmbiguityList"][bessel12]
Out[2]=

Interpreter can return nested AmbiguityList expressions that may be difficult to reason about:

In[3]:=
nested = Interpreter["HeldSemanticExpression", AmbiguityFunction -> All]["12 10 11"]
Out[3]=

Flatten the expression to see all possibilities in a single flat list:

In[4]:=
ResourceFunction["FlattenAmbiguityList"][nested]
Out[4]=

Scope (3) 

Ambiguous expressions can produce a large number of possibilities:

In[5]:=
ambiguous = SemanticInterpretation["boston, miami", AmbiguityFunction -> All]
Out[5]=
In[6]:=
ResourceFunction["FlattenAmbiguityList"][ambiguous] // First // Length
Out[6]=

Limit the number of distinct possibilities produced:

In[7]:=
ResourceFunction["FlattenAmbiguityList"][ambiguous, 10]
Out[7]=

Also limit to possibilities that pass a selection function:

In[8]:=
ResourceFunction["FlattenAmbiguityList"][ambiguous, 10, FreeQ["Massachusetts"]]
Out[8]=

Options (3) 

By default, only preexisting metadata is maintained during restructuring:

In[9]:=
congo = ResourceFunction["FlattenAmbiguityList"][
  AmbiguityList[{Entity["Country", "DemocraticRepublicCongo"], Entity["Country", "RepublicCongo"], Entity["Language", "KongoSanSalvador::9rdzh"], Entity["Language", "Koongo::9wqpj"], Entity["River", "Congo::zqkh9"], Entity["Movie", "Congo::mf7gc"], Entity["Word", "congo"]}]
  ]
Out[9]=

Add an entity type to descriptions for further clarity:

In[10]:=
flatCongo = ResourceFunction["FlattenAmbiguityList"][congo, "AddEntityTypeToDescription" -> True]
Out[10]=

Show metadata alongside possibilities:

In[11]:=
Grid[Thread[{#1, #3}] & @@ flatCongo, Frame -> All]
Out[11]=

Applications (3) 

Find all interpretations for a food using an ambiguous unit of "cup":

In[12]:=
oneCupFlour = Interpreter["SemanticExpression", AmbiguityFunction -> All][
  "1 cup all-purpose flour"]
Out[12]=

Flatten the expression to see each interpretation:

In[13]:=
flattened = ResourceFunction["FlattenAmbiguityList"][oneCupFlour]
Out[13]=

Compare calorie amounts for different interpretations of the unit:

In[14]:=
Sort@EntityValue[flattened[[1]], "AbsoluteTotalCaloriesContent", "NonMissingEntityAssociation"]
Out[14]=

Properties and Relations (5) 

Unambiguous expressions are not restructured:

In[15]:=
ResourceFunction["FlattenAmbiguityList"][{1, 2, 3}]
Out[15]=

An already-flat AmbiguityList is not restructured:

In[16]:=
ResourceFunction["FlattenAmbiguityList"][#] === # &[
 AmbiguityList[{Entity["Country", "DemocraticRepublicCongo"], Entity["Country", "RepublicCongo"], Entity["River", "Congo::zqkh9"], Entity["Movie", "Congo::mf7gc"], Entity["Language", "KongoSanSalvador::9rdzh"], Entity["Language", "Koongo::9wqpj"], Entity["Word", "congo"]}]]
Out[16]=

Expressions containing AmbiguityList in deeper parts of an expression will be moved to the top level:

In[17]:=
ResourceFunction[
 "FlattenAmbiguityList"][{123, AmbiguityList[{Entity[
     "City", {"Springfield", "Illinois", "UnitedStates"}], Entity["City", {"Springfield", "Missouri", "UnitedStates"}]}, "springfield"]}]
Out[17]=

If ambiguity is present, a selection function that produces no matches returns an empty AmbiguityList:

In[18]:=
ResourceFunction["FlattenAmbiguityList"][
 AmbiguityList[{{AmbiguityList[{"a1", "a2", "a3"}, "A"], AmbiguityList[{"b1", "b2", "b3"}, "B"]}}], All, FreeQ[_String]]
Out[18]=

When no ambiguity is present, the expression is left untouched:

In[19]:=
ResourceFunction["FlattenAmbiguityList"][{1, 2, 3}, All, FreeQ[_String]]
Out[19]=

Possible Issues (1) 

Sometimes ambiguous expressions can produce a large number of possibilities, which can take excessive memory and computation time:

In[20]:=
MemoryConstrained[
 Length@First@
   ResourceFunction["FlattenAmbiguityList"][
    SemanticInterpretation["springfield, boston", AmbiguityFunction -> All]],
 100*10^6
 ]
Out[21]=

Publisher

Andrew Steinacher

Version History

  • 2.0.0 – 07 December 2020
  • 1.0.0 – 13 November 2020

Author Notes

The use of None in the second argument of AmbiguityList is not documented… but it was the only way to follow the documented forms where the third argument contains metadata, but no uniform single string can be put into the second argument. An empty AmbiguityList is also undocumented, but is a natural use case when no possibilities are found that meet the criteria.

License Information