Author Topic: metalanguage: a language for describing other languages  (Read 3636 times)

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
metalanguage: a language for describing other languages
« on: September 20, 2015, 04:39:49 PM »
Wiki says:
Quote
In logic and linguistics, a metalanguage is a language used to make statements about statements in another language (the object language).

Basically, I believe that if we had a metalanguage that can describe any other language, we'd have a way to describe any system in the Universe because we use different languages to reason about the Universe. Having that kind of metalanguage we would have a solid ground for building an AGI.

Does anyone have any opinion on this?

infurl

  • *
  • Autobot
  • ******
  • Posts: 219
  • Humans will disappoint you.
    • Home Page
Re: metalanguage: a language for describing other languages
« Reply #1 on: September 20, 2015, 11:27:49 PM »
There are plenty of metalanguages available so that's not the problem. The problem is the same as it always has been, computational complexity.

Take the simplest set of metalanguages for example, the Chomsky Hierarchy. It contains the regular expressions used by most chatbots, easy to compute but very limited in power. Then there are context free grammars which are capable of describing most natural languages but which require a considerable amount of processing capability. Nowadays advances in computer hardware and algorithms (e.g. GLR parsers) make it practical to use these. Finally there are the context sensitive grammars which are capable of describing any conceivable language but so far they could only be processed easily by a quantum computer or something similar, so they are not yet practical to use.

Computational linguists have built many more sophisticated metalanguages on top of these basic principles, far too many to list here, but at the broadest level of classification they are dependency grammars and phrase structure grammars.

keghn

  • *
  • Starship Trooper
  • *******
  • Posts: 287
Re: metalanguage: a language for describing other languages
« Reply #2 on: September 21, 2015, 02:40:56 AM »
I used meta code. If that is what being talk about here. Like i would make up special codes words.
meta word i used would mean the next 256 byte would use a certain type of compression and
then another meta word mean the next 1024 would use a different type of compression algorithm.

  And then again if meta codes are used in a data base, then there has to be a meta word that
can not be data, or any thing else at all. So if a program pointer jump ahead, at a random distance,
it can use these special meta words as orientation markers.



ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #3 on: September 21, 2015, 06:53:48 AM »
Someone once had an idea for AI: wouldn't it be cool if AI behavior would be memorized as a set of algorithms (or functions) inside mutable programming code. Now, imperative programming languages like Java would be too abstract with their regular loops and assignments. Maybe if we had a language that is more like functioning of mind. Right now I'm working on something like functional language and it looks good for now:

Quote
What is Metafigure?

Metafigure is a programming language for defining other languages and theories. As for languages, it allows their syntax definition. As for theories, it also allows definition of dependencies between theory segments. Metafigure is equipped with mechanisms that can be used for a variety of data related tasks from data analysis and language translation to theorem proving and finding unknown general rules that hold for analyzed data.

   With Metafigure it is possible to describe a variety of theories for different systems held in the Universe. Metafigure acts as an arbitrary complexity level state machine that can reflect the dynamic nature of the data. When we know enough data about a system, we can predict its state changes and derive answers about the system. In fact, that is what is Metafigure primarily about: to serve as a foundation for forming conclusions about the Universe.

   Metafigure is closely related to scientific theories about theories, but it exhibits flexible syntax and semantic definitions in precision in which computer programmers are used to. With Metafigure one can define different sciences like logic, mathematics, chemistry and others, but the one is asked for detailed formalism like in regular computer programming languages. In spite of its very explicit layers of constructs, Metafigure manages to maintain a high level of abstraction in direction of once defined theories.
« Last Edit: September 21, 2015, 07:19:17 AM by ivan.moony »

Zero

  • *
  • Autobot
  • ******
  • Posts: 201
  • Fictional character
    • AGI DEV LOG
Re: metalanguage: a language for describing other languages
« Reply #4 on: September 21, 2015, 07:07:27 AM »
Actually, procedures can be used to act (that's what we do everyday with imperative languages), but they can also be used to feel... Imagine a robot looking at you while you're cooking. It recognizes every individual step action, and everytime it does, it raises flags on procedures that involve those steps. After a while, one of these procedures have a lot of flags raised: then the bot knows what you're cooking.
 O0

EDIT: I think you should like PEG.js
« Last Edit: September 21, 2015, 12:27:23 PM by Zero »
PRO|STAMINA [ programming game ]
AGI DEV LOG [ In Goto We Trust ]

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #5 on: September 21, 2015, 01:59:55 PM »
PEG.js is a fine product :) It is fast.

Edit: Sensing algorithms? What a cool idea :D
« Last Edit: September 22, 2015, 11:26:41 AM by ivan.moony »

Zero

  • *
  • Autobot
  • ******
  • Posts: 201
  • Fictional character
    • AGI DEV LOG
Re: metalanguage: a language for describing other languages
« Reply #6 on: September 25, 2015, 08:41:07 AM »
Yeah  :D

About sensing algorithms:

If you have sensing algorithms, while your brain is working, you always have a few procedures currently unfinished. So it's all about what procedures you decide to complete.

As you adequately put, the problem is choice  ^-^
PRO|STAMINA [ programming game ]
AGI DEV LOG [ In Goto We Trust ]

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #7 on: October 09, 2015, 12:07:28 AM »
Quote
Basic symbol constructs

   Symbols are the most basic Metafigure particles that are used to hold data. When writing down an actual symbol, its name should start with a letter and continue with any combination of letters, numbers or underscore. Let’s take a look at our first example, we will define an arbitrary symbol “X”:

Code: [Select]
X <- @Integer {25}
Here we noted that symbol “X” has a type “@Integer” and a value “25“. We used operator “<-” which is read “follows form”, to denote the type of “X”. Type “@Integer” is actually a reference to another symbol and references are denoted with “@” prefix. We also say that “X” is a parent of its type. Curly braces serve as containers for actual data, in our case “25“.
 

Note that as Metafigure is a typed language, its symbols can accept only values that have the right type. That means if a symbol is eg. of a type @Integer, its value has to be an integer.

“Follows” from operator can be chained and it associates to the right.

   We can also define a range of types that some symbol can hold. We do it by using choice operator like in following example:

Code: [Select]
Bool <- (True | False)
   Choice operator is denoted by “|” sign and we used round braces to group choice elements because “follows from” operator has a precedence over choice operator. We can have any number of choices under a parent symbol, each delimited by “|”. Here we actually have built a type Bool which we can later use as:

Code: [Select]
B <- @Bool {True}
   Complementary to choice operator is a tuple operator “,”. A tuple denotes a list of values of which all belong to a certain symbol. Using a tuple, we can define input parameters of any function. Let’s see how an input of a function “And" would look like:

Code: [Select]
And <- (Left <- @Bool, Right <- @Bool)
Again, we can have any number of tuple elements, each delimited by “,” and we used round braces to override default operator precedence. We apply parameters to our partial “And” definition in a following way using curly braces:

Code: [Select]
A <- @And {Left {True}, Right {False}}
We used nested curly braces to apply specific values to “Left” and “Right” parameters, using a comma delimiter.

   Metafigure expressions can be spanned over multiple lines, so the previous example can be written in the following way without changing the meaning:

Code: [Select]
A <- @And {
    Left {True},
    Right {False}
}

Wherever an optional whitespace appears in our expressions, a new line can be introduced instead. Multiple line spanning becomes very handy with more complex types. It is used to increase readability of types and values.

   We can combine “follows from” operator, choices and tuples to build complex symbol types out of basic symbols. For the end of this section let’s build a more complete possible definition of Boolean constants and operator parameters. Note that for Boolean operators there are defined just parameters. Actual Boolean operator results will be defined through functions and will be introduced in following sections.

Code: [Select]
BooleanExpression <- (
    Bool <- (True | False) |
    And <- (Left <- @Bool, Right <- @Bool) |
    Or <- (Left <- @Bool, Right <- @Bool) |
    Not <- (@Bool)
)

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #8 on: October 11, 2015, 12:31:41 PM »
Quote
Symbol pattern matching and text parsing

   Assigning values in Metafigure, beside explicit notation, can also be made through symbol pattern matching and parsing arbitrary textual expressions.  Symbol pattern matching together with parsing is an advanced property that reveals the real power of Metafigure programming language.

   Symbol pattern matching enables automatic recognition of symbols against a list of values. Let’s consider an example of a type of integers:

Code: [Select]
Integer <- (
    Digit <- (‘0‘ | ‘1‘ | ‘2‘ | ‘3‘ | ‘4‘ | ‘5‘ | ‘6‘ | ‘7‘ | ‘8‘ | ‘9’),
    Next <- (@Integer | @Null)
}

To denote a value of 856 we could write:

Code: [Select]
X <- @Integer {
    Digit {‘8’},
    Next {
        Integer {
            Digit {‘5’},
            Next {
                Integer {
                    Digit {‘6‘},
                    Next {Null}
                }
            }
         }
    }                 
}

Instead of writing this complex expression symbol pattern matching allows us to write:

Code: [Select]
X <- @Integer {‘8‘, ‘5‘, ‘6’}
Values ‘8‘, ‘5‘ and ‘6' are arranged over the “@Integer” type, automatically inferring what symbols assertions are needed to encode the number. Internally, the number is memorized like in the example before the last one,  but we do not have to explicitly denote it in assignment expression. Symbol “@Null” is one of internal symbols and is automatically inferred after the last digit as a given possibility. We can arbitrary choose a method of assigning values, whether it is explicit assignment or symbol pattern matching, and Metafigure automatically detects what we want to do.

   It would be odd if we ought to write integers with quoted digits and commas. That is why Metafigure implements expression parsing. If we want to denote a symbol that should be parsed, we write “!” as a suffix to the symbol like in following example:

Code: [Select]
Integer! <- (
    Digit <- (‘0‘ | ‘1‘ | ‘2‘ | ‘3‘ | ‘4‘ | ‘5‘ | ‘6‘ | ‘7‘ | ‘8‘ | ‘9’),
    Next <- (@Integer | @Null)
}

When we defined “Integer” symbol as a parsed expression with "!" suffix,  we can write our number in the following way:

Code: [Select]
X <- @Integer {856}
where digits would be automatically arranged over “@Integer” type symbols like it was the case with symbol pattern matching. When we denote a symbol as a parsed expression, we exclude the possibility to write it in regular Metafigure symbol assignment manner, which means that we have to explicitly choose whether we want it to be later assigned in parsed or non-parsed manner. “!” sign is inherited over the symbol’s child symbols, meaning that all child symbols are also treated as parsed expressions. We can override it with “?” suffix in the child symbol we want to be treated as non-parsed expression. “!” and “?” suffixes on symbol definitions allow mixing parsed and non-parsed styles, as we find necessary.

   Beside generic Metafigure syntax for noting values in explicit or symbol pattern matching style, expression parsing makes it possible to define symbols that accept values in any syntax notation. That way we can write symbols representing syntaxes for specific expressions, domain specific languages, whole programming languages or theories which we can later combine in other value expressions.

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #9 on: October 13, 2015, 07:27:21 PM »
Quote
A word about lists

   One of the important topics in defining knowledge is lists. Among other uses, lists are useful in defining arbitrary length enumeration of parameters. There is a lot of possible list definitions and the common technique to define them is by recursion. Probably the most understandable recursive list definition is:

Code: [Select]
List <- (
    Item <- (...),
    Next <- (@List | @Null)
)

   There are other list definitions that include associative methods. Left associative version looks this way:

Code: [Select]
List <- (
    Item <- (...) |
    Association <- (@List, @Item)
)

and right associative version looks this way:

Code: [Select]
List <- (
    Item <- (...) |
    Association <- (@Item, @List)
)

Associative methods are useful for defining operator precedence like in simple math expressions. In the following simplified example we use nested lists to achieve this behavior:

Code: [Select]
Sum! <- (
    Fact <- (
        Primary <- (
            (@WhiteSpace | @Null),
            Value <- (
                @Integer |
                Braces <- ('(', Infix <- @Sum, ')')
            ),
            (@WhiteSpace | @Null)
        ) |
        MulDiv <- (Left <- @Fact, Infix <- ('*' | '/'), Right <- @Primary)
    ) |
    AddSub <- (Left <- @Sum, Infix <- ('+' | '-'), Right <- @Fact)
)

Previous parsed expression example allows us to write expressions like the following one:

Code: [Select]
M <- @Sum {1 + 2 * (3 - 4) / 5}
while associating “MulDiv" expressions at higher priority regarding to “AddSub" expressions (of course, braces override this behavior). Actual calculation of results of expressions like these is a matter of using functions which we will explain in the next chapter.

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #10 on: October 15, 2015, 05:00:35 PM »
Quote
Defining functions

   Functions in Metafigure are symbols that calculate some result from their parameters. Function types are also built from “follows from” operator, together from specific result values that depend on specific parameters. To explain this, let us analyze following example:

Code: [Select]
01 BoolExp <- (
02     Bool <- (True | False) |
03
04     (
05         @Bool <- (
06             And <- (Left <- @Bool, Right <- @Bool)
07         )
08     ) {
09         True  {True,  True};
10         False {False, True};
11         False {True,  False};
12         False {False, False}
13     }
14 )

The example above shows possible partial definition of Boolean expressions. We defined Boolean constants in line 2 and a type of Boolean operator “And” in lines 5-7. Lines 9-12 contain a semantic table of values of operator “And”. Each of those lines contains a pair of a result and parameters from which the result follows. These pairs actually correspond to pairs on the left and on the right side of “follows from” operator which forms the function type. The right sides of those pairs are symbol pattern matched to “And” calling structure (from line 6), while the left sides belong to “@Bool” result (from line 5). As to values of “@Bool” result and “And” function, pattern matching automatically recognizes symbols and automatically asserts them in the following way:

Code: [Select]
{Bool {True}}  {And {Left {Bool {True}},  Right {Bool {True}}}};
{Bool {False}} {And {Left {Bool {True}},  Right {Bool {False}}}};
{Bool {False}} {And {Left {Bool {False}}, Right {Bool {True}}}};
{Bool {False}} {And {Left {Bool {False}}, Right {Bool {False}}}}

In shown expanded expression, we used curly braces as a utility for grouping value pairs and for optional decorator of our expressions (for “Bool” values).

   We see another new thing in “And” function example, and that is noting multiple values under the same symbol. Among other uses, this allows us to note semantic tables for later call-by-pattern.
 
Symbols in Metafigure actually can contain multiple values at the same time and they are noted delimited by a semicolon.

Now we can call our function in the following way:

Code: [Select]
Result <- @And {True, False}
and the symbol “Result “ is automatically being attached by the following value, calculated from “And” operator semantic table:   

Code: [Select]
Result {Bool {False}}
   When calling a function, Metafigure seeks for a pattern passed by parameters, so it can assign a result to a caller. This is known as call-by-pattern behavior. As we will see later, It will allow us to write complex functions.

   We saw how functions are defined by “follows from” operator analogous to the standard symbol definition. The only difference is in the availability of noting result values that depend on some parameters, and the symbol pattern matcher does the magic at the time of calling function. To look somewhat further, as a deduction is just a function from premises to conclusions, functions will make available definition of deduction rules too.

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #11 on: November 05, 2015, 12:05:47 AM »
I've been to another mind journey recently and among other things, two new operators popped up: "tag" operator for storing library stuff (not actually part of data, but utilities for constructing them) and "check" operator for reporting data errors (actually to restrict possible data values, like to prevent dividing by zero). I was aware of these two before, but now I realized they have something in common (or at least they should) with type operator and assigning-values operator, just like type and value assigning operators somehow look similar.

I'm thinking of noting all these four by a single parameterized operator: "<-[operator mode]", So we would have:
Code: [Select]
A <-[define] B //classic <- operator
A <-[reduce] B //this would replace assigning values
A <-[tag] B
A <-[check] B

Operator modes would be inherited down the definition, so mostly it would be sufficient to write just <- like in following example:
Code: [Select]
*And <-[define] ( //from now on "[define]" is inherited where "<-" is noted
    (
        Bool <- (*Left <- Bool, *Right <- Bool)
    ) <-[reduce] ( //from now on "[reduce]" is inherited where "<-" is noted
        True  <- (Left <- True,  Right <- True)  |
        False <- (Left <- False, Right <- True)  |
        False <- (Left <- True,  Right <- False) |
        False <- (Left <- False, Right <- False)
    )
)

I don't know if this would be a good idea, or someone would prefer to have four different notations like <=, <-, <+, <&.

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #12 on: November 10, 2015, 01:10:08 PM »
Disregard the last post, I've decided not to change Metafigure that much. The only changes I want to make are following:
  • new symbols are noted with "*" prefix
  • referring to existing symbols is made without prefix
  • curly braces are now replaced by round braces
It turned out that functional reactive aspect of Metafigure can entirely be described with events. The philosophy is: when a certain symbol gets some predicted value, other symbols can change their value to something else. I don't know if this can count as a new programming paradigm.

Here is a clock programmed in Metafigure:
Code: [Select]
(
    *Clock <- (
        *hour <- Integer (
            Case (
                pHour (init);
                (
                    hour + 1 (hour < 24);
                    0        (hour == 24)
                ) (Timer (60 * 60 * 1000))
            )
        ),
        *min <- Integer (
            Case (
                pMin (init);
                (
                    min + 1 (min < 60);
                    0       (min == 60)
                ) (Timer (60 * 1000))
             )
         ),
        *sec <- Integer (
            Case (
                pSec (init);
                (
                    sec + 1 (sec < 60);
                    0       (sec == 60)
                ) (Timer (1000))
            )
        )
    )
) <- (*pHour <- Integer, *pMin <- Integer, *pSec <- Integer)

And you initialize the running clock at 14:30:20 with the following code:
Code: [Select]
c <- Clock (14, 30, 20)
Symbol "Timer" does the magic of triggering state change at the right millisecond intervals. Still some issues about when the actual symbol gets its values, but I think I'll work it out.

Edit: Solved. We can trigger the starting of timer count to the moment of i.e. pHour getting assigned, so the fragment for controlling hour would be:
Code: [Select]
*hour <- Integer (
    Case (
        (
            pHour (pHour);
            (
                hour + 1 (hour < 24);
                0        (hour == 24)
            ) (Timer (60 * 60 * 1000))
        ) (pHour)
    )
)

P.S. Note that "Case" symbol is a tree of consequences from right to left. Definition of "Case" is simple and it looks like this:
Code: [Select]
*Case <- (
    Case <- Bool |
    @Result
)
Where @Result stands for parameterized symbol accepting any value (that is what "@" prefix do from now on)
« Last Edit: November 10, 2015, 02:39:03 PM by ivan.moony »

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #13 on: November 25, 2015, 05:30:45 PM »
New cosmetic changes:
  • "<-" operator is now written as "<=", still reads as "follows from"
  • application of parameters is having "<-" infix notation instead of whitespace and it reads "specifies from"
  • value delimiter ";" turns into "|". It is actually the same "|" from defining types
so our Boolean example finally looks like this:
Code: [Select]
01 *BoolExp <= (
02     *Bool <= (*True | *False) |
03
04     *And <= (
05         Bool <= (Bool, Bool)
06     ) <- (
07         True  <- (True,  True)  |
08         False <- (False, True)  |
09         False <- (True,  False) |
10         False <- (False, False)
11     )
12 )

Been thinking about defining Metafigure in itself. It looks simpler than I thought it would be:
Code: [Select]
01 *CExp <= (
02     *TExp <= (
03         *FExp <= (
04             *SExp <= (
05                 *Exp <= (
06                     (WhiteSpace | Null),
07                     *Value <= (
08                         Number |
09                         String |
10                         <<MF.Exp <- <<Symbol>>>> <= (
11                             *Symbol <= (
12                                 *Keyword <= ("parsed' | Null),
13                                 *Mod <= ('*' | '@' | Null),
14                                 SymbolName
15                             )
16                         ) |
17                         In <= (*Bra <= ('(', *In <= TExp, ')'))
18                     ),
19                     (@WhiteSpace | @Null)
20                 ) |
21                 *SpecifiesFrom <= (
22                     (Left <- Right) <= (*Left <= Exp, '<-', *Right <= Left)
23                 )
24             ) |
25             *FollowsFrom <= (
26                 (Left <= Right) <= (*Left <= SExp, '<=', *Right <= FExp)
27             )
28         ) |
29         *Tuple <= (
30             (Left, Right) <= (*Left <= FExp, ',', *Right <= TExp)
31         )
32     ) |
33     *Choice <= (
34         (Left | Right) <= (*Left <= TExp, '|', *Right <= CExp)
35     )
36 )

Important lines are:
  • 10 - this is actually a macro that converts a symbol name string to internal symbol pointer of that name. The internal type check returns an error in the case of non existing symbol
  • 22 - this is where parameters are applied (the new term is "specified"). The internal type check returns an error in the case of incorrect specification
  • 26, 30, 34 - right hand expressions are directly converted to their relevant Metafigure expressions on the left side. The right side is parsed and immediately converted to the left side
A lot of stuff is going under the hood with type checking, so I feel that this is still not a proof of Metafigure's completeness. I guess I should test it on examples like deduction on theorem proving and inductive search for new rules that hold for analyzed data. :wait:
« Last Edit: November 26, 2015, 01:57:34 PM by ivan.moony »

ivan.moony

  • *
  • Replicant
  • ********
  • Posts: 643
  • look, a star is falling
Re: metalanguage: a language for describing other languages
« Reply #14 on: January 11, 2016, 03:39:30 PM »
I'm developing the language a bit further. Important updates are that both <= and <- operators can be replaced by a single <- operator. With a new variable on the left side, the operator is considered  as <= (denoting type), while otherwise it's regular <- (parameters application).

 

Welcome

Please login or register.



Login with username, password and session length
mini a.i puzzles
by Freddy (General AI Discussion)
Today at 09:45:52 PM
trivia questions
by yotamarker (General AI Discussion)
Today at 07:54:30 PM
Robot Message in a Bottle
by 8pla.net (Home Made Robots)
Today at 04:04:21 AM
La-Masterpiece
by LOCKSUIT (Graphics)
February 24, 2017, 10:26:32 PM
Auto-Food-Drone type delivery
by Art (General Chat)
February 24, 2017, 06:52:28 PM
Galton Machines or Bean Machines
by Freddy (General AI Discussion)
February 24, 2017, 03:13:07 AM
3D Printing
by Art (General Chat)
February 23, 2017, 12:51:23 PM
MusicNet
by keghn (General AI Discussion)
February 22, 2017, 11:03:11 PM
Robust bipedal Cassie to transform robot mobility
by Tyler (Robotics News)
February 24, 2017, 04:48:44 PM
Artificial intelligence: Understanding how machines learn
by Tyler (Robotics News)
February 24, 2017, 10:49:13 AM
Hard at work: A review of the Laevo Exoskeleton
by Tyler (Robotics News)
February 23, 2017, 04:48:12 PM
Shell Ocean Discovery XPRIZE: Semi-finalists set sail on a journey to illuminate the ocean
by Tyler (Robotics News)
February 22, 2017, 10:48:25 PM
Drones for good 2.0: How WeRobotics is redefining the use of unmanned systems in developing countries
by Tyler (Robotics News)
February 22, 2017, 04:48:07 PM
At what point should an intelligent machine be considered a person?
by Tyler (Robotics News)
February 22, 2017, 10:48:24 AM
Ocado evaluating robotic manipulation for online shopping orders
by Tyler (Robotics News)
February 21, 2017, 10:50:46 PM
Motor control systems: Bode plots and stability
by Tyler (Robotics News)
February 21, 2017, 04:48:52 PM

Users Online

18 Guests, 1 User
Users active in past 15 minutes:
Freddy
[Administrator]

Most Online Today: 50. Most Online Ever: 208 (August 27, 2008, 08:24:30 AM)

Articles