Syntax and Notation#
Keywords#
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
All keywords in this standard are case-sensitive.
Syntax Used in this Document is YAML#
The PALS schema standard does not define any particular language to implement a lattice. Rather, there are associated language specific standards that define grammars for YAML, JSON, Python, etc. Along with these associated standards, there are packages that implement translation between lattice files and a representational internal format defined by the package.
While the standard itself is language agnostic, this document that describes the standard needs to use some syntax and this syntax is based upon YAML. YAML is formally defined and there are tutorials to learn YAML.
YAML 101#
In particular, there are dictionaries, which are unordered sets of key-value pairs, e.g.:
this_dictionary:
key1: value1
key2: 2.0
key3: true
{"this_dictionary": {
"key1": "value1",
"key2": 2.0,
"key3": true
}}
[this_dictionary]
key1 = "value1"
key2 = 2.0
key3 = true
{"this_dictionary": {
"key1": "value1",
"key2": 2.0,
"key3": True
}}
// insertion-order preserving dictionary
// alternatives: boost::multi_index_container, ryml::Tree, nlohmann::ordered_map, ...
using Dict = std::vector<std::pair<std::string, std::any>>;
Dict this_dictionary = {
{"key1", "value1"s},
{"key2", 2.0},
{"key3", true}
};
using OrderedCollections
this_dictionary = OrderedDict(
"key1" => "value1",
"key2" => 2.0,
"key3" => true
)
And lists, which are ordered sets of items, e.g.:
this_list:
- entry1
- entry2
- more_entries
{"this_list": [
"entry1",
"entry2",
"more_entries"
]}
this_list = [
"entry1",
"entry2",
"more_entries"
]
{"this_list": [
"entry1",
"entry2",
"more_entries"
]}
std::vector<std::string> this_list = {
"entry1",
"entry2",
"more_entries"
};
this_list = [
"entry1",
"entry2",
"more_entries"
]
One can nest dictionaries into lists and other dictionaries, e.g.:
this_list:
- key1: value1
key2: value2
- named_dictionary:
key3: value3
key4: value4
{"this_list": [
{"key1": "value1",
"key2": "value2"},
{"named_dictionary": {
"key3": "value3",
"key4": "value4"
}}
]}
[[this_list]]
key1 = "value1"
key2 = "value2"
[[this_list]]
[this_list.named_dictionary]
key3 = "value3"
key4 = "value4"
{"this_list":
[
{"key1": "value1",
"key2": "value2"},
{"named_dictionary":
{"key3": "value3",
"key4": "value4"}
}
]
}
std::vector<std::any> this_list = {
Dict{{"key1", "value1"s}, {"key2", "value2"s}},
Dict{{"named_dictionary", Dict{
{"key3", "value3"s}, {"key4", "value4"s}
}}}
};
using OrderedCollections
this_list = [
OrderedDict("key1" => "value1", "key2" => "value2"),
OrderedDict("named_dictionary" => OrderedDict(
"key3" => "value3", "key4" => "value4"
))
]
Note
Developer note: PALS dictionaries should, when possible, implement a dictionary that preserves insertion order.
While not strictly necessary, this helps with human readability:
For example, having the kind key of an element as the first attribute enhances legibility.
File Formats#
The PALS schema can be implemented in a variety of file formats.
It is highly recommended that the following self-describing file suffixes be used for
top-level PALS files (files that contain the root PALS node):
For sub-level included PALS format files, replace .pals with .subpals.
Note: Not following the recommendation may lead to, for example, reader/visualization tools not auto discovering the file as PALS, which can create friction for users.
Schema Files#
Schema files for validation have not yet been developed. A validation tool based on pydantic is in development. See the Libraries section.