Franck Pommereau

CoffeeScript lib in progress

......@@ -417,7 +417,7 @@ func (self Marking) String () string {
comma = true
}
buf.WriteString(fmt.Sprintf(`"%s": %s`, *p, *m))
}
}
buf.WriteString("}")
return buf.String()
}
......
......@@ -5,24 +5,66 @@ FREE = -1
DUMMY = -2
hash = (obj) ->
"""
coffee> dicts.hash("hello world")
-8572760634
coffee> dicts.hash(42)
-4720677242
coffee> dicts.hash(42) == dicts.hash("42")
false
coffee> dicts.hash([1, 2, 3])
4097603114
coffee> dicts.hash([1, 2, 3]) == dicts.hash([3, 2, 1])
false
coffee> dicts.hash(a:1, b:2, c:3)
2146137064
coffee> dicts.hash(a:1, b:2, c:3) == dicts.hash(c:3, b:2, a:1)
true
"""
try
return obj.hash()
catch err
h = 0
if typeof(obj) == "string"
for c in obj
for c in "#{typeof obj}/#{obj}"
h = (h << 5) - h + c.charCodeAt(0)
else if obj instanceof Array
for x in obj
h = (h << 5) - h + hash(x)
else if obj instanceof Object
for k, v of obj
h = h ^ ((hash(k) << 5) - h + hash(v))
h ^= ((hash(k) << 5) + hash(v))
else
h = hash("#{obj}")
h = hash("#{typeof obj}/#{obj}")
return h
eq = (left, right) ->
"""
coffee> dicts.eq("hello", "hello")
true
coffee> dicts.eq("hello", "world")
false
coffee> dicts.eq(42, 42)
true
coffee> dicts.eq(42, -42)
false
coffee> dicts.eq([1, 2, 3], [1, 2, 3])
true
coffee> dicts.eq([1, 2, 3], [1, 2, 3, 4])
false
coffee> dicts.eq([1, 2, 3], [1, 2, 4])
false
coffee> dicts.eq({a:1, b:2, c:3}, {c:3, b:2, a:1})
true
coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, c:3, d:4})
false
coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2})
false
coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, c:1234})
false
coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, d:3})
false
"""
try
return left.eq(right)
catch err
......@@ -54,6 +96,15 @@ class KeyError
class Dict
constructor: (init={}) ->
"""
coffee> new dicts.Dict()
Dict { indices: {}, itemlist: [], used: 0 }
coffee> new dicts.Dict(a:1, b:2)
Dict{indices: { '...': 1, '...': 0 },
itemlist: [{ key: 'a', value: 1, hash: ...},
{ key: 'b', value: 2, hash: ...}],
used: 2}
"""
@clear()
for key, val of init
@set(key, val)
......@@ -62,6 +113,12 @@ class Dict
@itemlist = []
@used = 0
len: ->
"""
coffee> (new dicts.Dict()).len()
0
coffee> (new dicts.Dict(a:1, b:2)).len()
2
"""
return @used
_gen_probes: (hashvalue) ->
PERTURB_SHIFT = 5
......@@ -73,6 +130,7 @@ class Dict
while true
i = 5 * i + perturb + 1
perturb >>= PERTURB_SHIFT
yield i
_lookup: (key, hashvalue) ->
freeslot = null
for i from @_gen_probes(hashvalue)
......@@ -91,6 +149,13 @@ class Dict
if item.key is key || item.hash == hashvalue && eq(item.key, key)
return [index, i]
set: (key, value) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> a.set("c", 3)
coffee> a.set("a", 0)
coffee> console.log a.toString()
{a: 0, b: 2, c: 3}
"""
hashvalue = hash(key)
[index, i] = @_lookup(key, hashvalue)
if index < 0
......@@ -99,12 +164,37 @@ class Dict
@used++
else
@itemlist[index] = {key: key, value: value, hash: hashvalue}
get: (key) ->
fetch: (key, otherwise=null) ->
[index, i] = @_lookup(key, hash(key))
if index < 0
throw new KeyError("key #{key} not found")
return otherwise
return @itemlist[index].value
get: (key, def=undefined) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> a.get("a")
1
coffee> a.get("x")
Thrown: ...
coffee> a.get("x", null)
null
"""
[index, i] = @_lookup(key, hash(key))
if index < 0
if def is undefined
throw new KeyError("key #{key} not found")
else
return def
return @itemlist[index].value
del: (key) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> a.del("a")
coffee> a.del("x")
Thrown: ...
coffee> a.eq(new dicts.Dict(b:2))
true
"""
[index, i] = @_lookup(key, hash(key))
if index < 0
throw new KeyError("key #{key} not found")
......@@ -119,20 +209,30 @@ class Dict
iter: ->
for item in @itemlist
yield [item.key, item.value]
copy: ->
copy = new Dict()
for item in @itemlist
copy.set(item.key, item.value)
return copy
has: (key) ->
[index, i] = @_lookup(key, hash(key))
return index >= 0
get: (key, otherwise=null) ->
[index, i] = @_lookup(key, hash(key))
if index < 0
return otherwise
return @itemlist[index].value
pop: ->
if @user == 0
throw new KeyError("cannot pop from empty dict")
item = @itemlist[@itemlist.length - 1]
@del(key)
return [item.key, item.value]
eq: (other) ->
if other not instanceof Dict
return false
if @used != other.used
return false
for [k, v] from @iter()
x = other.get(k, null)
if x is null or not eq(v, x)
return false
return true
toString: ->
items = ("#{ k }: #{ v }" for [k, v] from @iter())
return "{#{ items.join(', ') }}"
......
......@@ -9,15 +9,17 @@
DUMMY = -2;
hash = function(obj) {
var c, err, h, k, l, len, len1, m, v, x;
"coffee> dicts.hash(\"hello world\")\n-8572760634\ncoffee> dicts.hash(42)\n-4720677242\ncoffee> dicts.hash(42) == dicts.hash(\"42\")\nfalse\ncoffee> dicts.hash([1, 2, 3])\n4097603114\ncoffee> dicts.hash([1, 2, 3]) == dicts.hash([3, 2, 1])\nfalse\ncoffee> dicts.hash(a:1, b:2, c:3)\n2146137064\ncoffee> dicts.hash(a:1, b:2, c:3) == dicts.hash(c:3, b:2, a:1)\ntrue";
var c, err, h, k, l, len, len1, m, ref, v, x;
try {
return obj.hash();
} catch (error) {
err = error;
h = 0;
if (typeof obj === "string") {
for (l = 0, len = obj.length; l < len; l++) {
c = obj[l];
ref = `${typeof obj}/${obj}`;
for (l = 0, len = ref.length; l < len; l++) {
c = ref[l];
h = (h << 5) - h + c.charCodeAt(0);
}
} else if (obj instanceof Array) {
......@@ -28,16 +30,17 @@
} else if (obj instanceof Object) {
for (k in obj) {
v = obj[k];
h = h ^ ((hash(k) << 5) - h + hash(v));
h ^= (hash(k) << 5) + hash(v);
}
} else {
h = hash(`${obj}`);
h = hash(`${typeof obj}/${obj}`);
}
return h;
}
};
eq = function(left, right) {
"coffee> dicts.eq(\"hello\", \"hello\")\ntrue\ncoffee> dicts.eq(\"hello\", \"world\")\nfalse\ncoffee> dicts.eq(42, 42)\ntrue\ncoffee> dicts.eq(42, -42)\nfalse\ncoffee> dicts.eq([1, 2, 3], [1, 2, 3])\ntrue\ncoffee> dicts.eq([1, 2, 3], [1, 2, 3, 4])\nfalse\ncoffee> dicts.eq([1, 2, 3], [1, 2, 4])\nfalse\ncoffee> dicts.eq({a:1, b:2, c:3}, {c:3, b:2, a:1})\ntrue\ncoffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, c:3, d:4})\nfalse\ncoffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2})\nfalse\ncoffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, c:1234})\nfalse\ncoffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, d:3})\nfalse";
var err, i, k, l, ref, v;
try {
return left.eq(right);
......@@ -89,6 +92,7 @@
Dict = class Dict {
constructor(init = {}) {
"coffee> new dicts.Dict()\nDict { indices: {}, itemlist: [], used: 0 }\ncoffee> new dicts.Dict(a:1, b:2)\nDict{indices: { '...': 1, '...': 0 },\n itemlist: [{ key: 'a', value: 1, hash: ...},\n { key: 'b', value: 2, hash: ...}],\n used: 2}";
var key, val;
this.clear();
for (key in init) {
......@@ -104,6 +108,7 @@
}
len() {
"coffee> (new dicts.Dict()).len()\n0\ncoffee> (new dicts.Dict(a:1, b:2)).len()\n2";
return this.used;
}
......@@ -119,7 +124,8 @@
results = [];
while (true) {
i = 5 * i + perturb + 1;
results.push(perturb >>= PERTURB_SHIFT);
perturb >>= PERTURB_SHIFT;
results.push((yield i));
}
return results;
}
......@@ -151,6 +157,7 @@
}
set(key, value) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.set(\"c\", 3)\ncoffee> a.set(\"a\", 0)\ncoffee> console.log a.toString()\n{a: 0, b: 2, c: 3}";
var hashvalue, i, index;
hashvalue = hash(key);
[index, i] = this._lookup(key, hashvalue);
......@@ -171,16 +178,31 @@
}
}
get(key) {
fetch(key, otherwise = null) {
var i, index;
[index, i] = this._lookup(key, hash(key));
if (index < 0) {
throw new KeyError(`key ${key} not found`);
return otherwise;
}
return this.itemlist[index].value;
}
get(key, def = void 0) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.get(\"a\")\n1\ncoffee> a.get(\"x\")\nThrown: ...\ncoffee> a.get(\"x\", null)\nnull";
var i, index;
[index, i] = this._lookup(key, hash(key));
if (index < 0) {
if (def === void 0) {
throw new KeyError(`key ${key} not found`);
} else {
return def;
}
}
return this.itemlist[index].value;
}
del(key) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.del(\"a\")\ncoffee> a.del(\"x\")\nThrown: ...\ncoffee> a.eq(new dicts.Dict(b:2))\ntrue";
var i, index, j, lastindex, lastitem;
[index, i] = this._lookup(key, hash(key));
if (index < 0) {
......@@ -208,19 +230,21 @@
return results;
}
has(key) {
var i, index;
[index, i] = this._lookup(key, hash(key));
return index >= 0;
copy() {
var copy, item, l, len, ref;
copy = new Dict();
ref = this.itemlist;
for (l = 0, len = ref.length; l < len; l++) {
item = ref[l];
copy.set(item.key, item.value);
}
return copy;
}
get(key, otherwise = null) {
has(key) {
var i, index;
[index, i] = this._lookup(key, hash(key));
if (index < 0) {
return otherwise;
}
return this.itemlist[index].value;
return index >= 0;
}
pop() {
......@@ -233,6 +257,25 @@
return [item.key, item.value];
}
eq(other) {
var k, ref, v, x, y;
if (!(other instanceof Dict)) {
return false;
}
if (this.used !== other.used) {
return false;
}
ref = this.iter();
for (y of ref) {
[k, v] = y;
x = other.get(k, null);
if (x === null || !eq(v, x)) {
return false;
}
}
return true;
}
toString() {
var items, k, v;
items = (function() {
......
......@@ -6,8 +6,8 @@
"libs/js/dicts.coffee"
],
"names": [],
"mappings": "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",
"mappings": "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",
"sourcesContent": [
"# Python3 dicts ported to CoffeeScript, inspired from a Python version at\n# https://code.activestate.com/recipes/578375/\n\nFREE = -1\nDUMMY = -2\n\nhash = (obj) ->\n try\n return obj.hash()\n catch err\n h = 0\n if typeof(obj) == \"string\"\n for c in obj\n h = (h << 5) - h + c.charCodeAt(0)\n else if obj instanceof Array\n for x in obj\n h = (h << 5) - h + hash(x)\n else if obj instanceof Object\n for k, v of obj\n h = h ^ ((hash(k) << 5) - h + hash(v))\n else\n h = hash(\"#{obj}\")\n return h\n\neq = (left, right) ->\n try\n return left.eq(right)\n catch err\n if left instanceof Array\n if right not instanceof Array\n return false\n if right.length != left.length\n return false\n for i in [0..left.length]\n if not eq(left[i], right[i])\n return false\n return true\n else if left instanceof Object\n if right not instanceof Object\n return false\n for k, v of left\n if not right[k]?\n return false\n for k, v of right\n if not eq(left[k], right[k])\n return false\n return true\n else\n return left == right\n\nclass KeyError\n constructor: (@message) ->\n @name = \"KeyError\"\n\nclass Dict\n constructor: (init={}) ->\n @clear()\n for key, val of init\n @set(key, val)\n clear: ->\n @indices = {}\n @itemlist = []\n @used = 0\n len: ->\n return @used\n _gen_probes: (hashvalue) ->\n PERTURB_SHIFT = 5\n if hashvalue < 0\n hashvalue = -hashvalue\n i = hashvalue\n yield i\n perturb = hashvalue\n while true\n i = 5 * i + perturb + 1\n perturb >>= PERTURB_SHIFT\n _lookup: (key, hashvalue) ->\n freeslot = null\n for i from @_gen_probes(hashvalue)\n index = @indices[i]\n if index == undefined\n index = FREE\n if freeslot == null\n return [FREE, i]\n else\n return [DUMMY, freeslot]\n else if index == DUMMY\n if freeslot == null\n freeslot = i\n else\n item = @itemlist[index]\n if item.key is key || item.hash == hashvalue && eq(item.key, key)\n return [index, i]\n set: (key, value) ->\n hashvalue = hash(key)\n [index, i] = @_lookup(key, hashvalue)\n if index < 0\n @indices[i] = @used\n @itemlist.push {key: key, value: value, hash: hashvalue}\n @used++\n else\n @itemlist[index] = {key: key, value: value, hash: hashvalue}\n get: (key) ->\n [index, i] = @_lookup(key, hash(key))\n if index < 0\n throw new KeyError(\"key #{key} not found\")\n return @itemlist[index].value\n del: (key) ->\n [index, i] = @_lookup(key, hash(key))\n if index < 0\n throw new KeyError(\"key #{key} not found\")\n @indices[i] = DUMMY\n @used--\n if index != @used\n lastitem = @itemlist[@itemlist.length - 1]\n [lastindex, j] = @_lookup(lastitem.key, lastitem.hash)\n @indices[j] = index\n @itemlist[index] = lastitem\n @itemlist.pop()\n iter: ->\n for item in @itemlist\n yield [item.key, item.value]\n has: (key) ->\n [index, i] = @_lookup(key, hash(key))\n return index >= 0\n get: (key, otherwise=null) ->\n [index, i] = @_lookup(key, hash(key))\n if index < 0\n return otherwise\n return @itemlist[index].value\n pop: ->\n if @user == 0\n throw new KeyError(\"cannot pop from empty dict\")\n item = @itemlist[@itemlist.length - 1]\n @del(key)\n return [item.key, item.value]\n toString: ->\n items = (\"#{ k }: #{ v }\" for [k, v] from @iter())\n return \"{#{ items.join(', ') }}\"\n\nmodule.exports =\n hash: hash\n eq: eq\n KeyError: KeyError\n Dict: Dict\n"
"# Python3 dicts ported to CoffeeScript, inspired from a Python version at\n# https://code.activestate.com/recipes/578375/\n\nFREE = -1\nDUMMY = -2\n\nhash = (obj) ->\n \"\"\"\n coffee> dicts.hash(\"hello world\")\n -8572760634\n coffee> dicts.hash(42)\n -4720677242\n coffee> dicts.hash(42) == dicts.hash(\"42\")\n false\n coffee> dicts.hash([1, 2, 3])\n 4097603114\n coffee> dicts.hash([1, 2, 3]) == dicts.hash([3, 2, 1])\n false\n coffee> dicts.hash(a:1, b:2, c:3)\n 2146137064\n coffee> dicts.hash(a:1, b:2, c:3) == dicts.hash(c:3, b:2, a:1)\n true\n \"\"\"\n try\n return obj.hash()\n catch err\n h = 0\n if typeof(obj) == \"string\"\n for c in \"#{typeof obj}/#{obj}\"\n h = (h << 5) - h + c.charCodeAt(0)\n else if obj instanceof Array\n for x in obj\n h = (h << 5) - h + hash(x)\n else if obj instanceof Object\n for k, v of obj\n h ^= ((hash(k) << 5) + hash(v))\n else\n h = hash(\"#{typeof obj}/#{obj}\")\n return h\n\neq = (left, right) ->\n \"\"\"\n coffee> dicts.eq(\"hello\", \"hello\")\n true\n coffee> dicts.eq(\"hello\", \"world\")\n false\n coffee> dicts.eq(42, 42)\n true\n coffee> dicts.eq(42, -42)\n false\n coffee> dicts.eq([1, 2, 3], [1, 2, 3])\n true\n coffee> dicts.eq([1, 2, 3], [1, 2, 3, 4])\n false\n coffee> dicts.eq([1, 2, 3], [1, 2, 4])\n false\n coffee> dicts.eq({a:1, b:2, c:3}, {c:3, b:2, a:1})\n true\n coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, c:3, d:4})\n false\n coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2})\n false\n coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, c:1234})\n false\n coffee> dicts.eq({a:1, b:2, c:3}, {a:1, b:2, d:3})\n false\n \"\"\"\n try\n return left.eq(right)\n catch err\n if left instanceof Array\n if right not instanceof Array\n return false\n if right.length != left.length\n return false\n for i in [0..left.length]\n if not eq(left[i], right[i])\n return false\n return true\n else if left instanceof Object\n if right not instanceof Object\n return false\n for k, v of left\n if not right[k]?\n return false\n for k, v of right\n if not eq(left[k], right[k])\n return false\n return true\n else\n return left == right\n\nclass KeyError\n constructor: (@message) ->\n @name = \"KeyError\"\n\nclass Dict\n constructor: (init={}) ->\n \"\"\"\n coffee> new dicts.Dict()\n Dict { indices: {}, itemlist: [], used: 0 }\n coffee> new dicts.Dict(a:1, b:2)\n Dict{indices: { '...': 1, '...': 0 },\n itemlist: [{ key: 'a', value: 1, hash: ...},\n { key: 'b', value: 2, hash: ...}],\n used: 2}\n \"\"\"\n @clear()\n for key, val of init\n @set(key, val)\n clear: ->\n @indices = {}\n @itemlist = []\n @used = 0\n len: ->\n \"\"\"\n coffee> (new dicts.Dict()).len()\n 0\n coffee> (new dicts.Dict(a:1, b:2)).len()\n 2\n \"\"\"\n return @used\n _gen_probes: (hashvalue) ->\n PERTURB_SHIFT = 5\n if hashvalue < 0\n hashvalue = -hashvalue\n i = hashvalue\n yield i\n perturb = hashvalue\n while true\n i = 5 * i + perturb + 1\n perturb >>= PERTURB_SHIFT\n yield i\n _lookup: (key, hashvalue) ->\n freeslot = null\n for i from @_gen_probes(hashvalue)\n index = @indices[i]\n if index == undefined\n index = FREE\n if freeslot == null\n return [FREE, i]\n else\n return [DUMMY, freeslot]\n else if index == DUMMY\n if freeslot == null\n freeslot = i\n else\n item = @itemlist[index]\n if item.key is key || item.hash == hashvalue && eq(item.key, key)\n return [index, i]\n set: (key, value) ->\n \"\"\"\n coffee> a = new dicts.Dict(a:1, b:2)\n coffee> a.set(\"c\", 3)\n coffee> a.set(\"a\", 0)\n coffee> console.log a.toString()\n {a: 0, b: 2, c: 3}\n \"\"\"\n hashvalue = hash(key)\n [index, i] = @_lookup(key, hashvalue)\n if index < 0\n @indices[i] = @used\n @itemlist.push {key: key, value: value, hash: hashvalue}\n @used++\n else\n @itemlist[index] = {key: key, value: value, hash: hashvalue}\n fetch: (key, otherwise=null) ->\n [index, i] = @_lookup(key, hash(key))\n if index < 0\n return otherwise\n return @itemlist[index].value\n get: (key, def=undefined) ->\n \"\"\"\n coffee> a = new dicts.Dict(a:1, b:2)\n coffee> a.get(\"a\")\n 1\n coffee> a.get(\"x\")\n Thrown: ...\n coffee> a.get(\"x\", null)\n null\n \"\"\"\n [index, i] = @_lookup(key, hash(key))\n if index < 0\n if def is undefined\n throw new KeyError(\"key #{key} not found\")\n else\n return def\n return @itemlist[index].value\n del: (key) ->\n \"\"\"\n coffee> a = new dicts.Dict(a:1, b:2)\n coffee> a.del(\"a\")\n coffee> a.del(\"x\")\n Thrown: ...\n coffee> a.eq(new dicts.Dict(b:2))\n true\n \"\"\"\n [index, i] = @_lookup(key, hash(key))\n if index < 0\n throw new KeyError(\"key #{key} not found\")\n @indices[i] = DUMMY\n @used--\n if index != @used\n lastitem = @itemlist[@itemlist.length - 1]\n [lastindex, j] = @_lookup(lastitem.key, lastitem.hash)\n @indices[j] = index\n @itemlist[index] = lastitem\n @itemlist.pop()\n iter: ->\n for item in @itemlist\n yield [item.key, item.value]\n copy: ->\n copy = new Dict()\n for item in @itemlist\n copy.set(item.key, item.value)\n return copy\n has: (key) ->\n [index, i] = @_lookup(key, hash(key))\n return index >= 0\n pop: ->\n if @user == 0\n throw new KeyError(\"cannot pop from empty dict\")\n item = @itemlist[@itemlist.length - 1]\n @del(key)\n return [item.key, item.value]\n eq: (other) ->\n if other not instanceof Dict\n return false\n if @used != other.used\n return false\n for [k, v] from @iter()\n x = other.get(k, null)\n if x is null or not eq(v, x)\n return false\n return true\n toString: ->\n items = (\"#{ k }: #{ v }\" for [k, v] from @iter())\n return \"{#{ items.join(', ') }}\"\n\nmodule.exports =\n hash: hash\n eq: eq\n KeyError: KeyError\n Dict: Dict\n"
]
}
\ No newline at end of file
......
dicts = require "./dicts"
msets = require "./multisets"
class Marking
constructor: (@id=null) ->
"""
coffee> new markings.Marking()
Marking { id: null, d: Dict { indices: {}, itemlist: [], used: 0 } }
coffee> new markings.Marking(42)
Marking { id: 42, d: Dict { indices: {}, itemlist: [], used: 0 } }
"""
@d = new dicts.Dict()
iter: ->
return @d.iter()
hash: ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.set("p2", 4, 5)
coffee> b = new markings.Marking()
coffee> b.set("p1", 3, 1, 2)
coffee> b.set("p2", 5, 4)
coffee> a.hash() == b.hash()
true
"""
h = 7028009221
for [p, m] from @d.iter()
h ^= (dicts.hash(p) << 5) + dicts.hash(m)
return h
eq: (other) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.set("p2", 4, 5)
coffee> b = new markings.Marking()
coffee> b.set("p1", 3, 1, 2)
coffee> b.set("p2", 5, 4)
coffee> a.eq(b)
true
"""
if other not instanceof Marking
return false
return @d.eq(other.d)
copy: (id=null) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.set("p2", 4, 5)
coffee> a.copy().eq(a)
coffee> a.copy() is a
false
"""
copy = new Marking(id)
for [p, m] from @iter()
copy.set(p, m.copy())
return copy
has: (place) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.set("p2", 4, 5)
coffee> a.has("p1")
true
coffee> a.has("p3")
false
"""
return @d.has(place)
set: (place, tokens...) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> console.log a.get("p1").toString()
[1, 2, 3]
coffee> a.set("p1")
coffee> a.has("p1")
false
"""
if tokens.length == 0 and @has(place)
@d.del(place)
else
@d.set(place, new msets.Mset(tokens...))
update: (place, tokens) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.set("p2", 4, 5, 6)
coffee> a.update("p1", a.get("p2"))
coffee> console.log a.get("p1").toString()
[1, 2, 3, 4, 5, 6]
"""
if @has(place)
@d.get(place).add(tokens)
else
@d.set(place, tokens.copy())
get: (place) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> console.log a.get("p1").toString()
[1, 2, 3]
coffee> console.log a.get("p2").toString()
[]
"""
return @d.get(place, new msets.Mset())
empty: (place) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.empty("p1")
false
coffee> a.empty("p2")
true
"""
return @get(place).empty()
add: (other) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> b = new markings.Marking()
coffee> b.set("p1", 4)
coffee> b.set("p2", 5, 6)
coffee> c = new markings.Marking()
coffee> c.set("p1", 1, 2, 3, 4)
coffee> c.set("p2", 5, 6)
coffee> a.add(b).eq(c)
true
"""
for [p, m] from other.iter()
@update(p, m)
return this
sub: (other) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> b = new markings.Marking()
coffee> b.set("p1", 2, 3)
coffee> b.set("p2", 5)
coffee> c = new markings.Marking()
coffee> c.set("p1", 1)
coffee> a.sub(b).eq(c)
true
"""
for [p, m] from other.iter()
mine = @d.get(p, this)
if mine is this
# skip
else if m.geq(mine)
@d.del(p)
else
@d.set(p, mine.sub(m))
return this
geq: (other) ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> b = new markings.Marking()
coffee> b.set("p1", 2, 3)
coffee> a.geq(b)
true
coffee> b.set("p1", 1, 2, 3)
coffee> a.geq(b)
true
coffee> b.set("p1", 1, 2, 3, 4)
coffee> b.get("p1").d
coffee> a.geq(b)
false
coffee> b.set("p1", 1, 2, 3)
coffee> b.set("p2", 4)
coffee> a.geq(b)
false
"""
for [p, m] from other.iter()
if not @get(p).geq(m)
return false
return true
toString: ->
"""
coffee> a = new markings.Marking()
coffee> a.set("p1", 1, 2, 3)
coffee> a.set("p2", 3, 4)
coffee> console.log a.toString()
{'p1': [1, 2, 3], 'p2': [3, 4]}
"""
items = ("'#{ p }': #{ m.toString() }" for [p, m] from @iter())
return "{#{ items.join(', ') }}"
module.exports =
Marking: Marking
// Generated by CoffeeScript 2.0.2
(function() {
var Marking, dicts, msets;
dicts = require("./dicts");
msets = require("./multisets");
Marking = class Marking {
constructor(id1 = null) {
this.id = id1;
"coffee> new markings.Marking()\nMarking { id: null, d: Dict { indices: {}, itemlist: [], used: 0 } }\ncoffee> new markings.Marking(42)\nMarking { id: 42, d: Dict { indices: {}, itemlist: [], used: 0 } }";
this.d = new dicts.Dict();
}
iter() {
return this.d.iter();
}
hash() {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.set(\"p2\", 4, 5)\ncoffee> b = new markings.Marking()\ncoffee> b.set(\"p1\", 3, 1, 2)\ncoffee> b.set(\"p2\", 5, 4)\ncoffee> a.hash() == b.hash()\ntrue";
var h, m, p, ref, x;
h = 7028009221;
ref = this.d.iter();
for (x of ref) {
[p, m] = x;
h ^= (dicts.hash(p) << 5) + dicts.hash(m);
}
return h;
}
eq(other) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.set(\"p2\", 4, 5)\ncoffee> b = new markings.Marking()\ncoffee> b.set(\"p1\", 3, 1, 2)\ncoffee> b.set(\"p2\", 5, 4)\ncoffee> a.eq(b)\ntrue";
if (!(other instanceof Marking)) {
return false;
}
return this.d.eq(other.d);
}
copy(id = null) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.set(\"p2\", 4, 5)\ncoffee> a.copy().eq(a)\ncoffee> a.copy() is a\nfalse";
var copy, m, p, ref, x;
copy = new Marking(id);
ref = this.iter();
for (x of ref) {
[p, m] = x;
copy.set(p, m.copy());
}
return copy;
}
has(place) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.set(\"p2\", 4, 5)\ncoffee> a.has(\"p1\")\ntrue\ncoffee> a.has(\"p3\")\nfalse";
return this.d.has(place);
}
set(place, ...tokens) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> console.log a.get(\"p1\").toString()\n[1, 2, 3]\ncoffee> a.set(\"p1\")\ncoffee> a.has(\"p1\")\nfalse";
if (tokens.length === 0 && this.has(place)) {
return this.d.del(place);
} else {
return this.d.set(place, new msets.Mset(...tokens));
}
}
update(place, tokens) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.set(\"p2\", 4, 5, 6)\ncoffee> a.update(\"p1\", a.get(\"p2\"))\ncoffee> console.log a.get(\"p1\").toString()\n[1, 2, 3, 4, 5, 6]";
if (this.has(place)) {
return this.d.get(place).add(tokens);
} else {
return this.d.set(place, tokens.copy());
}
}
get(place) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> console.log a.get(\"p1\").toString()\n[1, 2, 3]\ncoffee> console.log a.get(\"p2\").toString()\n[]";
return this.d.get(place, new msets.Mset());
}
empty(place) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.empty(\"p1\")\nfalse\ncoffee> a.empty(\"p2\")\ntrue";
return this.get(place).empty();
}
add(other) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> b = new markings.Marking()\ncoffee> b.set(\"p1\", 4)\ncoffee> b.set(\"p2\", 5, 6)\ncoffee> c = new markings.Marking()\ncoffee> c.set(\"p1\", 1, 2, 3, 4)\ncoffee> c.set(\"p2\", 5, 6)\ncoffee> a.add(b).eq(c)\ntrue";
var m, p, ref, x;
ref = other.iter();
for (x of ref) {
[p, m] = x;
this.update(p, m);
}
return this;
}
sub(other) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> b = new markings.Marking()\ncoffee> b.set(\"p1\", 2, 3)\ncoffee> b.set(\"p2\", 5)\ncoffee> c = new markings.Marking()\ncoffee> c.set(\"p1\", 1)\ncoffee> a.sub(b).eq(c)\ntrue";
var m, mine, p, ref, x;
ref = other.iter();
for (x of ref) {
[p, m] = x;
mine = this.d.get(p, this);
if (mine === this) {
// skip
} else if (m.geq(mine)) {
this.d.del(p);
} else {
this.d.set(p, mine.sub(m));
}
}
return this;
}
geq(other) {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> b = new markings.Marking()\ncoffee> b.set(\"p1\", 2, 3)\ncoffee> a.geq(b)\ntrue\ncoffee> b.set(\"p1\", 1, 2, 3)\ncoffee> a.geq(b)\ntrue\ncoffee> b.set(\"p1\", 1, 2, 3, 4)\ncoffee> b.get(\"p1\").d\ncoffee> a.geq(b)\nfalse\ncoffee> b.set(\"p1\", 1, 2, 3)\ncoffee> b.set(\"p2\", 4)\ncoffee> a.geq(b)\nfalse";
var m, p, ref, x;
ref = other.iter();
for (x of ref) {
[p, m] = x;
if (!this.get(p).geq(m)) {
return false;
}
}
return true;
}
toString() {
"coffee> a = new markings.Marking()\ncoffee> a.set(\"p1\", 1, 2, 3)\ncoffee> a.set(\"p2\", 3, 4)\ncoffee> console.log a.toString()\n{'p1': [1, 2, 3], 'p2': [3, 4]}";
var items, m, p;
items = (function() {
var ref, results, x;
ref = this.iter();
results = [];
for (x of ref) {
[p, m] = x;
results.push(`'${p}': ${m.toString()}`);
}
return results;
}).call(this);
return `{${items.join(', ')}}`;
}
};
module.exports = {
Marking: Marking
};
}).call(this);
//# sourceMappingURL=markings.js.map
{
"version": 3,
"file": "markings.js",
"sourceRoot": "../..",
"sources": [
"libs/js/markings.coffee"
],
"names": [],
"mappings": "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",
"sourcesContent": [
"dicts = require \"./dicts\"\nmsets = require \"./multisets\"\n\nclass Marking\n constructor: (@id=null) ->\n \"\"\"\n coffee> new markings.Marking()\n Marking { id: null, d: Dict { indices: {}, itemlist: [], used: 0 } }\n coffee> new markings.Marking(42)\n Marking { id: 42, d: Dict { indices: {}, itemlist: [], used: 0 } }\n \"\"\"\n @d = new dicts.Dict()\n iter: ->\n return @d.iter()\n hash: ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.set(\"p2\", 4, 5)\n coffee> b = new markings.Marking()\n coffee> b.set(\"p1\", 3, 1, 2)\n coffee> b.set(\"p2\", 5, 4)\n coffee> a.hash() == b.hash()\n true\n \"\"\"\n h = 7028009221\n for [p, m] from @d.iter()\n h ^= (dicts.hash(p) << 5) + dicts.hash(m)\n return h\n eq: (other) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.set(\"p2\", 4, 5)\n coffee> b = new markings.Marking()\n coffee> b.set(\"p1\", 3, 1, 2)\n coffee> b.set(\"p2\", 5, 4)\n coffee> a.eq(b)\n true\n \"\"\"\n if other not instanceof Marking\n return false\n return @d.eq(other.d)\n copy: (id=null) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.set(\"p2\", 4, 5)\n coffee> a.copy().eq(a)\n coffee> a.copy() is a\n false\n \"\"\"\n copy = new Marking(id)\n for [p, m] from @iter()\n copy.set(p, m.copy())\n return copy\n has: (place) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.set(\"p2\", 4, 5)\n coffee> a.has(\"p1\")\n true\n coffee> a.has(\"p3\")\n false\n \"\"\"\n return @d.has(place)\n set: (place, tokens...) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> console.log a.get(\"p1\").toString()\n [1, 2, 3]\n coffee> a.set(\"p1\")\n coffee> a.has(\"p1\")\n false\n \"\"\"\n if tokens.length == 0 and @has(place)\n @d.del(place)\n else\n @d.set(place, new msets.Mset(tokens...))\n update: (place, tokens) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.set(\"p2\", 4, 5, 6)\n coffee> a.update(\"p1\", a.get(\"p2\"))\n coffee> console.log a.get(\"p1\").toString()\n [1, 2, 3, 4, 5, 6]\n \"\"\"\n if @has(place)\n @d.get(place).add(tokens)\n else\n @d.set(place, tokens.copy())\n get: (place) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> console.log a.get(\"p1\").toString()\n [1, 2, 3]\n coffee> console.log a.get(\"p2\").toString()\n []\n \"\"\"\n return @d.get(place, new msets.Mset())\n empty: (place) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.empty(\"p1\")\n false\n coffee> a.empty(\"p2\")\n true\n \"\"\"\n return @get(place).empty()\n add: (other) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> b = new markings.Marking()\n coffee> b.set(\"p1\", 4)\n coffee> b.set(\"p2\", 5, 6)\n coffee> c = new markings.Marking()\n coffee> c.set(\"p1\", 1, 2, 3, 4)\n coffee> c.set(\"p2\", 5, 6)\n coffee> a.add(b).eq(c)\n true\n \"\"\"\n for [p, m] from other.iter()\n @update(p, m)\n return this\n sub: (other) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> b = new markings.Marking()\n coffee> b.set(\"p1\", 2, 3)\n coffee> b.set(\"p2\", 5)\n coffee> c = new markings.Marking()\n coffee> c.set(\"p1\", 1)\n coffee> a.sub(b).eq(c)\n true\n \"\"\"\n for [p, m] from other.iter()\n mine = @d.get(p, this)\n if mine is this\n # skip\n else if m.geq(mine)\n @d.del(p)\n else\n @d.set(p, mine.sub(m))\n return this\n geq: (other) ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> b = new markings.Marking()\n coffee> b.set(\"p1\", 2, 3)\n coffee> a.geq(b)\n true\n coffee> b.set(\"p1\", 1, 2, 3)\n coffee> a.geq(b)\n true\n coffee> b.set(\"p1\", 1, 2, 3, 4)\n coffee> b.get(\"p1\").d\n coffee> a.geq(b)\n false\n coffee> b.set(\"p1\", 1, 2, 3)\n coffee> b.set(\"p2\", 4)\n coffee> a.geq(b)\n false\n \"\"\"\n for [p, m] from other.iter()\n if not @get(p).geq(m)\n return false\n return true\n toString: ->\n \"\"\"\n coffee> a = new markings.Marking()\n coffee> a.set(\"p1\", 1, 2, 3)\n coffee> a.set(\"p2\", 3, 4)\n coffee> console.log a.toString()\n {'p1': [1, 2, 3], 'p2': [3, 4]}\n \"\"\"\n items = (\"'#{ p }': #{ m.toString() }\" for [p, m] from @iter())\n return \"{#{ items.join(', ') }}\"\n\nmodule.exports =\n Marking: Marking\n"
]
}
\ No newline at end of file
......@@ -2,16 +2,164 @@ dicts = require "./dicts"
class Mset
constructor: (items...) ->
"""
coffee> new multisets.Mset(1, 2, 3)
Mset{d: Dict{indices: {...}, itemlist: [..., ..., ...], used: 3}}
"""
@d = new dicts.Dict()
for i in items
@d.set(i, @d.get(i, 0) + 1)
iter: ->
"""
coffee> (i for i from new multisets.Mset(1, 2, 2, 3, 3, 3).iter())
[ 1, 2, 3 ]
coffee> (i for i from new multisets.Mset().iter())
[]
"""
for [k, n] from @d.iter()
yield k
iterdup: ->
"""
coffee> (i for i from new multisets.Mset(1, 2, 2, 3, 3, 3).iterdup())
[ 1, 2, 2, 3, 3, 3 ]
coffee> (i for i from new multisets.Mset().iterdup())
[]
"""
for [k, n] from @d.iter()
for i in [1..n]
yield k
hash: ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> b = new multisets.Mset(3, 2, 3, 2, 3, 1)
coffee> c = new multisets.Mset(1, 2, 3)
coffee> a.hash() == b.hash()
true
coffee> a.hash() == c.hash()
false
"""
h = 2485867687
for [k, n] from @d.iter()
h ^= (dicts.hash(k) << 5) + dicts.hash(n)
return h
eq: (other) ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> b = new multisets.Mset(3, 2, 3, 2, 3, 1)
coffee> c = new multisets.Mset(1, 2, 3)
coffee> a.eq(b)
true
coffee> a.eq(c)
false
coffee> (new multisets.Mset()).eq(new multisets.Mset())
true
"""
if other not instanceof Mset
return false
return @d.eq(other.d)
copy: ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> a.eq(a.copy())
true
coffee> a is a.copy()
false
"""
return new Mset(@iterdup()...)
len: ->
"""
coffee> (new multisets.Mset()).len()
0
coffee> (new multisets.Mset(1, 2, 2, 3, 3, 3)).len()
6
"""
len = 0
for [k, n] from @d.iter()
len += n
return len
add: (other) ->
"""
coffee> a = new multisets.Mset(1, 2, 3)
coffee> b = new multisets.Mset(2, 3, 3)
coffee> a.add(b)
coffee> a.eq(new multisets.Mset(1, 2, 2, 3, 3, 3))
true
"""
for [k, n] from other.d.iter()
@d.set(k, @d.get(k, 0) + n)
return this
sub: (other) ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> b = new multisets.Mset(2, 3, 3)
coffee> c = new multisets.Mset(1, 2, 3)
coffee> d = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> a.sub(b)
coffee> a.eq(c)
true
coffee> a.sub(c).len()
0
coffee> c.sub(d).len()
0
"""
for [k, n] from other.d.iter()
m = @d.get(k, 0)
if m <= n
@d.del(k)
else
@d.set(k, m - n)
return this
geq: (other) ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> b = new multisets.Mset(2, 3, 3)
coffee> c = new multisets.Mset(1, 2, 3)
coffee> a.geq(b)
true
coffee> b.geq(c)
false
"""
for [k, n] from other.d.iter()
if not @d.get(k, 0) >= n
return false
return true
empty: ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> b = new multisets.Mset()
coffee> a.empty()
false
coffee> b.empty()
true
"""
return @d.used == 0
count: (value) ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> (a.count(i) for i in [0...4])
[ 0, 1, 2, 3 ]
"""
return @d.get(value, 0)
map: (func) ->
"""
coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)
coffee> b = a.map((k, n) -> [k+1, n+1])
coffee> b.eq(new multisets.Mset(2, 2, 3, 3, 3, 4, 4, 4, 4))
true
"""
copy = new Mset()
for [k, n] from @d.iter()
copy.d.set(func(k, n)...)
return copy
toString: ->
"""
coffee> console.log new multisets.Mset(1, 2, 2, 3, 3, 3).toString()
[1, 2, 2, 3, 3, 3]
coffee> console.log new multisets.Mset().toString()
[]
"""
items = ("#{ v }" for v from @iterdup())
return "[#{ items.join(', ') }]"
m = new Mset(1, 2, 2, 3, 3, 3)
console.log m.d
module.exports =
Mset: Mset
......
// Generated by CoffeeScript 2.0.2
(function() {
var Mset, dicts, m;
var Mset, dicts;
dicts = require("./dicts");
Mset = class Mset {
constructor(...items) {
var i, j, len;
"coffee> new multisets.Mset(1, 2, 3)\nMset{d: Dict{indices: {...}, itemlist: [..., ..., ...], used: 3}}";
var i, j, len1;
this.d = new dicts.Dict();
for (j = 0, len = items.length; j < len; j++) {
for (j = 0, len1 = items.length; j < len1; j++) {
i = items[j];
this.d.set(i, this.d.get(i, 0) + 1);
}
}
toString() {}
* iter() {
"coffee> (i for i from new multisets.Mset(1, 2, 2, 3, 3, 3).iter())\n[ 1, 2, 3 ]\ncoffee> (i for i from new multisets.Mset().iter())\n[]";
var k, n, ref, results, x;
ref = this.d.iter();
results = [];
for (x of ref) {
[k, n] = x;
results.push((yield k));
}
return results;
}
};
* iterdup() {
"coffee> (i for i from new multisets.Mset(1, 2, 2, 3, 3, 3).iterdup())\n[ 1, 2, 2, 3, 3, 3 ]\ncoffee> (i for i from new multisets.Mset().iterdup())\n[]";
var i, k, n, ref, results, x;
ref = this.d.iter();
results = [];
for (x of ref) {
[k, n] = x;
results.push((yield* (function*() {
var j, ref1, results1;
results1 = [];
for (i = j = 1, ref1 = n; 1 <= ref1 ? j <= ref1 : j >= ref1; i = 1 <= ref1 ? ++j : --j) {
results1.push((yield k));
}
return results1;
})()));
}
return results;
}
hash() {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> b = new multisets.Mset(3, 2, 3, 2, 3, 1)\ncoffee> c = new multisets.Mset(1, 2, 3)\ncoffee> a.hash() == b.hash()\ntrue\ncoffee> a.hash() == c.hash()\nfalse";
var h, k, n, ref, x;
h = 2485867687;
ref = this.d.iter();
for (x of ref) {
[k, n] = x;
h ^= (dicts.hash(k) << 5) + dicts.hash(n);
}
return h;
}
eq(other) {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> b = new multisets.Mset(3, 2, 3, 2, 3, 1)\ncoffee> c = new multisets.Mset(1, 2, 3)\ncoffee> a.eq(b)\ntrue\ncoffee> a.eq(c)\nfalse\ncoffee> (new multisets.Mset()).eq(new multisets.Mset())\ntrue";
if (!(other instanceof Mset)) {
return false;
}
return this.d.eq(other.d);
}
copy() {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> a.eq(a.copy())\ntrue\ncoffee> a is a.copy()\nfalse";
return new Mset(...this.iterdup());
}
len() {
"coffee> (new multisets.Mset()).len()\n0\ncoffee> (new multisets.Mset(1, 2, 2, 3, 3, 3)).len()\n6";
var k, len, n, ref, x;
len = 0;
ref = this.d.iter();
for (x of ref) {
[k, n] = x;
len += n;
}
return len;
}
add(other) {
"coffee> a = new multisets.Mset(1, 2, 3)\ncoffee> b = new multisets.Mset(2, 3, 3)\ncoffee> a.add(b)\ncoffee> a.eq(new multisets.Mset(1, 2, 2, 3, 3, 3))\ntrue";
var k, n, ref, x;
ref = other.d.iter();
for (x of ref) {
[k, n] = x;
this.d.set(k, this.d.get(k, 0) + n);
}
return this;
}
sub(other) {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> b = new multisets.Mset(2, 3, 3)\ncoffee> c = new multisets.Mset(1, 2, 3)\ncoffee> d = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> a.sub(b)\ncoffee> a.eq(c)\ntrue\ncoffee> a.sub(c).len()\n0\ncoffee> c.sub(d).len()\n0";
var k, m, n, ref, x;
ref = other.d.iter();
for (x of ref) {
[k, n] = x;
m = this.d.get(k, 0);
if (m <= n) {
this.d.del(k);
} else {
this.d.set(k, m - n);
}
}
return this;
}
geq(other) {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> b = new multisets.Mset(2, 3, 3)\ncoffee> c = new multisets.Mset(1, 2, 3)\ncoffee> a.geq(b)\ntrue\ncoffee> b.geq(c)\nfalse";
var k, n, ref, x;
ref = other.d.iter();
for (x of ref) {
[k, n] = x;
if (!this.d.get(k, 0) >= n) {
return false;
}
}
return true;
}
empty() {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> b = new multisets.Mset()\ncoffee> a.empty()\nfalse\ncoffee> b.empty()\ntrue";
return this.d.used === 0;
}
m = new Mset(1, 2, 2, 3);
count(value) {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> (a.count(i) for i in [0...4])\n[ 0, 1, 2, 3 ] ";
return this.d.get(value, 0);
}
console.log(m);
map(func) {
"coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\ncoffee> b = a.map((k, n) -> [k+1, n+1])\ncoffee> b.eq(new multisets.Mset(2, 2, 3, 3, 3, 4, 4, 4, 4))\ntrue";
var copy, k, n, ref, x;
copy = new Mset();
ref = this.d.iter();
for (x of ref) {
[k, n] = x;
copy.d.set(...func(k, n));
}
return copy;
}
toString() {
"coffee> console.log new multisets.Mset(1, 2, 2, 3, 3, 3).toString()\n[1, 2, 2, 3, 3, 3]\ncoffee> console.log new multisets.Mset().toString()\n[]";
var items, v;
items = (function() {
var ref, results;
ref = this.iterdup();
results = [];
for (v of ref) {
results.push(`${v}`);
}
return results;
}).call(this);
return `[${items.join(', ')}]`;
}
};
module.exports = {
Mset: Mset
};
}).call(this);
......
......@@ -6,8 +6,8 @@
"libs/js/multisets.coffee"
],
"names": [],
"mappings": ";AAAA;AAAA,MAAA,IAAA,EAAA,KAAA,EAAA;;EAAA,KAAA,GAAQ,OAAA,CAAQ,SAAR;;EAEF,OAAN,MAAA,KAAA;IACI,WAAa,CAAA,GAAC,KAAD,CAAA;AACT,UAAA,CAAA,EAAA,CAAA,EAAA;MAAA,IAAC,CAAA,CAAD,GAAK,IAAI,KAAK,CAAC,IAAV,CAAA;MACL,KAAA,uCAAA;;QACI,IAAC,CAAA,CAAC,CAAC,GAAH,CAAO,CAAP,EAAU,IAAC,CAAA,CAAC,CAAC,GAAH,CAAO,CAAP,EAAU,CAAV,CAAA,GAAe,CAAzB;MADJ;IAFS;;IAIb,QAAU,CAAA,CAAA,EAAA;;EALd;;EAQA,CAAA,GAAI,IAAI,IAAJ,CAAS,CAAT,EAAY,CAAZ,EAAe,CAAf,EAAkB,CAAlB;;EACJ,OAAO,CAAC,GAAR,CAAY,CAAZ;AAXA",
"mappings": "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",
"sourcesContent": [
"dicts = require \"./dicts\"\n\nclass Mset\n constructor: (items...) ->\n @d = new dicts.Dict()\n for i in items\n @d.set(i, @d.get(i, 0) + 1)\n toString: ->\n \n\nm = new Mset(1, 2, 2, 3)\nconsole.log m\n"
"dicts = require \"./dicts\"\n\nclass Mset\n constructor: (items...) ->\n \"\"\"\n coffee> new multisets.Mset(1, 2, 3)\n Mset{d: Dict{indices: {...}, itemlist: [..., ..., ...], used: 3}}\n \"\"\"\n @d = new dicts.Dict()\n for i in items\n @d.set(i, @d.get(i, 0) + 1)\n iter: ->\n \"\"\"\n coffee> (i for i from new multisets.Mset(1, 2, 2, 3, 3, 3).iter())\n [ 1, 2, 3 ]\n coffee> (i for i from new multisets.Mset().iter())\n []\n \"\"\"\n for [k, n] from @d.iter()\n yield k\n iterdup: ->\n \"\"\"\n coffee> (i for i from new multisets.Mset(1, 2, 2, 3, 3, 3).iterdup())\n [ 1, 2, 2, 3, 3, 3 ]\n coffee> (i for i from new multisets.Mset().iterdup())\n []\n \"\"\"\n for [k, n] from @d.iter()\n for i in [1..n]\n yield k\n hash: ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> b = new multisets.Mset(3, 2, 3, 2, 3, 1)\n coffee> c = new multisets.Mset(1, 2, 3)\n coffee> a.hash() == b.hash()\n true\n coffee> a.hash() == c.hash()\n false\n \"\"\"\n h = 2485867687\n for [k, n] from @d.iter()\n h ^= (dicts.hash(k) << 5) + dicts.hash(n)\n return h\n eq: (other) ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> b = new multisets.Mset(3, 2, 3, 2, 3, 1)\n coffee> c = new multisets.Mset(1, 2, 3)\n coffee> a.eq(b)\n true\n coffee> a.eq(c)\n false\n coffee> (new multisets.Mset()).eq(new multisets.Mset())\n true\n \"\"\"\n if other not instanceof Mset\n return false\n return @d.eq(other.d)\n copy: ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> a.eq(a.copy())\n true\n coffee> a is a.copy()\n false\n \"\"\"\n return new Mset(@iterdup()...)\n len: ->\n \"\"\"\n coffee> (new multisets.Mset()).len()\n 0\n coffee> (new multisets.Mset(1, 2, 2, 3, 3, 3)).len()\n 6\n \"\"\"\n len = 0\n for [k, n] from @d.iter()\n len += n\n return len\n add: (other) ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 3)\n coffee> b = new multisets.Mset(2, 3, 3)\n coffee> a.add(b)\n coffee> a.eq(new multisets.Mset(1, 2, 2, 3, 3, 3))\n true\n \"\"\"\n for [k, n] from other.d.iter()\n @d.set(k, @d.get(k, 0) + n)\n return this\n sub: (other) ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> b = new multisets.Mset(2, 3, 3)\n coffee> c = new multisets.Mset(1, 2, 3)\n coffee> d = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> a.sub(b)\n coffee> a.eq(c)\n true\n coffee> a.sub(c).len()\n 0\n coffee> c.sub(d).len()\n 0\n \"\"\"\n for [k, n] from other.d.iter()\n m = @d.get(k, 0)\n if m <= n\n @d.del(k)\n else\n @d.set(k, m - n)\n return this\n geq: (other) ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> b = new multisets.Mset(2, 3, 3)\n coffee> c = new multisets.Mset(1, 2, 3)\n coffee> a.geq(b)\n true\n coffee> b.geq(c)\n false\n \"\"\"\n for [k, n] from other.d.iter()\n if not @d.get(k, 0) >= n\n return false\n return true\n empty: ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> b = new multisets.Mset()\n coffee> a.empty()\n false\n coffee> b.empty()\n true\n \"\"\"\n return @d.used == 0\n count: (value) ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> (a.count(i) for i in [0...4])\n [ 0, 1, 2, 3 ] \n \"\"\"\n return @d.get(value, 0)\n map: (func) ->\n \"\"\"\n coffee> a = new multisets.Mset(1, 2, 2, 3, 3, 3)\n coffee> b = a.map((k, n) -> [k+1, n+1])\n coffee> b.eq(new multisets.Mset(2, 2, 3, 3, 3, 4, 4, 4, 4))\n true\n \"\"\"\n copy = new Mset()\n for [k, n] from @d.iter()\n copy.d.set(func(k, n)...)\n return copy\n toString: ->\n \"\"\"\n coffee> console.log new multisets.Mset(1, 2, 2, 3, 3, 3).toString()\n [1, 2, 2, 3, 3, 3]\n coffee> console.log new multisets.Mset().toString()\n []\n \"\"\"\n items = (\"#{ v }\" for v from @iterdup())\n return \"[#{ items.join(', ') }]\"\n\nmodule.exports =\n Mset: Mset\n"
]
}
\ No newline at end of file
......
coffee -c -m libs/js/
coffee -c -m "$@" libs/js/*.coffee
......
import os, os.path, subprocess, re
def walk (root='libs/js') :
for dirpath, dirnames, filenames in os.walk(root) :
for name in filenames :
if name.endswith('.coffee') :
yield os.path.relpath(os.path.join(dirpath, name), root)
class Test (object) :
def __init__ (self, path, lineno, src, out) :
self.path = path
self.lineno = lineno
self.src = src
self.out = out
@classmethod
def require (cls, root, path) :
base = os.path.splitext(path)[0]
name = os.path.basename(base)
full = os.path.join(".", root, base)
return cls(path, 0, "%s = require %r" % (name, full), [])
@classmethod
def bunch (cls, root, path, bunch) :
return [cls.require(root, path)] + bunch
def codegen (self, out) :
out.write("console.log '+++ %s:%s +++'\n" % (self.path, self.lineno))
out.write(self.src + "\n")
out.write("console.log '--- %s:%s ---'\n" % (self.path, self.lineno))
if self.lineno > 0 :
return "%s:%s" % (self.path, self.lineno)
def _fail (self, out) :
print("\n#### %s:%s" % (self.path, self.lineno))
print("%s" % self.src)
print("## expected:")
print("\n".join(self.out))
print("## obtained:")
print("\n".join(out))
def check (self, out) :
if self.src.startswith and out and out[-1] == "undefined" :
del out[-1]
if out and out[0].startswith("[stdin]:") :
self._fail(out)
return False
elif any("..." in s for s in self.out) :
o = re.sub(r"\s", "", "".join(out))
e = re.sub(r"\s", "", "".join(self.out))
e = re.escape(e).replace(r"\.\.\.", ".*?")
if re.match("^%s$" % e, o) :
return True
else :
self._fail(out)
return False
elif not self.out or out == self.out :
return True
else :
self._fail(out)
return False
def extract (root, path) :
bunch = []
src = delim = None
out = []
for num, line in enumerate(open(os.path.join(root, path))) :
stripped = line.strip()
if stripped == delim :
if src is not None :
bunch.append(Test(path, *src, out))
out, src = [], None
if bunch :
yield Test.bunch(root, path, bunch)
delim = None
bunch = []
elif stripped in ("'''", '"""') :
delim = stripped
elif delim and stripped.startswith("coffee>") :
if src is not None :
bunch.append(Test(path, *src, out))
out, src = [], None
src = (num + 1, stripped[7:].strip())
elif delim :
out.append(stripped)
if bunch :
yield Test.bunch(root, path, bunch)
def codegen (tests, path) :
d = {}
with open(path, "w") as out :
for t in tests :
key = t.codegen(out)
if key :
d[key] = t
return d
def run (src) :
try :
out = subprocess.check_output(["coffee", "-i"],
stdin=open(src),
stderr=subprocess.STDOUT)
out = out.decode().splitlines()
except subprocess.CalledProcessError as err :
out = err.output.decode().splitlines()
for line in out :
while line.startswith("coffee> ") :
line = line[8:]
if line.strip() :
yield line.rstrip()
def check_output (out, tests) :
passed = failed = 0
tid = None
tout = []
skip = False
for line in out :
if skip :
skip = False
elif line.startswith("+++") :
tid = line.split()[1]
tout = []
skip = True
elif line.startswith("---") :
skip = True
assert line.split()[1] == tid
if tid not in tests :
continue
t = tests[tid]
if t.check(tout) :
passed += 1
else :
failed += 1
else :
tout.append(line)
return passed, failed
if __name__ == "__main__" :
root = "libs/js"
passed, failed = 0, 0
nl = False
for path in walk(root) :
base = os.path.basename(os.path.splitext(path)[0])
for num, tests in enumerate(extract(root, path)) :
if nl :
print()
nl = False
print("+ %s: %s tests" % (os.path.join(root, path), len(tests) - 1))
src = ",test-%s-%04u.coffee" % (base, num)
tests = codegen(tests, src)
out = run(src)
p, f = check_output(out, tests)
passed += p
failed += f
nl = f > 0
os.unlink(src)
if failed :
print()
print("= %s tests failed (out of %s)" % (failed, failed+passed))