Abstract Wikipedia/Local keys

So far, we only allowed for global keys.

Global keys are of the form Z-Number-K-Number, i.e. a ZID followed by a KID, e.g. Z802K1.

Local keys omit the ZID and consist only of the KID, e.g. K1.

Local keys are useful when the function or type of the function call or object are created on the fly, since these don’t have global IDs. This is necessary to allow for generics.

We will implement support for local keys in two steps: allow declaring and using local keys, and using local keys as a shorthand.

Declaring and using local keys edit

First, we allow declaring and using local keys.

We can test it the following way.

Assume the existence of the following function Z10400 that creates a type:

{
  "type": "Function",
  "arguments": [{
    "type": "argument declaration",
    "argument type": "Type",
    "argument ID": "Z10400K1",
    "label": {
      "type": "multilingual text",
      "texts": []
    }
  }],
  "return type": "Type",
  "testers": [],
  "implementations": [ "Z10401" ],
  "identity": "Z10400"
}
{
  "Z1K1": "Z8",
  "Z8K1": [{
    "Z1K1": "Z17",
    "Z17K1": "Z4",
    "Z17K2": "Z10400K1",
    "Z17K3": {
      "Z1K1": "Z12",
      "Z12K1": []
    }
  }],
  "Z8K2": "Z4",
  "Z8K3": [],
  "Z8K4": [ "Z10401" ],
  "Z8K5": "Z10400"
}

With the following implementation:

{
  "type": "Implementation",
  "function": "Z10400",
  "composition": {
    "type":  "Type",
    "identity": {
      "type": "Function call",
      "function": "Z10400",
      "Z10400K1": {
        "type": "Argument reference",
        "argument ID": "Z10400K1"
      }
    }, 
    "keys": [{
        "type": "Key",
        "value type": {
          "type": "Argument reference",
          "argument ID": "Z10400K1"
        },
        "key ID": "K1",
        "label": {
          "type": "Multilingual text",
          "texts": []
        }
      }],
    "validator": "Default validator"
  }
}
{
  "Z1K1": "Z14",
  "Z14K1": "Z10400",
  "Z14K2": {
    "Z1K1":  "Z4",
    "Z4K1": {
      "Z1K1": "Z7",
      "Z7K1": "Z10400",
      "Z10400K1": {
        "Z1K1": "Z18",
        "Z18K1": "Z10400K1"
      }
    }, 
    "Z4K2": [{
        "Z1K1": "Z3",
        "Z3K1": {
          "Z1K1": "Z18",
          "Z18K1": "Z10400K1"
        },
        "Z3K2": "K1",
        "Z3K3": {
          "Z1K1": "Z12",
          "Z12K1": []
        }
      }],
    "Z4K3": "Z100"
  }
}

Then the following ZObject should be valid:

{
  "type": {
    "type": "Function call",
    "function": "Z10400",
    "Z10400K1": "String"
  },
  "K1": "test"
}
{
  "Z1K1": {
    "Z1K1": "Z7",
    "Z7K1": "Z10400",
    "Z10400K1": "Z6"
  },
  "K1": "test"
}

Note that in this case the function call describing the type evaluates to the following type:

{
  "type":  "Type",
  "identity": {
    "type": "Function call",
    "function": "Z10400",
    "Z10400K1": "String"
  },
  "keys": [{
    "type": "Key",
    "value type": "String",
    "key ID": "K1",
    "label": {
      "type": "Multilingual text",
      "texts": []
    }
  }],
  "validator": "Default validator"
}
{
  "Z1K1":  "Z4",
  "Z4K1": {
    "Z1K1": "Z7",
    "Z7K1": "Z10400",
    "Z10400K1": "Z6"
  },
  "Z4K2": [{
    "Z1K1": "Z3",
    "Z3K1": "Z6",
    "Z3K2": "K1",
    "Z3K3": {
      "Z1K1": "Z12",
      "Z12K1": []
    }
  }],
  "Z4K3": "Z100"
}

I.e. it describes a type that has one key of type Z6/String and the key is K1. This is exactly what is given by the ZObject above.

Using local keys as shorthand edit

In case the identity of the type or of the function in a function call of a ZObject is a simple reference, one can use local keys and both the normalization and canonicalization processes will expand them to global keys by prepending them to the local keys.

This allows for function calls and ZObject to have positional keys.

This feature can be dropped or implemented later.

I.e. the following value:

{
  "type": "String",
  "K1": "test"
}
{
  "Z1K1": "Z6",
  "K1": "test"
}

Will be canonicalized to:

{
  "type": "String",
  "value": "test"
}
{
  "Z1K1": "Z6",
  "Z6K1": "test"
}

The following function call:

{
  "type": "Function call",
  "function": "Z10400",
  "K1": "String"
}
{
  "Z1K1": "Z7",
  "Z7K1": "Z10400",
  "K1": "Z6"
}

Will be canonicalized to:

{
  "type": "Function call",
  "function": "Z10400",
  "Z10400K1": "String"
}
{
  "Z1K1": "Z7",
  "Z7K1": "Z10400",
  "Z10400K1": "Z6"
}