# logica
a compile-to-javascript predicate logic language

note: this is a preview public release, so documentation is a bit sparse right now.

logica is a language for expressing [Boolean algebra](http://en.wikipedia.org/wiki/Boolean_algebra). It's clean syntax makes it easy for non-programmers and domain experts to express complex logic and conditional knowledge.

* flexible syntax
* interpreted or compile-to-javascript
* all operators support multiple arguments (except `not`)
* extensible with custom predicate operators

## basic usage

in logica, you create predicates (functions which result in a `true` or `false` value). The simplest predicate is a literal boolean value. That is, the following is valid logica:

    true

This, clearly, will always evaluate to true. Of course, you probably want more complex things:

    (OR
      (Today = "wednesday")
      (Today = "mittwoch")
    )

Whitespace doesn't matter, but it can improve usability. Optionally, commas can be used to separate the various pieces. We could also write:

    (OR,(Today="wednesday"),(=,Today,"mittwoch"))

Here, we're using a symbolic variable, `Today`, and comparing it to the literal values `wednesday` and `mittwoch`.

In JavaScript, you might write:

    Today === "wednesday" || Today === "mittwoch"

Notice the parentheses? You can nest predicates as deeply as you'd like.

Note that since this predicate references `Today`, we can't evaluate it without a value for `Today`. It might help to think about it like this: in logica, you're writing a function. Each symbolic variable you use requires a corresponding argument. When using logica in JavaScript, these are supplied as properties on a `state` object which is passed in.

Putting it all together,

    var logica = require('logica')

    var source = '(OR (Today = "wednesday"), (Today = "mittwoch"))'

    logica.exec(source, {Today: 'mittwoch'})
    // => true

    logica.exec(source, {Today: 'wednesday'})
    // => true

    logica.exec(source, {Today: 'tuesday'})
    // => false

Now that you've got the basics, check out the `/examples/` folder for more.

A slightly more elaborate (and contrived, but valid) predicate might be:

    # a logica program

    (AND
      (foo = 'baz')
      faa
      (NOT (NOT true))

      (pizzas >= 23)
      ('cheese' IN toppings)
      (and (foo = bar))
    )

## using the compiler

logica can be compiled to JavaScript sourcecode so that the overhead of parsing only has to occur once. For example, a server can pre-compile logica predicates for use on a client application.

in node, simply:

    var compile = require('logica')

    var jsCode = compile(sourceString, options);

## using a compiled function

The compiler generates JavaScript sourcecode as a string. This intermediate form expects certain functions to exist in the runtime environment implementing logica operators.

The easiest way to consume this source is using the hydrate function:

    var hydrate = require('logica/hydrate')
    var logicaFn hydrate(compiledLogicaSource)

    var state = { foo: true, bar: false }

    var result = logicaFn(state)

Hydrate is a standalone module with no dependencies. You can use it, for example, to execute functions clientside that were precompiled on the server.

## compile options
You can supply and `opts` object as the optional second argument of `compile`.

- `prettyPrint`: boolean (default false). If true, will generate code with line breaks and indentation

## examples

See the `/examples` folder. Files ending in `.logica` are plain logica source files.

## running the unit tests

    $ make test

## hacking on the parser

logica's parser is implemented in [jison](http://zaach.github.com/jison/). The lexer and parser definitions are implemented in the file `logica.jison`, which generates `parser.js`. This file will get overwritten - do not make modifications to this file. Instead, modifications can be made in `logica.jison` itself or in `postParser.js`, which is just JavaScript.

To generate `parser.js`:

    $ make

## contributors
Jason Denizac - jden - <jason@denizac.org>

## license
MIT (c) 2013 Agile Diagnosis, Inc.
See LICENSE.md