Skip to content
This repository was archived by the owner on Feb 17, 2024. It is now read-only.

Commit 4b7c87f

Browse files
Add documentation to readme
1 parent 3f435bc commit 4b7c87f

File tree

1 file changed

+241
-5
lines changed

1 file changed

+241
-5
lines changed

README.md

Lines changed: 241 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,250 @@
1-
# opsearch
1+
# Operator Search
22

3-
A Clojure library designed to ... well, that part is up to you.
3+
Provides a simple, partially optimised implementation of a breadth-first search mechanism for applying simple
4+
STRIPS-style operators. For a more efficient engine, check out [the planner](https://github.com/cognesence/planner).
45

5-
## Usage
6+
## Contents
67

7-
FIXME
8+
+ [Installation](#installation)
9+
+ [Overview](#overview)
10+
+ [Operators](#operators)
11+
+ [Examples](#examples)
12+
- [Without a World](#without-a-world)
13+
- [Using a World](#using-a-world)
14+
- [Using Compound Goals](#using-compound-goals)
815

16+
## Installation
17+
18+
This library is hosted on clojars. Get it by adding `org.clojars.cognesence/opsearch` to your dependencies in your
19+
Leiningen `project.clj` file.
20+
21+
```
22+
(defproject com.example/myproject "1.0.0"
23+
:description "My Leiningen project!"
24+
:url "http://example.com/projects/myproject"
25+
:license {:name "Eclipse Public License"
26+
:url "http://www.eclipse.org/legal/epl-v10.html"}
27+
:dependencies [[org.clojure/clojure "1.8.0"]
28+
[org.clojars.cognesence/opsearch "1.0.1"]])
29+
30+
```
31+
32+
## Overview
33+
34+
The `ops-search` method takes the following arguments:
35+
36+
+ `start` - a start state
37+
+ `goal` - a minimally specified goal state (see below)
38+
+ `operators` - a collection of operators
39+
+ `:world` - a definition of unchanging world states
40+
41+
A map is returned showing:
42+
43+
+ the goal state it reached
44+
+ the path it took
45+
+ any commands to send to another subsystem
46+
+ a textual description of the path
47+
48+
**Note:** it is possible to use ops-search without the pattern matcher but its use is then highly restricted. For this
49+
guide we assume the pattern matcher will be used.
50+
51+
Goals are minimally specified so any state which is a superset of the goal is deemed a goal state.
52+
53+
## Operators
54+
55+
Operators for this search are specified in a map which should associate the operator name with its definition. Operator
56+
definitions describe preconditions and effects. Effects are specified in terms of deletions and additions. The
57+
operators used in the examples below are based on a tuple representation.
58+
59+
For example, a move-agent operator could be written as:
60+
61+
```clojure
62+
move {:pre ((agent ?agent)
63+
(at ?agent ?p1)
64+
(connects ?p1 ?p2)
65+
)
66+
:add ((at ?agent ?p2))
67+
:del ((at ?agent ?p1))
68+
```
69+
70+
Given a state description like:
71+
72+
```clojure
73+
'#{(at Ralf table)
74+
(connects table bench)
75+
(agent Ralf)
76+
})
77+
```
78+
79+
The move operator could produce a successor state:
80+
81+
```clojure
82+
'#{(at Ralf bench)
83+
(connects table bench)
84+
(agent Ralf)
85+
})
86+
```
87+
88+
By deleting `(at Ralf table)` and adding `(at Ralf bench)`.
89+
90+
Operators may (optionally) also specify:
91+
92+
+ `:txt` - a textual description of the operator application to aid readibility
93+
+ `:cmd` - an encoded command for the operator, typically for the benefit of some other subsystem.
94+
95+
A more complete (but still slightly toy) set of operators could be:
96+
97+
```clojure
98+
(def ops
99+
'{pickup {:pre ( (agent ?agent)
100+
(manipulable ?obj)
101+
(at ?agent ?place)
102+
(on ?obj ?place)
103+
(holds ?agent nil)
104+
)
105+
:add ((holds ?agent ?obj))
106+
:del ((on ?obj ?place)
107+
(holds ?agent nil))
108+
:txt (pickup ?obj from ?place)
109+
:cmd [grasp ?obj]
110+
}
111+
drop {:pre ( (at ?agent ?place)
112+
(holds ?agent ?obj)
113+
(:guard (? obj))
114+
)
115+
:add ( (holds ?agent nil)
116+
(on ?obj ?place))
117+
:del ((holds ?agent ?obj))
118+
:txt (drop ?obj at ?place)
119+
:cmd [drop ?obj]
120+
}
121+
move {:pre ( (agent ?agent)
122+
(at ?agent ?p1)
123+
(connects ?p1 ?p2)
124+
)
125+
:add ((at ?agent ?p2))
126+
:del ((at ?agent ?p1))
127+
:txt (move ?p1 to ?p2)
128+
:cmd [move ?p2]
129+
}
130+
})
131+
```
132+
133+
## Examples
134+
135+
### Without a World
136+
137+
All following examples use the pickup, drop and move operators defined above:
138+
139+
```clojure
140+
(def state1
141+
'#{(at R table)
142+
(on book table)
143+
(on spud table)
144+
(holds R nil)
145+
(connects table bench)
146+
(manipulable book)
147+
(manipulable spud)
148+
(agent R)
149+
})
150+
```
151+
152+
Note (as stated above) goals are minimally specified so any state which is a superset of the goal is deemed a goal
153+
state.
154+
155+
```clojure
156+
; user=> (ops-search state1 '((on book bench)) ops)
157+
{:state #{(agent R) (manipulable book) (on spud table)
158+
(on book bench) (holds R nil) (at R bench)
159+
(manipulable spud) (connects table bench)},
160+
:path (#{(agent R) (manipulable book) (on spud table)
161+
(holds R nil) (manipulable spud) (connects table bench)
162+
(on book table) (at R table)}
163+
#{(agent R) (holds R book) (manipulable book)
164+
(on spud table) (manipulable spud)
165+
(connects table bench) (at R table)}
166+
#{(agent R) (holds R book) (manipulable book)
167+
(on spud table) (at R bench)
168+
(manipulable spud) (connects table bench)}),
169+
:cmds ([grasp book] [move bench] [drop book]),
170+
:txt ((pickup book from table) (move table to bench) (drop book at bench))}
171+
```
172+
173+
### Using a World
174+
175+
`:world` definitions contain unchanging state relations. Separating static/world relations from those that may change
176+
improves the efficiency of the search.
177+
178+
```clojure
179+
(def world
180+
'#{(connects table bench)
181+
(manipulable book)
182+
(manipulable spud)
183+
(agent R)
184+
})
185+
186+
(def state2
187+
'#{(at R table)
188+
(on book table)
189+
(on spud table)
190+
(holds R nil)
191+
})
192+
193+
; user=> (ops-search state2 '((on book bench)) ops :world world)
194+
{:state #{(on spud table) (on book bench) (holds R nil) (at R bench)},
195+
:path (#{(on spud table) (holds R nil) (on book table) (at R table)}
196+
#{(holds R book) (on spud table) (at R table)}
197+
#{(holds R book) (on spud table) (at R bench)}),
198+
:cmds ([grasp book] [move bench] [drop book]),
199+
:txt ((pickup book from table) (move table to bench) (drop book at bench))}
200+
```
201+
202+
### Using Compound Goals
203+
204+
```clojure
205+
(def world2
206+
'#{(connects table bench)
207+
(connects bench table)
208+
(connects bench sink)
209+
(connects sink bench)
210+
(manipulable book)
211+
(manipulable spud)
212+
(agent R)
213+
})
214+
215+
(def state3
216+
'#{(at R table)
217+
(on book table)
218+
(on spud table)
219+
(holds R nil)
220+
})
221+
222+
; user=> (ops-search state3 '((on book bench)(on spud sink)) ops :world world2)
223+
{:state #{(at R sink) (on book bench) (holds R nil) (on spud sink)},
224+
:path (#{(on spud table) (holds R nil) (on book table) (at R table)}
225+
#{(holds R book) (on spud table) (at R table)}
226+
#{(holds R book) (on spud table) (at R bench)}
227+
#{(on spud table) (on book bench) (holds R nil) (at R bench)}
228+
#{(on spud table) (on book bench) (holds R nil) (at R table)}
229+
#{(on book bench) (holds R spud) (at R table)}
230+
#{(on book bench) (at R bench) (holds R spud)}
231+
#{(at R sink) (on book bench) (holds R spud)}),
232+
:cmds ([grasp book] [move bench] [drop book]
233+
[move table] [grasp spud] [move bench] [move sink] [drop spud]),
234+
:txt ((pickup book from table) (move table to bench) (drop book at bench)
235+
(move bench to table) (pickup spud from table) (move table to bench)
236+
(move bench to sink) (drop spud at sink))}
237+
```
238+
239+
Note that goals can be specified as matcher patterns so the following is also a valid call:
240+
241+
```clojure
242+
(ops-search state3 '((on ?x bench)(on ?y sink)) ops :world world2)
243+
```
244+
9245
## License
10246

11-
Copyright © 2017 FIXME
247+
Copyright © 2017 Simon Lynch
12248

13249
Distributed under the Eclipse Public License either version 1.0 or (at
14250
your option) any later version.

0 commit comments

Comments
 (0)