Commit 923b1fd5 authored by Uwe Köckemann's avatar Uwe Köckemann
Browse files

Initial commit

parents
temp/
__pycache__/
*~
#*#
.#*
*#
#*
.pyc
\ No newline at end of file
This diff is collapsed.
#+TITLE: The AIDDL Framework
The Artificial Intelligence Domain Definition Language (AIDDL) allows to model
AI problems, data and how AI methods are connected in order to solve
problems. This allows to create complex integrated AI systems by combining
robust and well-studied components.
* Overview
#+CAPTION: Overview of AIDDL components and interactions.
#+NAME: fig:overview
[[./material/figures/overview.png]]
AIDDL files represent modules containing type definitions (e.g., defining states
or goal for planning, instance for machine learning), data (e.g., concrete state
or goal for planning), functionality definitions (define computation based on
input and output types), as well as function compositions that implemented the
actual integrated system (functionality + control flow).
The [[file:core/README.org][Core Library]] implements AIDDL support for a programming language (parser,
data structures, evaluator). The [[file:common/README.org][Common library]] is a collection of AI type
definitions and algorithms that can be used for rapid prototyping of integrated
AI systems. The [[file:example/README.org][Example Library]] is a collection of example project that
demonstrate how AIDDL is used to create integrated AI systems. Examples use
implementations from the Common Library.
* Installation & Quick Start
Below you find (links to) instructions on how to:
1) Set the two environment variables AIDDL_PATH and AIDDL_WORK
2) Install the Core and Common libraries
3) Run the examples included in this repository
We use <AIDDL-ROOT> to refer to the folder containing this README file.
** Setting AIDDL_PATH and AIDDL_WORK
Modules in AIDDL_PATH can be imported by using their module name or filename
relative to path entries. AIDDL_WORK is the default working folder and is
used by some of our examples.
The following examples show how to add the aiddl path of org.aiddl.core and
org.aiddl.common to the AIDDL_PATH.
*** Linux
Add the following lines to the end of the ~/.profile file:
AIDDL_PATH="<AIDDL-ROOT>/common/aiddl/:<AIDDL-ROOT>/core/aiddl/"
AIDDL_WORK="<AIDDL-ROOT>/tmp/"
*** Windows
1) Navigate to: Computer -> Settings -> Advanced Settings -> Environment Variables
2) Add a new variable named AIDDL_PATH
3) Change the value of AIDDL_PATH to include the following folders:
- <AIDDL-ROOT>/core/aiddl
- <AIDDL-ROOT>/common/aiddl
You may have to restart applications to make sure they can use the newly set variable.
** Build & Install Core and Common Libraries
To install the Java version, follow the instructions in the following files:
- [[file:core/java/README.org][Java Core Library]]
- [[file:common/java/README.org][Java Common Library]]
** Run Examples
Follow the instructions in your example of choice:
- Example: [[file:example/learning-agent/README.org][Planning and Learning]]
- Example: [[file:example/planning-and-goal-inference/][Planning and Goal Inference]]
* AIDDL Files
An AIDDL file contains a module entry followed by any number of entries. There
are a few entries with a special meaning (as indicated by their types) and some
expressions can be evaluated. In the following we will go though each of these
in turn.
Everything in an AIDDL file is an entry. Below we discussed a few entries with
special types (~#mod~, ~#req~, ~#nms~, ~#def~).
A regular entry is a tuple with the form:
#+BEGIN_EXAMPLE
(t n v)
#+END_EXAMPLE
Here, the type ~t~ can be either a basic type (e.g., org.aiddl.type.integer), or a
type defined as described below. The name ~n~ is the name of the entry. Names are not
allowed to contain references. The value ~v~ can be any term.
** Basic Type Hierarchy
Everything written in AIDDL is a term. This section shows the basic type
hierarchy, gives a few examples, and provides the AIDDL reference name for each
type.
|--------------------+-----------------------------------+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------|
| Name | Reference | Description | Examples |
|--------------------+-----------------------------------+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------|
| Term | ~org.aiddl.term~ | Every AIDDL expression is a term. | see below |
| Symbolic | ~org.aiddl.term.symbolic~ | Non-numerical constants. | ~a~ ~e1~ ~+~ ~#integer~ |
| Boolean | ~org.aiddl.term.symbolic.boolean~ | Boolean constants | ~true~ ~false~ |
| Variable | ~org.aiddl.term.variable~ | Named variables beginning with ~?~ or anonymous variables ~_~ | ~?x ~?e1 ~_~ |
| String | ~org.aiddl.term.string~ | Any string of characters in quotes. | ~"a"~ ~"abc"~ ~"1 2 3"~ |
| Numerical | ~org.aiddl.term.numerical~ | Different types of numerical values. All numerical types can be compared and used in the same computation. | see below |
| Integer | ~org.aiddl.term.numerical.integer~ | Positive or negative integers. | ~0~ ~-3~ ~11~ |
| Rational | ~org.aiddl.term.numerical.rational~ | Positive or negative rational numbers. | ~0/1~ ~-1/3~ ~110/13~ |
| Real | ~org.aiddl.term.numerical.real~ | Positive or negative real numbers. | ~0.0~ ~-1.3~ ~1.1~ |
| Infinity | ~org.aiddl.term.numerical.inf~ | Positive or negative infinity. | ~INF~ ~+INF~ ~-INF~ |
| Collection | ~org.aiddl.term.collection~ | Collections of terms. | see below |
| Set | ~org.aiddl.term.collection.set~ | A set of terms. Cannot be matched to other terms. | ~{}~ ~{e1 e2 e3}~ ~{1 1 2}~ |
| List | ~org.aiddl.term.collection.list~ | A list of terms. | ~[]~ ~[e1 e2 e3]~ ~[1 1 2]~ |
| Tuple | ~org.aiddl.term.tuple~ | A tuple of terms. Unlike lists, we assume tuples will not be extended. | ~() ~(e1 e2 e3)~ ~(1 1 2)~ |
| Reference | ~org.aiddl.term.reference~ | A reference to an entry in a specific module. | ~e@m~ references entry named ~e~ in module ~m~ |
| | | | ~$e~ references entry named ~e~ in module where the reference appears (aka self reference) |
| Function Reference | ~org.aiddl.term.fun-ref~ | Reference to a function. Allows using functions as data. | ~^org.aiddl.eval.add~ ~^(lambda (?x ?y) (* ?x ?y))~ |
| Key-Value Pair | ~org.aiddl.term.key-value~ | A key and a value term. | ~x:10~ symbolic key ~x~ with integer value ~10~ |
| | | | ~?x:?y~ variable key ~?x~ with variable value ~?y~ |
| | | | ~x:y:z~ symbolic key ~x~ with key value pair ~y:z~ as a value |
** Grammar
The following grammar defines the AIDDL file format.
#+BEGIN_EXAMPLE
<AiddlFile> :: <Module> (<Entry>)*
<Module> :: "(#mod" <Symbolic> <Symolic> ")"
<Entry> :: "("<Term> <Term> <Term>")"
<Term> :: <Numerical> | <Collection> | <Tuple> | <Symbolic> | <String>
| <Variable> | <Reference> | <KeyValue>
<Numerical> :: <Integer> | <Rational> | <Real> | <Infinity>
<Collection> :: <List> | <Set>
<List> :: "[" <Term>* "]"
<Set> :: "{" <Term>* "}"
<Tuple> :: "(" <Term>* ")"
<Reference> :: <Term>"@"<Term> | "$"<Term>
<FunRef> :: "^"<Term>
<KeyValue> :: <Term>":"<Term>
<Symbolic> :: (("a"-"z"|"A"-"Z"|"#")("a"-"z"|"A"-"Z"|"0"-"9"|"_"|"."|"-"|"'")*)
|"+"|"-"|"/"|"*"|"&"|"|"|"!"|"="|"<"|">"|"=>"|"<=>"|"^"|"!="|"<="|">="
<String> :: "\"" [~\"]* "\""
<Variable> :: <NamedVariable> | "_"
<NamedVariable> :: ?(("a"-"z"|"A"-"Z")("a"-"z"|"A"-"Z"|"0"-"9"|"_"|"."|"-"|"'")*)
<Integer> :: ["-"]("0"|"1"-"9")("0"-"9"]*
<Rational> :: ["-"]("0"|"1"-"9")("0"-"9")* "/" ("1"-"9"("0"-"9")*)
<Real> :: ["-"] ("0"|"1"-"9")("0"-"9")* "." ("0"-"9")+
<Infinity> :: ["+"|"-"]"INF"
#+END_EXAMPLE
** Modules (#mod)
Modules are used to distinguish sets of entries based on their purpose.
Entry names may be reused across different modules but must be unique
in each module. Each AIDDL file is associated to a single module which is
indicated by its module entry. The module entry is always the first entry
in an AIDDL file. The entry
#+BEGIN_EXAMPLE
(#mod self org.aiddl.module)
#+END_EXAMPLE
has type ~#mod~, name ~self~, and value ~org.aiddl.module~. Here, the name
refers to the way in which the module refers to itself (usually we use the
symbolic term ~self~). The value is the way in which other modules refer to this
module (i.e. the global name of the module).
** Requirements (#req)
Requirements are used to allow AIDDL files to make local references to
other modules.
A requirement is an entry of type ~#req~:
#+BEGIN_EXAMPLE
(#req A "required.aiddl")
#+END_EXAMPLE
The name ~A~ of a requirement creates a local alias for the module found in the
required file. This alias can then be used in references instead of the full
name. Given the requirement above, the term ~e@A~ refers to an entry named ~e~
in the module stated in file ~required.aiddl~.
** Name Spaces (#nms)
Name spaces allow to avoid extensive usage of references. A name space is of
type ~#nms~. Applying a name space will substitute every occurrence of a name
with its value for each entry in the name space module.
A name space is an entry of type ~#nms~:
#+BEGIN_EXAMPLE
(#nms A "namespace.aiddl")
#+END_EXAMPLE
Including a name space will substitute all entries in the current module with
the values of the entries found in ~namespace.aiddl~.
Example:
Assuming ~namespace.aiddl~ contains the entry
#+BEGIN_EXAMPLE
(org.aiddl.term.symbolic + org.aiddl.eval.add)
#+END_EXAMPLE
and the current module has the entry
#+BEGIN_EXAMPLE
(org.aiddl.term.list L [+])
#+END_EXAMPLE
it will be replaced by
#+BEGIN_EXAMPLE
(org.aiddl.term.list L [org.aiddl.eval.add])
#+END_EXAMPLE
when the name space is applied.
Standard name spaces commonly used in our AIDDL examples are:
- [[file:definitions/eval.aiddl][eval.aiddl]] :: short names for predefined functions
- [[file:definitions/eval-ht.aiddl][eval-ht.aiddl]] :: same as eval.aiddl but uses names prefaced by a hashtag
- [[file:definitions/type.aiddl][type.aiddl]] :: short names for basic types
- [[file:definitions/type-ht.aiddl][type-ht.aiddl]] :: same as types.aiddl but uses names prefaced by a hashtag
** Definitions (#def)
A definition is an entry of type ~#def~. The name of a definition entry is
the name of the type it defines and its value is a function that can be evaluated to
determine if a term is an instance of the type. Functions may refer to their
argument by using the special term ~#self~.
The following type definition is satisfied by all integers between 0 and 10 (for
readability we assume name spaces ~eval.aiddl~ and ~type.aiddl~ are used):
#+BEGIN_EXAMPLE
(#def SmallInteger
(and
(type #self integer)
(>= #self 0)
(<= #self 10)))
#+END_EXAMPLE
* Support
Contact Uwe Köckemann (uwe.kockemann_at_oru.se) in case of questions,
suggestions, feature requests, bug reports.
* Acknowledgments
This work was supported by European Union H2020 Project [[https:www.ai4eu.eu][AI4EU]] under grant
agreement ID 825619 as part of Task 7.4 on Integrative AI.
#+TITLE: The AIDDL Common Library
The AIDDL Common Library contains type definitions, implementations and test
cases for many common AI algorithms. These implementations can be used as
building blocks for fast prototyping of integrated AI systems.
(#mod self org.aiddl.common)
(#nms EVAL "eval.aiddl")
(#def Map
(and
(type #self {list set})
(forall ?e #self
(and
(type ?e key-value) ))))
(#def MapGen
(match (?KT ?VT) #self
^(lambda ?M ($MapOf (?KT ?VT ?M)))))
(#def MapOf
(match (?KeyType ?ValueType ?Map) #self
(and
(type ?Map {^list ^set})
(forall ?k:?v ?Map
(and
(type ?k ?KeyType)
(type ?v ?ValueType)
)))))
(#def SetGen
^(lambda ?Set
($SetOf #self ?Set) ))
(#def (SetOf ?Type ?Set)
(and
(type ?Set ^set)
(forall ?e ?Set (type ?e ?Type))))
(#def ListGen
^(lambda ?List
(ListOf ?List #self) ))
(#def (ListOf ?Type)
(and
(type #self ^list)
(forall ?e #self (type ?e ?Type))))
(#def Composite
(match (?S ?Arg) #self
(and
(type ?S ^collection)
(forall ?e ?S (type ?Arg ?e))
)))
(#def KeyValuedType
^(lambda ?x
(forall ?k:?t #self
(call ?t (get-key ?k ?x))) ))
(#mod self org.aiddl.common.domain)
;; Finite sets of values & expressions that can be expanded into finite sets.
;; Domains are sets of key-values that attach value sets to types. Signatures
;; attach types to tuples (t1 t2 t3) or key-value pairs (t1 t2 t3):t4 This can
;; be used to limit the scope of legal assignments of atomics in logic or
;; state-variable assignments in planning.
(#namespace EVAL "eval.aiddl")
(#def EnumValues
(and
(type #self {#set #list})
(forall ?e #self
(type ?e { #symbolic #numerical #variable #string $DomainValues } )) ))
(#def IntegerValues
(and
(type #self #set)
(type (get min ?R) #integer)
(type (get max ?R) #integer) ))
(#def RationalValues
(and
(type #self #set)
(type (get min #self) #rational)
(type (get inc #self) #rational)
(>= (get inc #self) 0/1)
(type (get max #self) #rational) ))
(#def RealValues
(and
(type (get min #self) #real)
(type (get inc #self) #real)
(>= (get inc #self) 0.0)
(type (get max #self) #real) ))
(#def NumericalValues
(and
(type #self {
$IntegerDomain
$RealDomain
$RationalDomain})))
(#def TupleValues
(and
(type #self #tuple)
(forall ?e #self
(type ?e {symbolic $Domain}) )))
(#def KeyValueValues
(and
(type #self #key-value-pair)
(type (key #self) {symbolic $Domain})
(type (value #self) {symbolic $Domain}) ))
(#def DomainValues
(type #self
{ $Enum
$Numerical
$Tuple
$KeyValue }))
(#def Domains
(and
(type #self ^collection)
(forall ?X:?D #self
(and
(type ?D $DomainValues)))))
(#def TupleSignature
(and
(type #self ^tuple)
(forall ?e #self
(type ?e { ^symbolic } ) )))
(#def StateVariableSignature
(and
(type #self key-value)
(type (key #self) { ^$TupleSignature } )
(type (value #self) { ^symbolic } ) ))
(#def Signatures
(and
(type #self ^set)
(forall ?e #self (type ?e ^$TupleSignature ^$StateVariableSignature))))
(#mod self org.aiddl.common.learning.decision-tree)
(#nms EVAL org.aiddl.eval)
(#def Comparator (in #self {= < > >= <=}))
(#def Condition
(and
(type #self tuple)
(signature #self [$Comparator term term])))
(#def Decision
(and
(type #self tuple)
(signature #self [$Condition $DecisionTree])))
(#def DecisionTree
(or
(type #self #term)
(and
(type #self #list)
(forall ?e #self (type ?e Decision))
)))
(#mod self org.aiddl.common.learning.supervised)
(#nms EVAL org.aiddl.eval)
(#req T org.aiddl.common.domain)
(#req LA org.aiddl.common.math.linear-algebra)
(#def WildcardDomain
(= #self *))
(#def Attribute
(and
(type #self #tuple)
(signature #self [term {Domain@T $WildcardDomain}])))
(#def Attributes
(and
(type #self list)
(forall ?e #self
(type ?e $Attribute))))
(#def DataPoint (and (type #self list)))
(#def DataPoints
(and
(type #self {list set})
(forall ?e #self
(type ?e $DataPoint))))
(#def Problem
(and
(type #self tuple)
(match (attributes : ?Attributes label : ?Label data : ?Data) #self
(and
(type ?Attributes $Attributes)
(type ?Data $DataPoints)
(exists (?Label _) ?Attributes true)
(forall ?Datapoint ?Data
(and
(= (size ?Datapoint) (size ?Attributes))
(zip (?Att ?Val) [?Attributes ?Datapoint]
(match (?Var ?Domain) ?Att
(or
(= ?Domain *)
(in ?Val ?Domain)
)
)
)
)
)
)
)))
(#def ConfusionMatrix
(match (attributes : ?A matrix : ?M) #self
(and
(type ?A #list)
(type ?M Matrix@LA)
(= (size ?A) (size ?M))
(= (size ?A) (size (first ?M)))
)))
\ No newline at end of file
(#mod self org.aiddl.common.math.graph)
(#nms EVAL org.aiddl.eval)
(#req C org.aiddl.common)
;; Todo:
;; - Graph types (directed, ...)
;; -> Assemble from args? (Graph {directed weighted multi labeled})
(#def Node
(type #self ^term))
(#def Edge
(or
(type #self ^$UndirectedEdge)
(type #self ^$DirectedEdge) ))
(#def Label
(type #self ^term))
(#def UndirectedEdge
(and
(type #self {^tuple ^list ^set})
(type (get-key e #self) ^set)
(= (size (get-key e #self)) 2)
(forall ?e (get-key e #self)
(type ?e ^$Node) )))
(#def DirectedEdge
(and
(type #self {^tuple ^list ^set})
(exists e:?e #self
(and
(type ?e ^tuple)
(signature ?e [^$Node ^$Node])
(= (size ?e) 2) ))))
(#def LabeledEdge
(and
(type #self ^$Edge)
(exists label:?L #self
(type ?L ^$Label) )))
(#def WeightedEdge
(and
(type #self ^$Edge)
(exists w:?w #self
(type ?w ^numerical) )))
(#def Graph (type (^$Node ^$Edge #self) ^$TypedGraph))
(#def TypedGraph
(match (?NodeType ?EdgeType ?G) #self
(and
(type ?G ^tuple)
(match (V:?V E:?E) ?G
(and
(type ?V {^set ^list})
(forall ?v ?V (call ?NodeType ?v)) ;; (type ?v ?NodeType))
(forall ?e ?E
(and
(call ?EdgeType ?e) ;; (type ?e ?EdgeType)
(cond
(type ?e ^$UndirectedEdge) :
(contains-all ?V (get-key e ?e))
(type ?e ^$DirectedEdge) :
(and
(contains ?V (get-idx 0 (get-key e ?e)))
(contains ?V (get-idx 1 (get-key e ?e))) )))))))))
(#def Simple
(type (get-key V #self) ^set))
(#def Multi
(type (get-key V #self) ^list))
(#def Directed
(forall ?e (get-key E #self)
(type ?e ^$DirectedEdge) ))
(#def Undirected
(forall ?e (get-key E #self)
(type ?e ^$UndirectedEdge) ))
(#def Weighted
(forall ?e (get-key E #self)
(type ?e ^$WeightedEdge) ))
(#def Connected
(forall ?v1 (get-key V #self)
(forall ?v2 (get-key V #self)
(or
(= ?v1 ?v2)
(exists ?e (get-key E #self)
(= (get-key e ?e) {?v1 ?v2}) )))))
(#def Path
(and
(type #self ^list)
(forall ?n #self (type ?n ^$Node))))
(#def DistanceMap
(and
(type #self ^collection)
(forall ?k:?v #self
(and
(type ?k ^$Node)
(type ?v ^numerical) ))))
(#def PredecessorMap
(and
(type #self ^collection)
(forall ?k:?v #self
(and
(type ?k ^$Node)
(type ?v ^$Node) ))))
(#interface transpose (
uri : org.aiddl.common.math.graph.transpose
input : ^$Graph
output : ^$Graph
))
(#interface bellman-ford (
uri : org.aiddl.common.math.graph.bellman-ford
input : (KeyValuedType@C [graph:^$Graph start:^$Node target:^$Node])
output : (KeyValuedType@C [path:^$Path distance:^$DistanceMap predecessor:^$PredecessorMap])
))
(#interface depth-first-search (
uri : org.aiddl.common.match.graph.depth-first-search
input : $Graph
output : (KeyValuedType@C [
pi:^(MapGen@C ^$Node ^$Node)
distances:^(MapGen ^$Node ^numerical)
finish-times:^(MapGen@C ^$Node ^numerical)
components:^(SetGen@C ^(SetGen@C ^$Node)) ]
)