#
# Copyright (C) 1999-2020. Christian Heller.
#
# This file lists arguments for certain design decisions.
# Its content may later be moved into the cyboi book
# or a cyboi FAQ on the website.
#
# Cybernetics Oriented Programming (CYBOP) <http://www.cybop.org/>
# CYBOP Developers <cybop-developers@nongnu.org>
#
# @version CYBOP 0.21.0 2020-07-29
# @author Christian Heller <christian.heller@cybop.org>
#

Design Decisions
================

Contents
________

Terminology
Language
Arithmetic Operands
HTML Formatting
Accessing Array Elements
Multiple Formats
Multi Channel Communication
Date Time
Socket
Receiving Data via Server Socket
Receiving Data via Client Socket
Allocation
Serialisation/Encoding/Compression/Sending
Encoding
Language and Format
Sensing Threads
Stack Memory
Knowledge Path
Container Operations
Comparison
Search
Arbitrary-precision arithmetic (Langzahlarithmetik)
Coupling of Objects
Pseudo Terminal
GUI Event Processing
Dynamic Typing
Hello World!

Terminology
___________

Fix terminology, e.g.:
- model and property, both of them are a part|node
- item
- array|data etc.

xml node|element|tag|attribute etc.

Language
________

the only difference between languages CLI and TUI is
that for CLI, the cursor position is NOT reset to the origo
since cursor positioning is NOT wanted for cli.

Arithmetic Operands
___________________

Question:
Is it possible to combine operands of type "integer" and "double" for an arithmetic operation?

Example:
    <!-- This example cuts off decimal places of the resulting number, since integer is used as type. -->
    <part name="divide" channel="inline" encoding="utf-8" language="text/cybol" format="calculate/divide" model="">
        <property name="result" channel="inline" encoding="utf-8" language="text/cybol" format="path/knowledge" model=".result"/>
        <property name="operand" channel="inline" encoding="utf-8" language="text/cybol" format="number/integer" model="2"/>
        <property name="type" channel="inline" encoding="utf-8" language="text/cybol" format="meta/type" model="number/integer"/>
    </part>

Answer:
It is NOT possible.
- cyboi uses void* types only for passing parametres around
- a type cast is done before executing an arithmetic operation
- the type could theoretically be read from each argument
- however, both arguments might have different types so that
  cyboi could not decide which operation to use and how to cast
- once, the result might be a double and the operand an integer,
  another time the other way around
- in the end it is the responsibility of the CYBOL developer
  to decide if he wants to work with integer or double values
- a combination of both worlds is not possible, nor necessary
- if needed, there is always the "cast/" operations in cybol

HTML Formatting
_______________

- a cybol constraint "indentation" of type "logicvalue/boolean"
  may be handed over to send/serialise operations that indicates
  whether or not generated html should be formatted
- a formatted file (indented and using more line breaks) is
  approximately three times as big as a "condensed" (non-formatted) one

- if formatting (pretty printing) is wanted, then pre-formatted tags
  might get indented, even though this is not wanted
- therefore, a cybol property "preformatted" of type "logicvalue/boolean"
  may be specified for each html node
- it is excluded from generated html attributes
- actually, it is not a good idea to give format-related properties
  on structure-related tags
- however, THIS IS THE BEST CHOICE, since no-break spaces also have
  to be specified directly
- one functioning alternative would be to filter for <pre> tags
- the problem is that nowadays, preformatting is mostly done via css
  classes whose name may vary, so that they cannot be filtered

Accessing Array Elements
________________________

The following is NOT necessary, since indices may be given to operations like "overwrite" or "add"
* Find solution for accessing single elements of an array from within cybol
--> possibly use "overwrite" operation and specify index as property
--> using a special knowledge path syntax like .settings.buffer[0] is probably NOT possible,
since a knowledge part (and not integer or character value etc.) is to be returned

Question:
Should the knowledge path be extended for accessing single array elements?

Example:
.variables.buffer[0]

Answer:
No, for two reasons.
a) The knowledge path always returns a part, never a primitive like integer etc.
b) The "modify/overwrite" operation has "index" properties, so that
   single elements of an array may be accessed.

Multiple Formats
________________

Question:
Should multiple formats (types) be allowed?
- separated by a pipe character
- as value of the "format" CYBOL attribute
- to be processed in this order, one-by-one in CYBOI

Example:
format="text/plain|UTF-8|tar|gzip"

Answer:
This is NOT necessary.
- there is a "format" attribute in CYBOL, e.g. number/fraction-vulgar
- there is an additional "language" attribute, e.g. text/html
- multiple translations can be handled as separate operations,
  by assigning the result of one translation to a tree node
  which serves as input to another operation
- similar to pipelining in UNIX

Multi Channel Communication
___________________________

- the libuv multi-channel communication library of Node.js was checked out
- it was decided not to use its ideas, since it is based on threads again
- the "select" function is NOT used either, since it works only with file descriptors, but not xcb etc.

- in cyboi, sensing threads are NOT used any longer
- instead, the main thread frequently queries all channels for available data (busy waiting)

Storing server and client service identification:

The communication client service identification is kept as variable in the
corresponding cybol application, as is done with the client socket, see:
examples/socket_server/handler.cybol: operation "communicate/receive", property: "sender"
examples/socket_server/logic.cybol: operation "communicate/send", property: "receiver"

The communication client service identification MAY be given (but does NOT have to)
as property for a "send" or "receive" cybol operation.
If it is NOT given as property, then a standard value of zero (0) is expected inside cyboi.
This applies e.g. for terminal communication where it would be tedious to always
have to specify a client terminal service identification.

Date Time
_________

There are dozens of calendars, historic and in use.
Most of them are based on the position of the sun or/and moon,
others on an era/epoch in which a certain king was ruling.
Neither CYBOI, nor any other system can support them all
with 100 % accuracy, since some epochs of kings can only
be estimated.
Decision: CYBOI will only support the most important calendars.

The modern calendar is the "Gregorian Calendar",
introduced by pope Gregor in the 16th century (1582-10-15).
Decision: Therefore, CYBOI has to offer this date representation.

Another often used calendar is the "Julian Calendar",
introduced by Julius Caesar around 40 B. C.
It was valid until the Gregorian Calendar was introduced.
Decision: CYBOI should additionally support also this date representation.

For computing and many sciences like astronomy etc. it is useful
to have a CONTINUOUS COUNTING of time. This is not the case
with calendars, since they use "leap days" and have inconsistencies,
e.g. the two weeks left out when the Julian was switched to
the Gregorian calendar.
Therefore, a so-called "Julian Day Number" (JDN) exists, which is
something different than the "Julian Calendar". It is the continuous
count of days since the beginning of the Julian Period, starting at
noon on January 1, 4713 BC proleptic Julian calendar, which is
equal to November 24, 4714 BC, in the proleptic Gregorian calendar.
The "Julian Date" (JD) of any instant is the Julian day number for
the preceding noon plus the fraction of the day since that instant.
Julian Dates are expressed as a Julian day number with a decimal
fraction added. For example, The Julian Date for 00:30:00.0
January 1, 2013 is 2456293.520833.
Decision: CYBOI does NOT use the Julian Date, since it is to be
represented as floating point number, which is not very efficient.

Another option is to use a single signed integer number which
increments every second.
This is done so in Unix-like and many other operating systems and
file formats and called "Unix time", or "POSIX time".
It is defined as the number of seconds that have elapsed since
00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970,
NOT counting leap seconds.
Modern Unix time is based on UTC, which counts time using SI seconds,
and breaks up the span of time into days almost always 86400 seconds
long, but due to "leap seconds" occasionally 86401 seconds.
This extra second keeps the days synchronized with the rotation
of the Earth, per Universal Time.
Due to its handling of leap seconds, it is NEITHER a linear
representation of time NOR a true representation of UTC.
When a leap second occurs, so that the UTC day is not exactly
86400 seconds long, a DISCONTINUITY occurs in the Unix time number.
When a leap second is inserted, the Unix time number increases
continuously during the leap second, and then jumps back by 1
at the end of the leap second. This leads to ambiguous Unix
time numbers that can refer either to the instant in the middle
of a leap second, or to the instant one second later.
Decision: CYBOI will use a signed integer number.

Generally, it is necessary to decide whether a time scale is counting:
1 calendar days:
- measurand: time-of-day [mean solar second]
- count of mean solar seconds (which are subdivisions of calendar days)
- determined by astronomy
- example: Julian Date (JD), Coordinated Universal Time (UTC)
- application: civil purposes, modern calendars, most legal systems of time
2 SI seconds:
- measurand: elapsed time interval [SI second]
- following atomic seconds (which are unrelated to calendar days)
- calendar becomes influenceable by politics
- example: Temps Atomique International (TAI)
- application: modern telecommunication, navigation systems
3 other effects:
- just recently, it was found that TAI is not quite accurate
- it was proposed by astronomers to observe effects of pulsars (stars)

UTC is a combination of the first two incommensurate concepts.
It only works fine through the concept of occasional "leap seconds".

Also POSIX tries to be both and as a result it cannot address leap
seconds meaningfully. The Realtime and Advanced Realtime extensions
to POSIX now offer two separate clocks:
http://pubs.opengroup.org/onlinepubs/007904975/basedefs/time.h.html

Decision: CYBOI will use TWO TIMES (separate clocks) internally:
1 Julian Date (JD) based on solar second
2 International Time (TI) or Temps Atomique International (TAI) based on SI second
--> both, JD and TI (or TAI) are determined using the Real Time Clock (RTC) on mainboard
    (Zählerstand Sekunden seit Unix-Epoche 1970)
Remark: auch Betriebssysteme führen eine interne Software-Uhr als Zähler und beziehen nur das Taktsignal via IRQ von der Hardware
Abgleich: erfolgt entweder (1) beim Booten mit Hardware-Uhr oder (2) fortlaufend mit Zeitserver via NTP

A "leap second" as well as "daylight/summer time" are decisions
by some humans to reset all of the clocks to comply with changes.
These two kinds of clock resets are extremely similar, and the
zoneinfo (or tz library) files and POSIX rules already have the
mechanisms for handling both. It now consists of two separate databases:

1 posix: considers a Unix time_t value to be equivalent to the number
of mean solar seconds since 1970-01-01; since 1972-01-01 its value
matches UTC except during leap seconds; every day has 86400 seconds;
for correct time this requires that the system clock be retarded or
reset backward at each leap second; this is the default provided
with most Unix systems, and it is most consistent with POSIX

2 right: considers a Unix time_t value to be equivalent to the count
of seconds actually broadcast in radio time signals since 1970-01-01;
it requires a file of leap seconds to be updated whenever a new one
occurs; for correct time this requires that the system clock
increment monotonically using TAI seconds; despite its name, this is
generally regarded as experimental and inconsistent with POSIX;
this was the branch of code which was briefly used by default in 4.4BSD Unix

There are two time scales which can reasonably be extrapolated back to 1601:
- Universal Time (UT): mean solar second
- Terrestrial Time (TT): SI second

However, UT in all its forms (including GMT) is actually a measure of
time-of-day, which is really the earth rotation angle, and should not
be used anymore, possibly for calculating historic dates, as an exception.

See:
http://en.wikipedia.org/wiki/Unix_Time
http://www.ucolick.org/~sla/leapsecs/timescales.html

Decision: CYBOI will use internal "zoneinfo" maps with information
similar to the "zoneinfo" (or tz library) database files in Unix.
UTC will be treated as timezone distinct from the underlying
operating system time, based on the broadcast time signals.
The only frequent change needed is to place the leap second
information into the internal "zoneinfo" maps, just like timezones.
That way, CYBOI will remain flexible even if broadcast time signals
abandon leap seconds and are based on atomic time only.

The relevant pieces of the POSIX 2008 specification are the definition
of tzset(), and the definition of environment variable TZ.
The only change needed in the POSIX spec is to substitute the
new name of an internationally-approved, uniformly-incrementing,
atomically-regulated broadcast time scale (e.g., "TI", as the
2003 Colloquium in Torino suggested) in place of the current "UTC".
This would allow the underlying system time to increment uniformly while
also allowing the time presented to humans to keep pace with the sun.
It would remove the need for the kernel to handle leap seconds.
It would remove the need for other coding hacks and code complexity
which try to work around the non-uniform timing hiccup which POSIX
compliance currently demands.

See:
http://pubs.opengroup.org/onlinepubs/007904975/basedefs/time.h.html
http://www.ucolick.org/~sla/leapsecs/right+gps.html

Decision: CYBOI will use International Time (TI) in the future,
which is likely to start in year 2022.
It is a candidate for radio broadcast time signals.
TI would be a purely atomic time scale offset from Temps Atomique
International (TAI) by a fixed integer number of seconds.
In order to avoid discontinuities for systems using radio
broadcast time signals the offset would be equal to the
offset of UTC at the instant of switching from UTC to TI.

Conversion:

http://www.astro-toolbox.com/
Julian Day --> any other: http://www.fourmilab.ch/documents/calendar/
TAI --> TT: http://cr.yp.to/libtai/tai64.html
Gregorian --> Julian Calendar: http://www.scribd.com/doc/28678552/Astronomische-Berechnungen
http://www.ortelius.de/kalender/calc_de.php

Definition:

http://de.wikipedia.org/wiki/Julianisches_Datum
http://de.wikipedia.org/wiki/Umrechnung_zwischen_Julianischem_Datum_und_Gregorianischem_Kalender
http://www.fourmilab.ch/documents/calendar/
https://en.wikipedia.org/wiki/System_time

Links:

http://de.wikibooks.org/wiki/Astronomische_Berechnungen_f%C3%BCr_Amateure/_Druckversion
http://de.wikipedia.org/wiki/Zeitrechnung
http://de.wikipedia.org/wiki/Proleptisch
http://de.wikipedia.org/wiki/Jahr_Null
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/GregorianCalendar.html
http://de.wikipedia.org/wiki/Datumsformat
http://de.wikipedia.org/wiki/ISO_8601
http://de.wikipedia.org/wiki/Uhrzeit

Timezone database (tz, zoneinfo):

http://www.twinsun.com/tz/tz-link.htm

Socket
______

Only one service may exist per port
server sockets are stored in internal memory
client sockets NOT -- they have to be stored in the corresponding cybol application
Implement session on application level (e.g. in Res Medicinae)

Only the server socket number gets stored in internal memory,
in order to be able to use it for communication
all other things (address, port etc.) are set inside the socket

Receiving Data via Server Socket
________________________________

For detecting available data, a server socket may use various techniques.

Solutions:

1 non-blocking mode

This IS the current solution in cyboi.
Not very efficient due to the "busy wait" loop, but it works.

2 poll(), select(), WSAAsyncSelect(), WSASelectEvent()

These functions are blocking and work only with file descriptors.
However, file descriptors do not exist for all kinds of communication
channels. For the x window system, for example, they do not.
But cyboi wants to serve other channels besides sockets as well
(terminal/tui, x-window-system/xcb/gui).

Therefore, this solution was NOT chosen.

3 self-made thread with blocking mode

This approach requires more overhead, an import of libpthread or
similar libraries and the handling of a special thread.

Since non-blocking mode is easier to implement, this solution was
NOT chosen for now. However, it may be an option for the future.

Receiving Data via Client Socket
________________________________

Data received via socket are stored in a buffer (array).
This happens in an endless loop, since more data than
the buffer can store might be available. Problem:
When there are no further data available, the recv() call blocks.

Solutions:

1 Non-blocking socket mode:

Used on the client side, it causes the recv() function to return
too fast and early, WITHOUT having received the data yet.

Therefore, blocking mode is necessary on the client side and
this solution was NOT chosen.

However, there are some exceptions: Advanced applications like
web browsers handle many connections being the client,
and often do non-blocking connect.

2 Delimiter on application level:

Stream sockets do not delimit messages. All data are an opaque byte stream.
One could implement that on application level, for example:
- a size field in the message header structure
or:
- using a delimiter such as '\n' for single-line text

However, cyboi is to be free of application-level logic.
Therefore, this solution was NOT chosen.

Reference:
https://stackoverflow.com/questions/3053757/read-from-socket

3 Peeking ahead available data:

Microsoft documentation states in several places that MSG_PEEK should
be avoided altogether because it were inefficient and inaccurate.
One is forced to call "recv()" twice.

Therefore, this solution was NOT chosen.
However, it could be a fallback solution if "ioctl" below does not work.

Reference:
https://stackoverflow.com/questions/11266783/recv-with-msg-peek-shows-full-message-but-returns-would-block-normally

4 Using ioctl() to query FIONREAD

This function call will return how many data are available.

The "ioctl" system call is supported by most Unix and Unix-like systems,
including Linux and macOS, though the available request codes
differ from system to system. Microsoft Windows provides a
similar function, named "DeviceIoControl", in its Win32 API.
https://en.wikipedia.org/wiki/Ioctl

#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

Example:

int len = 0;
ioctl(sock, FIONREAD, &len);
if (len > 0) {
    len = read(sock, buffer, len);
}

Reference:
https://www.gnu.org/software/libc/manual/html_node/IOCTLs.html
https://man7.org/linux/man-pages/man2/ioctl.2.html
https://stackoverflow.com/questions/3053757/read-from-socket
https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxbd00/ioctl.htm#ioctl

Allocation
__________

The size of array, item, part is NOT predictable at allocation time,
since it depends on the given type of contained elements.
Therefore, they may NOT be treated like a compound (e.g. datetime, duration)
and special allocation functions have been defined for them.

The size of complex, datetime, duration, fraction, io_entry is fixed,
which is why they may be treated as compounds and do NOT require
special allocation functions.

Serialisation/Encoding/Compression/Sending
__________________________________________

TERMINAL:

    <part name="print_terminal_message" channel="inline" format="communicate/send" model="">
        <property name="message" channel="inline" format="text/plain" model="Waiting for client requests ..."/>
            <property name="format" channel="inline" format="meta/format" model="text/plain"/>
            <property name="encoding" channel="inline" format="meta/encoding" model="utf-8"/>
            <property name="newline" channel="inline" format="logicvalue/boolean" model="true"/>
        <property name="language" channel="inline" format="meta/language" model="message/cli"/>
        <property name="channel" channel="inline" format="meta/channel" model="terminal"/>
    </part>

HTTP:
- meta header
- message

    <part name="send_http_request" channel="inline" format="communicate/send" model="">
        <property name="receiver" channel="inline" format="path/knowledge" model=".app.var.server_socket"/>
        <property name="message" channel="inline" format="text/plain" model="sayhello"/>
        <property name="metadata" channel="inline" format="path/knowledge" model=".app.var.metadata"/>
        <property name="compression" channel="inline" format="meta/compression" model="application/zip"/>
        <property name="compression" channel="inline" format="meta/compression" model="application/octet-stream"/> <!-- .arc, .ark, .sue -->
        <property name="encoding" channel="inline" format="meta/encoding" model="utf-8"/>
        <property name="format" channel="inline" format="meta/format" model="text/plain"/>
        <property name="language" channel="inline" format="meta/language" model="message/http"/>
        <property name="channel" channel="inline" format="meta/channel" model="socket"/>
    </part>

FTP:
- stateful control connection
- maintains current working directory and other flags
- each transfer requires a secondary connection (different port) through which the data is transferred

    <part name="send_ftp_command" channel="inline" format="communicate/send" model="">
        <property name="receiver" channel="inline" format="path/knowledge" model=".app.var.server_socket"/>
        <property name="message" channel="inline" format="text/plain" model="DELE"/>
        <property name="language" channel="inline" format="meta/language" model="message/ftp-control"/>
        <property name="channel" channel="inline" format="meta/channel" model="socket"/>
    </part>
    <part name="send_ftp_data" channel="inline" format="communicate/send" model="">
        <property name="receiver" channel="inline" format="path/knowledge" model=".app.var.server_socket"/>
        <property name="message" channel="inline" format="text/plain" model="somefile.bla"/>
        <property name="language" channel="inline" format="meta/language" model="message/ftp-data"/>
        <property name="channel" channel="inline" format="meta/channel" model="socket"/>
    </part>

Q: Should the send/receive operations be held simple, without properties for
serialisation/encoding/compression?

A1: NOT possible. Besides a sender or receiver at least a channel AND language have to be given.

A2: NOT useful. An encoding is neccessary for text (not byte) data.
Requiring the user to encode in cybol before calling "send" is tedious and unconvenient.
The same counts for compression. If channel and language have to be given anyway,
why not specifying the encoding and compression AT ONCE? Both are OPTIONAL anyway and not always needed.

==> Therefore, all of these properties are processed inside send/received.
The encoding must only be considered for text-, not for byte data.

Q: Is the separation of language + format really necessary?
Merge both into one if-else file?
If formats are different in languages, then offer one format per language?

The separation of language + format IS NECESSARY, since html and others
are destination languages and need element/part and simple data types as format.

Encoding
________

Use format "text/ascii" for data that are to be read byte-wise.
Do NOT use format "number/byte", since that will deserialise
text into comma-separated byte values.

Language and Format
___________________

language AND format are both necessary for deserialisation
e.g. a date may be represented differently, depending on the language
- XDT: 31.12.2015 (German format)
- CYBOL: 2015-12-31 (ISO format)
therefore, at first the language is determined, and only
afterwards the corresponding format deserialised

however, the deserialisers for many languages reuse
format deserialisers of the CYBOL language, e.g. for
deserialising integer numbers, since their format is mostly clear

Why is it NOT possible to always call "decode" before "deserialise"?
--> there are languages like HTTP that may contain byte code (e.g. an image)
and deserialising it would destroy data semantics

Why is it NOT possible to always call "deserialise" before "decode"?
--> if the source is given in a text language like XML, then that
has an encoding (e.g. ASCII or UTF-8 with many bytes representing one character)
ignoring the encoding and deserialising byte-by-byte would lead to wrong results

Therefore, an alternative solution considering both problems had to be found.
- text languages first HAVE TO BE decoded, in order to correctly identify characters and then deserialise them
- byte languages do NOT have to be decoded at all and may be deserialised directly

that means deserialiers for text languages have "wchar_t" as source input
and deserialisers for any other (byte) languages have "char" as source input
the output of a deserialiser is always a model

The text "decode" HAS TO BE treated differently from other "extract" byte encodings
(e.g. base64, gzip compression), because its result is always "wchar_t",
whilst other decodings deliver "char".
Therefore, the following chaining is NOT possible:
encoding="utf-8,gzip"
The following, on the other hand, IS POSSIBLE:
encoding="utf-8" compression="tar|gzip|base64"

Sensing Threads
_______________

Are not used anymore, due to different handling and difficulties
in the various operating systems.

// CAUTION! Moving the following code to an own thread in files
// "win32_display_sensor.c" and "message_win32_display_sensor.c"
// does NOT work, since the "PeekMessage" function
// checks the message queue of the CALLING thread ONLY.
//
// If it was called within an external "sensing" thread,
// then messages of the cyboi main thread
// (to which all windows belong) would never get recognised.
// Therefore, this main thread has to check for messages.

Stack Memory
____________

Three possible options for using local variables on stack have been evaluated:

1 Manual Creation

    <node name="create_stack_variables" channel="inline" format="memorise/push" model="">
        <node name="break" channel="inline" format="logicvalue/boolean" model="false"/>
        <node name="index" channel="inline" format="number/integer" model="1"/>
        <node name="count" channel="inline" format="number/integer" model="10"/>
        <node name="model" channel="file" format="element/part" model="counter_stack/model.cybol"/>
    </node>

Problem: The variables would have to be destroyed manually as well.
If forgotten, they might cause memory leaks.
Also, having to create stack variables manually using a
cybol operation seems complicated and annoying.

2 Model Properties

    <node name="execute_logic" channel="inline" format="flow/sequence" model="">
        <node name="model" channel="file" format="element/part" model="counter_stack/logic.cybol">
            <node name="break" channel="inline" format="logicvalue/boolean" model="false"/>
            <node name="index" channel="inline" format="number/integer" model="1"/>
            <node name="count" channel="inline" format="number/integer" model="10"/>
            <node name="model" channel="file" format="element/part" model="counter_stack/model.cybol"/>
        </node>
    </node>

Problem: The stack variables are not usable.
They are defined as child nodes of the "model" node ...

TODO?? Perhaps they ARE possible anyway?? Both, solution 2 and 3?

3 Part Properties

    <node name="logic" channel="file" format="element/part" model="counter_stack/logic.cybol">
        <node name="break" channel="inline" format="logicvalue/boolean" model="false"/>
        <node name="index" channel="inline" format="number/integer" model="1"/>
        <node name="count" channel="inline" format="number/integer" model="10"/>
        <node name="model" channel="file" format="element/part" model="counter_stack/model.cybol"/>
    </node>

Problem: This solution is only usable for compound logic parts
that have been defined beforehand in a cybol logic file.

TODO?? Perhaps they ARE possible anyway?? Both, solution 2 and 3?

Usage of solution 3 definition in a part at runtime:

    <node name="execute_logic" channel="inline" format="flow/sequence" model="">
        <node name="model" channel="inline" format="path/knowledge" model=".app.logic"/>
    </node>

Knowledge Path
______________

MIME Type for cybol knowledge paths: "text/cybol-path"

Symbols:

#   stack memory
.   knowledge memory model
:   knowledge memory properties
|   signal memory
*   part identified by reference, which reads the given path containing another path pointing to the actual model
()  part identified by name, which is given as path to a model of format "text/plain"
[]  part identified by index, which is given as path to a model of format "number/integer"

Memory Examples:

#           stack memory root
.           knowledge memory root model
:           knowledge memory root properties
|           signal memory root

Simple Examples:

#variable_on_stack
.path.to.model
.path.to:property
*.part.containing.path
**.double_reference.child_node

Part Access Examples:

.(.node.name).child.node
.(.node.(.nested.path.name)).subnode

.[#index_as_integer_on_stack]
.[.path.to.index_as_integer].some.child
.[.x.[.y]]

It is also permitted to give a string as index:
.model.[5]

Complex Examples:

.[.path.to.index_as_integer]
.[*#reference_to_an_index_on_stack]
:[**:some_property.subnode]
.app.addresses.[#loop_index]
.app.model.[.app.var.dialogue_number].label
**.part#property.[#index_on_stack].[*.node.index].node.(.node.name.(.nested.path.node)).(**.double_reference.node).link

CAUTION! It is NOT permitted to give an integer literal as index, e.g.: .model.[5]

Reasons:

- it was tried to implement this, but it would lead to improper source code
- cybol knowledge paths can be considered to consist of variables as in classical programmes
- variables with prefixes . and : reference heap memory
- variables with the prefix # reference stack memory
- literals are in general forbidden in cybol knowledge paths, all are variable names only
- in all cybol example applications written up to now, the index was used dynamically,
  coming from a variable -- so it does not seem necessary to introduce constant integer literals as index

- integer literals as index could be parsed and converted into a local variable without problem
- but since there is no actual knowledge model behind, the reference to a local variable would have to be returned (forbidden)
- returning the index is important for passing it to the next recursive call of function "deserialise_knowledge"
- of course, one could introduce an additional function argument (parametre) or allocate something additional,
  but this would be improper, blow up source code and make it dirty
- it just does not feel right or necessary

CAUTION! It is NOT permitted to use a path ending with dot or colon, e.g.:
.path.ending.with.model-dot.
.path.ending.with.property-colon:

Reasons:

- it seems tempting to use these for accessing all model nodes or all property nodes, as container
- however, internally to cyboi the "model" item and "properties" ITEM would have to be kept as pointer
- but all of cyboi relies on and processes PART nodes, consisting of items
- therefore, an additional property can be given to cybol container operations,
  in order to identify either the "model" or the "property" hierarchy of a node

Container Operations
____________________

- overwrite/copy: only allow deep copying, NOT shallow --> this avoids multiple pointers to one model and potential troubles with GC
- e.g. primitive models like an integer are always copied by VALUE and models of type "element/part" are always copied DEEP with their whole subtree
- move: it is not very efficient to handle this as: deep copy source model to destination + remove source, in case there is a large sub tree hanging on it

- therefore, as alternative, moving is using SHALLOW copying INSIDE
- add an optional property "move" as boolean to cybol operations "overwrite", "append", "insert"
- when move is true, then use SHALLOW copy, otherwise DEEP copy (default)
- the pointers are references in both cases (already checked), so no problem

- only child nodes are copied/moved, NOT the parent node
- however, the destination node always has to exist already
- then adapt cybol operations in "applicator/modify/"

Comparison
__________

Difference:
- standard comparison: delivers MANY results, one for each element in an array (vector), so that the result is again an array (vector)
- lexicographical comparison: delivers just ONE result

Implementation:
Implement lexicographical comparison in cybop directory called "src/executor/checker/"
ONLY for type "wide_character", since "lexicographical" in effect means "type wide_character".
If integer, double or fraction, a date-time etc. have to be sorted lexicographically,
then sort them INTERNALLY (for date using e.g. cyboi type "datetime") and
only AFTERWARDS, serialise them into type "wide_character" (string)!

Java:
- many programming languages (e.g. Java) return value -1 if lesser, 0 if equal, 1 if greater
- Java knows "equals" with boolean return value AND "compareTo" with int return value
- cyboi should better stick to a standard flag (0 or 1) as return value of the comparison

Operators:
- directory: "executor/comparator/"
- standard comparison operators are implemented: ==, !=, <, >, <=, >=
- others are possible in the future: ~ for "similar" etc.
- the cybol operations are called e.g. "compare/less-or-equal"
- the size of the result array gets extended to the one of the bigger input operand array

Dimension:
- two scalar numbers: direct comparison and just one result
- two vectors: elements get processed one by one and results (0 or 1) are written one by one into a vector (as done e.g. in MATLAB)
- similar to the cybol operation "calculate/add"
- two matrices: not represented by just one node (part), but by a tree of nodes (matrix-row-column or matrix-x-y-z), so that n-dimensional matrices are possible
- CAUTION! matrix comparison has to be implemented in cybol (!), not cyboi, e.g. using a comparison operation operand path like:
    .domain.matrix.[z].[y].[x]
- n dimensions (not only 3, but also more) are possible
- the cybol application developer has to use n nested loops for these n dimensions
- alternatively, n recursive calls using a new stack loop variable for each tree level
- possibly, provide a cybol library offering matrix comparison over n dimensions
- possibly, this library may be used for ANY comparison (?)
- the library always has to be instantiated using "communicate/receive" in memory before usage,
    since it will depend on stack variables, which only exist in the tree after having been instantiated

Lexicographical order:
https://en.wikipedia.org/wiki/Lexicographical_order#Numeral_systems_and_dates
- integer: an integer is larger than another one if either it has more digits (ignoring leading zeroes) or the number of digits is the same and the first digit which differs is larger
- real numbers written in decimal notation:
    - a slightly different variant of the lexicographical order is used
    - the parts on the left of the decimal point are compared as with integer
    - if they are equal, the parts at the right of the decimal point are compared with the lexicographical order
- negative numbers:
    - reverse the order for comparing negative numbers
    - testing the sign in computers takes some time
    - consider two's complement representation for representing signed integers
- string: array of "char" or "wchar_t"; use ASCII and UNICODE, i.e. alphabetical order
- date: represented as Julian Date (JD) integer in cyboi; YYYY-MM-DD etc. get converted into JD integer; thus, a simple number comparison suffices

Search
______

- the Java "String" class and other languages know methods like: startsWith, endsWith, subString, indexOf, contains
- these are also applicable to a vector of types like: int, double, char etc.
- provide corresponding cybol operations: search/prefix, search/suffix, search/subsequence, search/index
- the corresponding cyboi-internal function use "compare" functions as described above

Arbitrary-precision arithmetic (Langzahlarithmetik)
___________________________________________________

- Rechnen mit ganzen Zahlen beliebiger Länge
- Länge nur durch verfügbaren Arbeitsspeicher begrenzt
- numerischer Vergleich beginnt wie der lexikographische bei beiden Operanden am höchstrangigen Ende
- Rang einer Stelle nicht von ihrem Abstand vom höchstrangigen Ende bestimmt, sondern von ihrem Abstand vom niedrigstrangigen Ende, der "Einerstelle"
- vor dem Vergleich müssen also die Längen der beiden Operanden durch Auffüllen mit führenden Nullen angeglichen werden
- danach werden (beim numerischen wie beim lexikographischen Vergleich) gleiche Ränge in beiden Operanden miteinander verglichen
- Verarbeitungsrichtung: bei Division von hochrangig zu niedrigrangig; bei Addition, Subtraktion und Multiplikation jedoch umgekehrt

Coupling of Objects
___________________

- Qt signals & slots help avoid multiple inheritance and loosely couple objects
- the same can be achieved using cybol knowledge paths, based on tree / hierarchy

Pseudo Terminal
_______________

- Evaluate creation of pseudo-terminal (master-slave) again
- Use it in general and offer stdin/stdout as option?
- See: gnu_-_c_library.html#Pseudo_002dTerminals

Decision:

It is NOT useful to create pseudo terminals for now.

What might be useful in the future, is to have not just one
but possibly many terminal/console windows,
belonging to only one application, open at the same time.

However, opening these pseudo terminal windows works differently
not only in the single operating systems, but possibly also
on various desktops (KDE, GNOME, Xfce etc.)

GUI Event Processing
____________________

- events arrive in sensor
- they are read from the display as xcb event / win32 message
- they are stored in the input/output structure by the sensor (a directory stream/reader/display/ is therefore NOT necessary)
- an irq is set, so that the event may be stored as signal in the signal_memory
- direct reading of events is NOT intended, it works only and always via sensor and irq
- the event is stored temporarily by sensor in an input/output entry structure
- the gui_event_deserialiser writes the event's details into the message properties
- the order of function calls in the gui deserialiser is complete

Dynamic Typing
______________

- it would be possible to store all cybol application values (read from cybol-xml) as string inside cyboi (RAM)
- the casting to a special type would then happen in the moment the value gets used by an operation
- advantage: no more types ("format" xml attribute, given as mime type in cybol) would have to be given in cybol-xml, i.e. one attribute less
- disadvantages: slower reaction at runtime due to necessary type casts; binary values such as images would have to be stored as BASE64 inside cyboi and cause longer conversion time
- conclusion: no dynamic typing in cyboi; types have to be given in cybol; strings (read from cybol-xml) get converted into the special values (in RAM) at application startup

Hello World!
____________

There are several variants of the "Hello, World!" cybol application
to demonstrate the ease of cybol development and its slim code.
However, it is important to emphasise that it is NOT the task
of a programming language to provide the simplest possible solution
for an output a la "Hello, World!".
Any language following this path is actually a Domain Specific Language (DSL)
for the domain of printing "Hello, World!".

On the contrary, a programming language should be as flexible and
uniform as possible, in other words a General Purpose Language (GPL).
Of course, DSL may ease programming in certain application areas.
But if the aim is to create a schema and language capable of
representing knowledge in general, then a GPL should be the result.
CYBOL is such a GPL and reaches its flexibility by following
the principles of human thinking:
- discrimination (discrete part models)
- composition (parts are containers)
- categorisation (inheritance of part properties)

