Skip to content

Commit

Permalink
[emscripten] javascript translator
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Tran committed Oct 15, 2021
1 parent 323a8b3 commit 3906c6b
Show file tree
Hide file tree
Showing 67 changed files with 1,031 additions and 783 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ __pycache__/
/experiments/issue*/data/
/misc/.tox/
/misc/autodoc/downward-xmlrpc.secret
*.cc.o
/src/bin
/src/CMakeFiles
/src/Makefile
/src/search/Makefile
/src/search/CMakeFiles
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
cd "$(dirname "$0")/../"
cd "$(dirname "$0")/../../"
if [ $# -eq 0 ]; then
echo "No arguments provided"
echo "Run either with "
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ downwardscript.onload = function() {
let stream = FS.open('output.sas', 'w+');
FS.write(stream, data, 0, data.length, 0);
FS.close(stream);
console.log('wrote to output.sas');
console.log('wrote to' + PATH_TO_INPUT);
}
}
inputXHR.send();
Expand Down
19 changes: 19 additions & 0 deletions src/javascript/translator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Translator in the browser
We offer to build the translator as python wheel.
This is done by executing the `setup.py` script.
**Pyodide** can then be used to load the python wheel in the browser.

## How to execute the translator using pyodide
The following steps are exemplarily presented in `usage_example.html` and `usage_example.js`
- you need to serve the JS file through a server; python can be used for that: `python -m http.server`
- in your javascript file, load the current pyodide version
- load pyodide's *micropip* package
- load the *.pddl* files into two javascript strings
- use micropip to install the translator-wheel created by `setup.py` into the python environment
- store the pddl strings to the browser's virtual filesystem using python
- import and execute the translator in python:
```Python
from translator.translate import run
run(["domain.pddl", "problem.pddl", "--sas-file", "output.sas"])
```
- load the result from the python environment to the javascript environment for further use
34 changes: 34 additions & 0 deletions src/javascript/translator/exampleFiles/domain.pddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
(define (domain gripper-strips)
(:predicates (room ?r)
(ball ?b)
(gripper ?g)
(at-robby ?r)
(at ?b ?r)
(free ?g)
(carry ?o ?g))

(:action move
:parameters (?from ?to)
:precondition (and (room ?from) (room ?to) (at-robby ?from))
:effect (and (at-robby ?to)
(not (at-robby ?from))))



(:action pick
:parameters (?obj ?room ?gripper)
:precondition (and (ball ?obj) (room ?room) (gripper ?gripper)
(at ?obj ?room) (at-robby ?room) (free ?gripper))
:effect (and (carry ?obj ?gripper)
(not (at ?obj ?room))
(not (free ?gripper))))


(:action drop
:parameters (?obj ?room ?gripper)
:precondition (and (ball ?obj) (room ?room) (gripper ?gripper)
(carry ?obj ?gripper) (at-robby ?room))
:effect (and (at ?obj ?room)
(free ?gripper)
(not (carry ?obj ?gripper)))))

22 changes: 22 additions & 0 deletions src/javascript/translator/exampleFiles/problem.pddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(define (problem strips-gripper-x-1)
(:domain gripper-strips)
(:objects rooma roomb ball4 ball3 ball2 ball1 left right)
(:init (room rooma)
(room roomb)
(ball ball4)
(ball ball3)
(ball ball2)
(ball ball1)
(at-robby rooma)
(free left)
(free right)
(at ball4 rooma)
(at ball3 rooma)
(at ball2 rooma)
(at ball1 rooma)
(gripper left)
(gripper right))
(:goal (and (at ball4 roomb)
(at ball3 roomb)
(at ball2 roomb)
(at ball1 roomb))))
35 changes: 35 additions & 0 deletions src/javascript/translator/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#! /usr/bin/python3
import os
import sys

sys.argv.append("bdist_wheel")

home = os.getcwd()

# go to translator root folder
os.chdir("../../translate")

# setup for bdist_wheel
from setuptools import setup, find_packages
setup(
name = 'translator',
version='1.0',
# Use one of the below approach to define package and/or module names:

#if there are only handful of modules placed in root directory, and no packages/directories exist then can use below syntax
# packages=[''], #have to import modules directly in code after installing this wheel, like import mod2 (respective file name in this case is mod2.py) - no direct use of distribution name while importing

#can list down each package names - no need to keep __init__.py under packages / directories
packages=['translator', 'translator/pddl', 'translator/pddl_parser'], #importing is like: from package1 import mod2, or import package1.mod2 as m2

# this approach automatically finds out all directories (packages) - those must contain a file named __init__.py (can be empty)
# packages=find_packages(), #include/exclude arguments take * as wildcard, . for any sub-package names
)

# move files to home directory and remove unnecessary files
import shutil
shutil.rmtree('build/')
shutil.rmtree('translator.egg-info/')
for file in os.listdir('dist'):
shutil.move('dist/' + file, os.path.join(home, file))
shutil.rmtree('dist/')
43 changes: 43 additions & 0 deletions src/javascript/translator/usage_example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Translator</title>
<script src="https://cdn.jsdelivr.net/pyodide/v0.18.1/full/pyodide.js" type="text/javascript"></script>
<script src="usage_example.js" type="text/javascript" defer></script>
</head>
<body>
<h1>Translator in the browser</h1>
Usage example
<br>
<hr>

<style>
.contentHolder {
display: flex;
}
.contentHolder > div {
padding: 0vh 1vw;
}
.result {
padding: 0vh 1vw;
}
</style>
<div class=contentHolder>
<div class="domain">
<h5>Domain:</h5>
<code>...</code>
</div>
<div class="problem">
<h5>Problem:</h5>
<code>...</code>
</div>
</div>
<hr>

<div class=result>
<code></code>
</div>
</body>
</html>

85 changes: 85 additions & 0 deletions src/javascript/translator/usage_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
var domain;
var problem;
var pyodide;

let loadFile = async (path) => {
return new Promise(resolve => {
console.log(`requesting ${path}`)
let request = new XMLHttpRequest()
request.open('GET', path)
request.responseType = 'text';
request.onload = () => {
result = request.responseText;
console.log(result);
resolve(result);
}
request.send();
})
}

let pythonCode_InstallTranslator = `
import micropip
micropip.install("translator-1.0-py3-none-any.whl")
`
let pythonCode_storePDDLToFilesystem = `
import js
problem = js.window.problem
domain = js.window.domain
with open('domain.pddl', 'w') as file:
file.write(domain)
with open('problem.pddl', 'w') as file:
file.write(problem)
`
let pythonCode_runTranslator = `
from translator.translate import run
run(["domain.pddl", "problem.pddl", "--sas-file", "output.sas"])
with open('output.sas', 'r') as file:
output_sas = file.read()
`

let showSourceFiles = (domain, problem) => {
domainHolder = document.querySelector("div[class='domain']").children[1];
problemHolder = document.querySelector("div[class='problem']").children[1];
domainHolder.innerText = domain;
problemHolder.innerText = problem;
}

let main = async () => {
let installTranslator = async () => {
return pyodide.runPython(pythonCode_InstallTranslator)
}
let storePDDLToFilesystem = async () => {
return pyodide.runPython(pythonCode_storePDDLToFilesystem)
}
let runTranslator = async () => {
return pyodide.runPython(pythonCode_runTranslator)
}

// load pyodide
pyodide = await loadPyodide({ indexURL : "https://cdn.jsdelivr.net/pyodide/v0.18.1/full/" });

// load micropip
await pyodide.loadPackage('micropip');

// load pddl files
domain = await loadFile('exampleFiles/domain.pddl');
problem = await loadFile('exampleFiles/problem.pddl');
showSourceFiles(domain, problem);

// run python
await installTranslator();
await storePDDLToFilesystem();
runTranslator();

// read result
let r = pyodide.globals.output_sas;
console.log(r);
resultHolder = document.querySelector("div[class='result']").children[0];
resultHolder.innerText = r;
};

main();
Loading

0 comments on commit 3906c6b

Please sign in to comment.