Skip to content

Commit 749b6cb

Browse files
committed
Merge branch 'v1.0'
2 parents 8671e76 + e451280 commit 749b6cb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2253
-14481
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ build/Release
2929
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
3030
node_modules
3131

32+
# Exclude JS file generated by PEG.js
33+
src/parser.js

README.md

Lines changed: 98 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,112 @@
22

33
Compile and run Constraint Handling Rules (CHR) in JavaScript.
44

5+
CHR.js is a just-in-time (JIT) compiler for Constraint Handling Rules, embedded in JavaScript. For better runtime performance it supports ahead-of-time (AOT) compilation too, either by its command line tool `chrjs` or [babel-plugin-chr](https://github.com/fnogatz/babel-plugin-chr), a plugin for Babel.
6+
57
## Getting Started
68

79
The [online version at chrjs.net](http://chrjs.net/) is the easiest way to generate a constraint solver. Just enter your Constraint Handling Rules, try adding some constraints, and download the generated solver code.
810

9-
## Install
10-
11-
npm install chr
12-
13-
## Usage as CLI
14-
15-
If you install CHR.js via npm it will create a new `chrjs` executable:
16-
17-
$ chrjs /path/to/your.chr > /created/constrainthandler.js
18-
19-
If no path is specified, `chrjs` reads from stdin.
20-
21-
## Usage with node.js
22-
23-
The CHR.js module can be used programmatically:
24-
25-
var chrjs = require('chr')
26-
27-
var code = chrjs.transform('a ==> b')
28-
chrjs.transformFile('path.chr', function(err, code) {
29-
console.log(code)
30-
})
31-
3211
## Example
3312

34-
Consider the following CHR source code, which generates all fibonacci numbers upto a given index `N` as constraints of the form `fib(Number,Value)`:
35-
36-
upto(N), fib(A,AV), fib(B,BV) ==> B === A+1, B < N | fib(B+1,AV+BV);
37-
38-
The CHR source code can be compiled to JavaScript by the use of the `chrjs` command:
39-
40-
$ echo 'upto(N), fib(A,AV), fib(B,BV) ==> B === A+1, B < N | fib(B+1,AV+BV);' | chrjs > fib.js
41-
42-
The generated JavaScript code has references to `chr/runtime` components, so make sure it is available. Open a REPL to play with the generated `fib.js`:
43-
44-
$ node
45-
> var konsole = require('chr/console') // for graphical representation
46-
> var CHR = require('./fib.js') // load the generated source
47-
> CHR.fib(1,1) // the first fibonacci is 0
48-
> CHR.fib(2,1) // the second is 1
49-
> konsole(CHR.Store) // print the content of the
50-
┌────────────┐ // constraint store
51-
│ Constraint │
52-
├────────────┤
53-
│ fib(1,1) │
54-
├────────────┤
55-
│ fib(2,1) │
56-
└────────────┘
57-
> CHR.upto(5) // generate the first 5 fibs
58-
> konsole(CHR.Store) // print the content of the
59-
┌────────────┐ // constraint store again
60-
│ Constraint │
61-
├────────────┤
62-
│ fib(1,1) │
63-
├────────────┤
64-
│ fib(2,1) │
65-
├────────────┤
66-
│ upto(5) │
67-
├────────────┤
68-
│ fib(3,2) │
69-
├────────────┤
70-
│ fib(4,3) │
71-
├────────────┤
72-
│ fib(5,5) │
73-
└────────────┘
74-
> CHR.fib(6,8).fib(7,13) // constraints allow chaining
75-
> CHR.Store.reset() // clear the constraint store
76-
77-
More example CHR scripts are provided in the project's `/examples` directory or at [chrjs.net](http://chrjs.net/).
13+
The following CHR rule generates all fibonacci numbers upto a given index `Max` as constraints of the form `fib(Number,Value)`.
14+
15+
upto(Max), fib(A,AV), fib(B,BV) ==> B === A+1, B < Max | fib(B+1,AV+BV)
16+
17+
The CHR rule can be used in JavaScript after declaring it via the `chr()` function, like in this example:
18+
19+
20+
var CHR = require('chr') // load the module
21+
var konsole = require('chr/console') // little tool for graphical
22+
// representations
23+
24+
var chr = CHR() // create new handler
25+
26+
// add the rule
27+
chr('upto(Max), fib(A,AV), fib(B,BV) ==> B === A+1, B < Max | fib(B+1,AV+BV)')
28+
29+
konsole.log(chr.Store) // print the content of the
30+
// constraint store
31+
/* results in:
32+
┌────────────┐
33+
│ Constraint │
34+
├────────────┤
35+
│ (empty) │
36+
└────────────┘
37+
*/
38+
39+
chr.fib(1,1) // the first fibonacci is 1
40+
chr.fib(2,1) // the second is 1
41+
42+
konsole.log(chr.Store) // both have been stored
43+
/* results in:
44+
┌────────────┐
45+
│ Constraint │
46+
├────────────┤
47+
│ fib(1,1) │
48+
├────────────┤
49+
│ fib(2,1) │
50+
└────────────┘
51+
*/
52+
53+
// now generate the fibonaccis upto the 5th element
54+
chr.upto(5)
55+
konsole.log(chr.Store)
56+
/* results in:
57+
┌────────────┐
58+
│ Constraint │
59+
├────────────┤
60+
│ fib(1,1) │
61+
├────────────┤
62+
│ fib(2,1) │
63+
├────────────┤
64+
│ upto(5) │
65+
├────────────┤
66+
│ fib(3,2) │
67+
├────────────┤
68+
│ fib(4,3) │
69+
├────────────┤
70+
│ fib(5,5) │
71+
└────────────┘
72+
*/
73+
74+
More example CHR scripts are provided at [chrjs.net](http://chrjs.net/).
75+
76+
Defining CHR rules in this way, they are compiled at runtime, that means we use a just-in-time (JIT) compilation. However, for performance reasons, we encourage the use of an ahead-of-time (AOT) compiler as presented in the [next section](#aot-compilation).
77+
78+
## AOT Compilation
79+
80+
The easiest way to precompile your JavaScript source code with embedded Constraint Handling Rules is by using [babel-plugin-chr](https://github.com/fnogatz/babel-plugin-chr), a plugin for [Babel](http://babeljs.io/):
81+
82+
npm install babel-plugin-chr
83+
babel --plugins chr script.js
84+
85+
However, CHR.js itself provides a command line tool to compile scripts that are dominated by Constraint Handling Rules:
86+
87+
chrjs script.chr > script.js
88+
89+
Please note, that the given `.chr` files must be of the following form, where CHR rules are the main elements and arbitrary JavaScript code must be placed in a preamble section:
90+
91+
{
92+
// preamble
93+
// code in this block can be used in the rules' guards and bodies
94+
95+
function print (v) {
96+
console.log(v)
97+
}
98+
99+
function pred (v) {
100+
return v < 5
101+
}
102+
}
103+
104+
print_num @ num(v) ==> ${ () => print(v) }
105+
generate_nums @ num(v) ==> ${ () => pred(v) } | num(v+1)
106+
107+
Functions ecapsulated in `${ ... }` are evaluated at rule application, as for JIT compilation too.
78108

79109
## Background
80110

81-
CHR.js was realized as a project as part of the Masters programme in Computer Science at the University of Ulm. Its Project Report with additional information about its architecture can be found online: https://fnogatz.github.io/paper-now-chrjs/.
111+
CHR.js was realized as a part of my Master Thesis in Computer Science at the University of Ulm, Germany. Its Project Report for a prototype implementation (versions `0.x`) with additional information about its architecture can be found online: https://fnogatz.github.io/paper-now-chrjs/.
82112

83113
The implementation is based on the compilation scheme presented in the paper [CHR for imperative host languages](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.149.8471) (2008; Peter Van Weert, Pieter Wuille, Tom Schrijvers, Bart Demoen). As of yet basically none of the mentioned optimizations have been implemented.
84-
85-
A list of open points for improving can be found in the [wiki](https://github.com/fnogatz/CHR.js/wiki/Todo) and the [project report](https://fnogatz.github.io/paper-now-chrjs/#summary).

bin/chrjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
var program = require('commander')
44
var concat = require('concat-stream')
5-
var chrjs = require('../index')
5+
var compile = require('../compile')
66

77
function onFinish(err, code) {
88
if (err) {
@@ -20,10 +20,10 @@ var file = program.args[0]
2020
var opts = program
2121

2222
if (file) {
23-
chrjs.transformFile(file, opts, onFinish)
23+
compile.fromFile(file, opts, onFinish)
2424
} else {
2525
process.stdin.pipe(concat({ encoding: 'string' }, function (source) {
26-
var code = chrjs.transform(source, opts)
26+
var code = compile(source, opts)
2727
onFinish(null, code)
2828
}))
2929
}

compile.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./src/compile')

compiler/browserify.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)