Skip to content

Commit

Permalink
Merge pull request #140 from QuMuLab/amdn
Browse files Browse the repository at this point in the history
AMDN
  • Loading branch information
haz authored Nov 23, 2021
2 parents e402d8c + e220510 commit 9ecd31f
Show file tree
Hide file tree
Showing 64 changed files with 3,255 additions and 756 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ __init__.pyc
generated_testing_files/
new_domain.pddl
new_prob.pddl
test_model.json
test_model.json
results.txt
html/
13 changes: 12 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
### Installing

Install macq for development by cloning the repository and running
`pip install .[dev]`
`pip install -e .[dev]`

We recommend installing in a virtual environment to avoid package version
conflicts.

**Note: `tarski` requires [`clingo`](https://potassco.org/clingo/) be installed to work.**

### Formatting

We use [black](https://black.readthedocs.io/en/stable/) for easy and consistent
Expand All @@ -34,3 +36,12 @@ report, run `pytest --cov=macq --cov-report=html`, and open `htmlcov/index.html`
in a browser. This will provide detailed line by line test coverage information,
so you can identify what specifically still needs testing.

### Generating Docs
To generate the HTML documentation, run `pdoc --html macq --config latex_math=True`.

During development, you can run a local HTTP server to reference/see live
changes to the documentation: `pdoc --http : macq --config latex_math=True`.

*Note: `--config latex_math=True` is required to properly render the latex found
in many extraction techniques' documentation.*

52 changes: 4 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This library is a collection of tools for planning-like action model acquisition
## Usage <a name="usage" />
```python
from macq import generate, extract
from macq.observation import IdentityObservation
from macq.observation import IdentityObservation, AtomicPartialObservation

# get a domain-specific generator: uses api.planning.domains problem_id/
# generate 100 traces of length 20 using vanilla sampling
Expand All @@ -39,50 +39,6 @@ trace.actions
trace.get_pre_states(action) # get the state before each occurance of action
trace.get_post_states(action) # state after each occurance of action
trace.get_total_cost()

######################################################################
# Model Extraction - OBSERVER Technique
######################################################################
observations = traces.tokenize(IdentityObservation)
model = extract.Extract(observations, extract.modes.OBSERVER)
model.details()

Model:
Fluents: at stone stone-03 location pos-04-06, at stone stone-01 location pos-04-06, at stone stone-02 location pos-05-06, at stone stone-06 location pos-07-04, at stone stone-11 ...
Actions:
push-to-goal stone stone-04 location pos-04-05 location pos-04-06 direction dir-up location pos-04-04 player player-01:
precond:
at player player-01 location pos-04-06
at stone stone-04 location pos-04-05
clear location pos-05-06
...
add:
at stone stone-04 location pos-04-04
clear location pos-04-06
at-goal stone stone-04
at player player-01 location pos-04-05
delete:
at stone stone-04 location pos-04-05
clear location pos-04-04
at player player-01 location pos-04-06
...
######################################################################
# Model Extraction - SLAF Technique
######################################################################
traces = generate.pddl.VanillaSampling(problem_id = 123, plan_len = 2, num_traces = 1).traces
observations = traces.tokenize(PartialObservabilityToken, method=PartialObservabilityToken.random_subset, percent_missing=0.10)
model = Extract(observations, modes.SLAF)
model.details()

Model:
Fluents: clear location pos-06-09, clear location pos-02-05, clear location pos-08-08, clear location pos-10-05, clear location pos-02-06, clear location pos-10-02, clear location pos-01-01, at stone stone-05 location pos-08-05, at stone stone-07 location pos-08-06, at stone stone-03 location pos-07-04, clear location pos-03-06, clear location pos-10-06, clear location pos-10-10, clear location pos-05-09, clear location pos-05-07, clear location pos-02-07, clear location pos-09-01, at stone stone-06 location pos-04-06, clear location pos-02-03, clear location pos-07-05, clear location pos-09-10, clear location pos-06-05, at stone stone-01 location pos-05-04, clear location pos-02-10, clear location pos-06-10, clear location pos-11-03, at stone stone-11 location pos-06-08, at stone stone-08 location pos-04-07, clear location pos-01-10, clear location pos-07-03, clear location pos-02-11, clear location pos-03-01, clear location pos-06-02, clear location pos-03-02, clear location pos-11-01, clear location pos-06-03, clear location pos-08-04, clear location pos-09-11, at stone stone-09 location pos-08-07, clear location pos-09-07, clear location pos-06-07, clear location pos-10-01, clear location pos-11-09, clear location pos-03-05, clear location pos-07-06, clear location pos-05-05, at stone stone-12 location pos-07-08, clear location pos-10-03, clear location pos-11-11, clear location pos-10-09, clear location pos-02-01, clear location pos-02-02, clear location pos-01-02, at stone stone-02 location pos-06-04, clear location pos-03-10, clear location pos-05-10, clear location pos-07-10, clear location pos-09-05, clear location pos-07-09, clear location pos-05-03, clear location pos-10-11, clear location pos-01-03, at stone stone-04 location pos-04-05, clear location pos-07-02, clear location pos-09-06, clear location pos-10-07, clear location pos-01-09, clear location pos-03-07, clear location pos-04-04, clear location pos-01-11
Actions:
move player player-01 direction dir-left location pos-05-02 location pos-06-02:
precond:
add:
delete:
(clear location pos-05-02)
(at player player-01 location pos-06-02)
```

## Coverage <a name="coverage"></a>
Expand All @@ -92,9 +48,9 @@ Model:
- [x] [Learning Planning Operators by Observation and Practice](https://aaai.org/Papers/AIPS/1994/AIPS94-057.pdf) (AIPS'94)
- [ ] [Learning by Experimentation: Incremental Refinement of Incomplete Planning Domains](https://www.sciencedirect.com/science/article/pii/B9781558603356500192) (ICML'94)
- [ ] [Learning Probabilistic Relational Planning Rules](https://people.csail.mit.edu/lpk/papers/2005/zpk-aaai05.pdf) (ICAPS'04)
- [ ] [Learning Action Models from Plan Examples with Incomplete Knowledge](https://www.aaai.org/Papers/ICAPS/2005/ICAPS05-025.pdf) (ICAPS'05)
- [x] [Learning Action Models from Plan Examples with Incomplete Knowledge](https://www.aaai.org/Papers/ICAPS/2005/ICAPS05-025.pdf) (ICAPS'05)
- [ ] [Learning Planning Rules in Noisy Stochastic Worlds](https://people.csail.mit.edu/lpk/papers/2005/zpk-aaai05.pdf) (AAAI'05)
- [ ] [Learning action models from plan examples using weighted MAX-SAT](https://www.sciencedirect.com/science/article/pii/S0004370206001408) (AIJ'07)
- [x] [Learning action models from plan examples using weighted MAX-SAT](https://www.sciencedirect.com/science/article/pii/S0004370206001408) (AIJ'07)
- [ ] [Learning Symbolic Models of Stochastic Domains](https://www.aaai.org/Papers/JAIR/Vol29/JAIR-2910.pdf) (JAIR'07)
- [x] [Learning Partially Observable Deterministic Action Models](https://www.aaai.org/Papers/JAIR/Vol33/JAIR-3310.pdf) (JAIR'08)
- [ ] [Acquisition of Object-Centred Domain Models from Planning Examples](https://ojs.aaai.org/index.php/ICAPS/article/view/13391) (ICAPS'09)
Expand All @@ -113,7 +69,7 @@ Model:
- [ ] [Learning STRIPS Action Models with Classical Planning](https://arxiv.org/abs/1903.01153) (ICAPS'18)
- [ ] [Learning Planning Operators from Episodic Traces](https://aaai.org/ocs/index.php/SSS/SSS18/paper/view/17594/15530) (AAAI-SS'18)
- [ ] [Learning action models with minimal observability](https://www.sciencedirect.com/science/article/abs/pii/S0004370218304259) (AIJ'19)
- [ ] [Learning Action Models from Disordered and Noisy Plan Traces](https://arxiv.org/abs/1908.09800) (arXiv'19)
- [x] [Learning Action Models from Disordered and Noisy Plan Traces](https://arxiv.org/abs/1908.09800) (arXiv'19)
- [ ] [Bridging the Gap: Providing Post-Hoc Symbolic Explanations for Sequential Decision-Making Problems with Black Box Simulators](https://arxiv.org/abs/2002.01080) (ICML-WS'20)
- [ ] [STRIPS Action Discovery](https://arxiv.org/abs/2001.11457) (arXiv'20)
- [ ] [Learning First-Order Symbolic Representations for Planning from the Structure of the State Space](https://arxiv.org/abs/1909.05546) (ECAI'20)
Expand Down
13 changes: 13 additions & 0 deletions docs/extract/amdn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Usage

```python
from macq import generate, extract

print(model.details())
```

**Output:**
```text
```

# API Documentation
77 changes: 77 additions & 0 deletions docs/extract/arms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Usage

```python
from macq import generate, extract
from macq.trace import PlanningObject, Fluent, TraceList
from macq.observation import PartialObservation

def get_fluent(name: str, objs: list[str]):
objects = [PlanningObject(o.split()[0], o.split()[1]) for o in objs]
return Fluent(name, objects)

traces = TraceList()
generator = generate.pddl.TraceFromGoal(problem_id=1801)

generator.change_goal(
{
get_fluent("communicated_soil_data", ["waypoint waypoint2"]),
get_fluent("communicated_rock_data", ["waypoint waypoint3"]),
get_fluent(
"communicated_image_data", ["objective objective1", "mode high_res"]
),
}
)
traces.append(generator.generate_trace())

generator.change_goal(
{
get_fluent("communicated_soil_data", ["waypoint waypoint2"]),
get_fluent("communicated_rock_data", ["waypoint waypoint3"]),
get_fluent(
"communicated_image_data", ["objective objective1", "mode high_res"]
),
}
)
traces.append(generator.generate_trace())

observations = traces.tokenize(PartialObservation, percent_missing=0.60)
model = extract.Extract(
observations,
extract.modes.ARMS,
upper_bound=2,
min_support=2,
action_weight=110,
info_weight=100,
threshold=0.6,
info3_default=30,
plan_default=30,
)

print(model.details())
```

**Output:**
```text
Model:
Fluents: (at rover rover0 waypoint waypoint2), (have_soil_analysis rover rover0 waypoint waypoint2), (have_soil_analysis rover rover0 waypoint waypoint3), ...
Actions:
(communicate_image_data rover waypoint mode objective lander waypoint):
precond:
calibrated camera rover
have_rock_analysis rover waypoint
communicated_rock_data waypoint
channel_free lander
at_soil_sample waypoint
at_rock_sample waypoint
add:
calibrated camera rover
at rover waypoint
have_image rover objective mode
channel_free lander
communicated_image_data objective mode
delete:
calibrated camera rover
...
```

# API Documentation
9 changes: 9 additions & 0 deletions docs/extract/extract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Usage

## Debugging
Include the argument `debug=True` to `Extract` to enable debugging for any
extraction technique.

*Note: debugging output and interfaces are unique to each method.*

# API Documentation
37 changes: 37 additions & 0 deletions docs/extract/observer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Usage

```python
from macq import generate, extract
from macq.observation import IdentityObservation

traces = generate.pddl.VanillaSampling(problem_id=123, plan_len=20, num_traces=100).traces
observations = traces.tokenize(IdentityObservation)
model = extract.Extract(observations, extract.modes.OBSERVER)

print(model.details())
```

**Output:**
```text
Model:
Fluents: at stone stone-03 location pos-04-06, at stone stone-01 location pos-04-06, at stone stone-02 location pos-05-06, at stone stone-06 location pos-07-04, at stone stone-11 ...
Actions:
push-to-goal stone stone-04 location pos-04-05 location pos-04-06 direction dir-up location pos-04-04 player player-01:
precond:
at player player-01 location pos-04-06
at stone stone-04 location pos-04-05
clear location pos-05-06
...
add:
at stone stone-04 location pos-04-04
clear location pos-04-06
at-goal stone stone-04
at player player-01 location pos-04-05
delete:
at stone stone-04 location pos-04-05
clear location pos-04-04
at player player-01 location pos-04-06
...
```

# API Documentation
28 changes: 28 additions & 0 deletions docs/extract/slaf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Usage

```python
from macq import generate, extract
from macq.observation import AtomicPartialObservation

traces = generate.pddl.VanillaSampling(problem_id=123, plan_len=2, num_traces=1).traces
observations = traces.tokenize(AtomicPartialObservation, percent_missing=0.10)
model = Extract(observations, extract.modes.SLAF)
print(model.details())
```

**Output:**
```text
Model:
Fluents: clear location pos-06-09, clear location pos-02-05, clear location pos-08-08, clear location pos-10-05, ...
Actions:
move player player-01 direction dir-left location pos-05-02 location pos-06-02:
precond:
add:
delete:
(clear location pos-05-02)
(at player player-01 location pos-06-02)
...
...
```

# API Documentation
17 changes: 17 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Usage Documentation

## Trace Generation
- [VanillaSampling](extract/observer/#usage)

## Tokenization
- [IdentityObservation](extract/observer#usage)
- [AtomicPartialObservation](extract/slaf#usage)

## Extraction Techniques
- [Observer](extract/observer#usage)
- [SLAF](extract/slaf#usage)
- [ARMS](extract/arms#usage)
- [AMDN](extract/amdn#usage)


# API Documentation
3 changes: 3 additions & 0 deletions macq/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
.. include:: ../docs/index.md
"""
13 changes: 7 additions & 6 deletions macq/extract/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from .model import Model
from .extract import Extract, modes, IncompatibleObservationToken, SLAF
from .learned_fluent import LearnedFluent
from .learned_action import LearnedAction
from .model import Model, LearnedAction
from .extract import Extract, modes
from .exceptions import IncompatibleObservationToken
from .model import Model

__all__ = [
"LearnedAction",
"LearnedFluent",
"Model",
"Extract",
"modes",
"IncompatibleObservationToken",
"LearnedAction",
"SLAF",
"LearnedFluent",
]
]
Loading

0 comments on commit 9ecd31f

Please sign in to comment.