top of page

 MELBOURNE
language introduction

The official source

Logo 1024x1024.png

What you need to know to start

WHAT IS MELBOURNE ? 

 

A rule engine inspired by Prolog : easy to write and read, powerful and flexible.

            

WHY MELBOURNE ?

 

For fun

WHO DEVELOPED MELBOURNE ?

Franck DANSAERT, in 2022, on his spare time in addition to music composition.

WHERE CAN I TRY MELBOURNE ?

The Melbourne Sandbox has been developed for iPad and is compatible with MacOS. You can download the application at the link below :

https://apps.apple.com/fr/app/melbourne-sandbox/id6443409136

MELBOURNE IS BASED ON THREE CONCEPTS

            

  1. Knowledge

  2. Atom

  3. Rules

            

A KNOWLEDGE is composed of Atoms separated by whitespaces

            

// Example

Leia is the sister of Luke

            

AN ATOM is either a fact, a variable or a function.

            

An atom in small cap or capitalised or using a symbol is considered as a fact (ex: Leia, Luke, &, <, etc.)

An atom in uppercase is a variable (ex: X, TITLE, etc.)

            

An atom starting with the character $ is a pre-defined function (ex: $add<Int>, $modulus<Int>, etc.)

 

AN ATOM CAN BE IDENTIFIED by atoms using parenthesis and comma. We use identifiers when we are talking about things in general and the listener/reader does not know exactly what we are referring to.

            

// Examples of atoms with identifiers

Leia(age(20),weight(52),name(Skywalker))

 

RULES explain how to infer knowledge from existing or inferred knowledges. A rule can be defined using variables and functions using the following format.

            

// Example 1:

   

X is therefore Y:

X is Z

Z is Y

            

//  Example 2:

X is the sister of Y:

X is a girl

The mother of X is Z

The mother of Y is Z

            

// Example 3:

            

X(Age(Y)) can drink:

$greater<Int>(Y,18)

            

KNOWLEDGE AND RULES are edited in the editor located in the upper screen. You can write for instance in the "Knowledge & Rules" editor the following text.

            

X is therefore Y:

X is Z

Z is Y

            

Franck is Human

Human is Mortal

            

THE COMMANDS are entered in the editor located in the lower screen. This is where you access the knowledge and query Melbourne. The query is a knowledge or infered knowledge using variables. Melbourne will infer all the possible values of the variables consequently once the "Enter" key pressed. Each query should end with a question mark ("?"). Some examples hereafter using the previous example.

            

Franck is X ?

// returns [X=Human]

            

X is Y ?

// returns  [Y=Human, X=Franck] or [Y=Mortal, X=Human]

            

Franck is therefore Y ?

// returns [Y=Mortal]

            

 COMMAND CAN ANSWER COMPLEX QUERIES as the given example hereafter

            

// KNOWLEDGE & RULES

            

Kenobi(age(20))

Anakin(age(9))

            

X can drink:

X(age(A))

$greater<Int>(A,18)

            

// COMMAND

            

X can drink ?

// returns [X=Kenobi]

            

ALTERNATIVE RULES CAN BE DEFINED to handle different scenarios.

            

// KNOWLEDGE & RULES

            

The car is light blue

The scooter is yellow

            

light blue is a color

yellow is a color

            

The color of the OBJECT is COLOR:

The OBJECT is X

X is a color

COLOR = X

            

The color of the OBJECT is COLOR:

The OBJECT is X1 X2

X1 X2 is a color

COLOR = $add<String>(X1,X2) // please note that you cannot use a whitespace to separate X1 and X2 : whitespace separates Atoms and cannot be used in an Atom's name

            

COMMAND

            

The color of the scooter is X ? // returns [X=yellow]

The color of the car is X ? // returns [X=lightblue]

            

 RULES can be formulaed as question as illustrated hereafter :

            

Rhodri reigned between years 844 and 878

 

WHEN X reigned:

X reigned between years X1 and X2

WHEN = $add<String>(X1,-,X2)

            

WHEN Rhodri reigned ? // returns [WHEN=844-878]

            

 HOW TO INTERPRET THE RESULTS :

            

If the command returns false, it means that either the statement is false or there is no solution to the assertion. For instance, using the given example above :

            

Kenobi(age(30)) ?

// will return false, because the age of Kenobi is 20 and not 30

            

Kenobi(weight(X)) ?

// will return false, because there is not solution to this assertion as no weight has been given

            

If the command returns true, it means that the statement is true ! For instance :

            

Kenobi(age(20)) ?

// will return true, because the age of Kenobi is 20 indeed

            

COMMENTS can be added in the Knowledge & Rules editor using the "//" symbol : all the text after this symbol will be ignored.

            

THE "=" and "!=" SYMBOLS have been defined, not as an allocation command but as an equality & difference test. For instance it is possible to write the followings :

 

// RULES

Z = X + Y:

Z = $add<Int>(X,Y)

Z = X +Y:

X = $subtract<Int>(Z,Y)

// COMMANDS    

X = 10 + 1 ?

// will return [X=11]

            

11 = X + 2 ?

// will return [X=9]

            

 These symbols are in fact rules which have been coded by default in Melbourne. These rules are given hereafter for education purpose to show how to define your own symbols

            

X = X:

true

    

X != Y:

$not<Bool>($equal<String>(X,Y))

THE "@" SYMBOL has been defined to confirm if an atom is an identifier of an Atom. Hereafter some examples.

Skywalker(Anakin,Lea,Luc)

Anakin @ Skywalker ? // returns true

X @ Skywalker ? // returns [X=Anakin] or [X=Leia] or [X=Luc]

Lightsabers(Darthvador(red),Luc(green))

Darthvador(COLOR) @ Lightsabers ? // returns [COLOR=red]

The @ symbol can be used to implement complex function such as the following :

// KNOWLEDGES

bike is assembly of parts(wheel,frame)

frame is assembly of parts(rearframe,frontframe)

rearframe is assembly of parts(bolt,nut)

 

basicpart(wheel)

basicpart(bolt)

basicpart(nut)

basicpart(frontframe)

// RULES

PART is part of X:

X is assembly of Y

SYSTEM @ Y

PART is part of SYSTEM

PART is part of X:

X is assembly of Y

PART @ Y

basicpart(PART)

//COMMANDS

X is part of bike ? // returns [X=bolt] or [X=wheel] or [X=frontframe] or [X=nut]

nut is part of X ? // returns [X=rearframe]

THE "..." SYMBOL defines none, one or more consecutive Atoms. This symbol can be used if only the beginning of a Knowledge has to be considered in a rule. Herefater an example. Please note that atoms mentionned or defined after these supension points will be ignored.

The car is big and fast

            

The OBJECT is X1:

The OBJECT is X1 ...

 

The car is X ? // returns [X=big]

The DEBUG ? command can be used to check the syntax correctness of the knowledges and rules. It will warn you about possible infinite loops, misspelled knowledge, etc. The debug functions are still limited but will help you to avoid basic mistakes. To debug your code, type in the command window :

            

DEBUG ?

               

 SOME FUNCTIONS have been coded at this stage

 

Manipulating Integer

            

$add<Int>           $add<Int>(10,20,30)         // returns 60 (10+20+30)

$subtract<Int>      $subract<Int>(100,20,30)    // returns 50 (100-20-30)

$product<Int>       $product<Int>(2,3,4,5)      // returns 60 (2*3*4*5)

$max<Int>           $max<Int>(2,3,4)            // returns 4

$min<Int>           $min<Int>(2,3,4,5,10,20)    // returns 2

 $modulus<Int>       $modulus<Int>(10,3)         // returns 1 (10%3)

$equal<Int>         $equal<Int>(10,10)          // returns true

$smaller<Int>       $smaller<Int>(2,3,4,5,6)    // returns true (2<3<4<5<6)

$greater<Int>       $greater<Int>(10,5,3)       // returns true (10>5>3)

Manipulating Double

            

$add<Double>            $add<Double>(10.0,20.0,30.0)         // returns 60.0 (10+20+30)

$subtract<Double>       $subract<Double>(100.0,20.0,30.0)    // returns 50.0 (100-20-30)

$product<Double>        $product<Double>(2.0,3.0,2.0)        // returns 12.0 (2*3*2)

$divide<Double>         $product<Double>(1.0,2.0,2.0)        // returns 0.25 (1/2/2)

$max<Double>            $max<Double>(2.0,3.0,4.0)            // returns 4.0

$min<Double>            $min<Double>(2.0,3.0))               // returns 2.0

$equal<Double>          $equal<Double>(10.0,10.0)            // returns true

$smaller<Double>        $smaller<Double>(2,3,4,5,6)          // returns true (2<3<4<5<6)

$greater<Double>        $greater<Double>(10,5,3)             // returns true (10>5>3)

 

Manipulating String

 

$add<String>        $add<String>(toto,tata,titi)             // returns tototatatiti

$equal<String>      $equal<String>(tutu,toto)                // returns false

$smaller<String>    $smaller<String>(franck,victor,zozo)     // returns true (franck<victor<zozo)

$greater<String>    $greater<String>(Z,B,A)                  // returns true (Z>B>A)

            

Manipulating Boolean

            

$and<Bool>          $and<Bool>(true,false,true)             // returns false

$not<Bool>          $not<Bool>(false)                       // returns true

$and<Bool>          $and<Bool>(true,false,false)            // returns true

 

Manipulating Array (strings separated by a semicolon without whitespace, e.g. 10;20;50)

            

$encode<Array>       $encode<Array>(10,20,30)                // return 10;20;30

$first<Array>        $first<Array>(toto;tata;titi)           // returns toto

$last<Array>         $last<Array>(toto;tata;titi)            // returns titi

$tail<Array>         $tail<Array>(toto;tata;titi)            // returns tata;titi

$add<Array>          $add<Array>(to;ta;ti,1;2;3,A;B;C)       // returns to;ta;ti;1;2;3;A;B;C

$sort<Array>         $sort<Array>(toto;tata;titi)            // returns tata;titi;toto

$sort<Array>         $sort<Array>(10.0,-3.0,-30.0)           // returns -30.0;-3.0;10.0

bottom of page