UNPKG

mahler

Version:

A automated task composer and HTN based planner for building autonomous system agents

142 lines 3.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.plan = plan; exports.branch = branch; exports.fork = fork; exports.sequence = sequence; const dag_1 = require("../dag"); const Label = { of(id) { return dag_1.Node.value({ id }); }, }; // Create a linked list from a list of strings // returns the head and tail of the list function fromList(elems) { const [first, ...labels] = elems; const root = Label.of(first); let tail = root; for (const label of labels) { const node = Label.of(label); tail.next = node; tail = node; } return [root, tail]; } function fromFork(branches) { branches = branches.filter((b) => b.length > 0); // If all branches are empty, return if (branches.length === 0) { return [null, null]; } // If there is only a branch, call the branch method if (branches.length === 1) { return fromBranch(branches[0]); } // For multiple branches, create a fork and // a join for the ends const root = dag_1.Node.fork(); const tail = dag_1.Node.join(); for (const b of branches) { const [r, t] = fromBranch(b); // We already checked that the branch is not empty // but typescript cannot infer that so we wrap this in // an if if (r != null && t != null) { t.next = tail; root.next.push(r); } } return [root, tail]; } function fromBranch(elems) { let root = null; let tail = null; while (elems.length > 0) { let r = null; let t = null; // Find the next fork const forkIndex = elems.findIndex((e) => Array.isArray(e)); const length = forkIndex > 0 ? forkIndex : elems.length; if (forkIndex === 0) { // If the fork is the first element of the branch, create a fork const branches = elems.shift(); [r, t] = fromFork(branches); } else if (length > 0) { // Otherwise create a sequence with the first N elements of the branch [r, t] = fromList(elems.splice(0, length)); } if (root == null) { root = r; tail = t; } else if (tail != null) { tail.next = r; tail = t; } } return [root, tail]; } /** * Start building a plan */ function plan() { let root = null; let tail = null; function setEnds(r, t) { if (root == null) { root = r; tail = t; } else if (tail != null) { tail.next = r; tail = t; } } const builder = { action(description) { return builder.actions(description); }, actions(...descriptions) { const [r, t] = fromList(descriptions); setEnds(r, t); return builder; }, fork(...branches) { const [r, t] = fromFork(branches); setEnds(r, t); return builder; }, root() { return root; }, end() { return (0, dag_1.toString)(root, (l) => l.id); }, }; return builder; } /** * Utility method to create a branch from an array * of values * * Each value may be a string or the result of `fork()` */ function branch(...values) { return values.filter((v) => !Array.isArray(v) || v.length > 0); } /** * Create a new fork from a list of branches * * Branches are returned by the `branch` method */ function fork(...branches) { return branches.filter((b) => b.length > 0); } function sequence(...actions) { return plan() .actions(...actions) .end(); } //# sourceMappingURL=builder.js.map