Result semantics and type mappings
Documentation status: reference — see Maturity and evidence.
A correct H-Logic client must understand both query cardinality and inherited type mappings. Do not assume every query returns a collection, and do not assume a subtype has the same visible role order as its parent.
Result cardinality
The query result contract is polymorphic:
- zero answers ->
nil; - one answer -> that value directly;
- several answers -> a linked conceptual list.
If the return expression itself constructs a tuple or list, the runtime preserves that shape rather than wrapping it in another singleton container.
ask .:#Person(p)[name='Ada'] return p;
ask .:#Person(p) return p;
ask .:#Person(p)[name=name] return (p, name);
Host bindings should normalize this contract deliberately rather than guessing from one successful test case.
Inherited instances
A subtype can reorder, project or identify roles from its supertype. A query through an ancestor may therefore return a mapped conceptual view that preserves the identity of the real descendant instance while presenting roles in the requested ancestor order.
define .:#Parent(left:#Value, right:#Value);
define .:#Child(first:#Value, second:#Value);
#Child ->_[map=#[[0,1],[1,0]]] #Parent;
Polyadic maps
A polyadic map is not just a permutation. Its normal form can represent projection, repeated positions and equality components. The normal polyadic map is the semantic source of truth; any positional cache is only a derived optimization when correspondence is unique.
Client rule
When projecting H-Logic results into .NET or another binding, preserve conceptual identity and use the Runtime-provided apparent role mapping. Never reconstruct a parent view by assuming raw slot positions.