Created
September 8, 2019 09:43
-
-
Save davidar/4d2335f3764fe312500c97867e2be1c3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%import common.WS | |
%ignore WS | |
ADJ: "big" | "red" | "tall" | "narrow" | "mine" | "blue" | "green" | "large" | "small" | "short" | "little" | "wide" | |
DET: "that" | "any" | "an" | "a" | "the" | |
NOUN: "block" | "pyramid" | "box" | "that" | "cube" | "table" | "thing" | "colour" | "object" | "steeple" | "superblock" | |
PREP: "into" | "onto" | "in" | "on top of" | "on" | "behind" | |
PREPT: "before" | "while" | |
VERB: "pick up" | "pick" | "contain" | "support" | "own" | "touch" | |
DIR: "left" | "right" | |
?start: ["will you"] ["please"] command | |
| question | |
| statement | |
command: verb noun | |
| "put" noun prep noun -> put | |
| "stack up" ("two" | "both of") noun ["and" noun] -> stack | |
| "build" noun -> build | |
question: "find" noun | |
| "is" ["there"] noun [adj] | |
| "do I" verb noun | |
| "which" noun ("is" | "are" | "were" | "does") adj | |
| "does" noun pred | |
| q | |
q: "what" ("does" | "did") noun verb [time] -> flipjoin | |
| "how many" noun ("are" | "were") adj -> count | |
| "how many" noun "did you" verb [time] -> count2 | |
| ["what"] "is" noun verb "ed" ["by"] -> passive | |
| "what" noun "is" noun -> join | |
| ("had" | "have") "you" verb "ed" noun ["up"] time -> qwhen | |
statement: noun "is" adj | |
| "I" verb noun "but I do" ("not" | "n't") verb noun -> but | |
| "a \"" NOUN "\" is" noun -> define | |
| "call" noun "\"" NOUN "\"" | |
verb: VERB | |
noun: [det] adj* NOUN ["s"] | |
| "the one you are holding" -> holding | |
| "the one which I told you to" verb -> commanded | |
| ["at least"] "one of them" -> that | |
| [det] adj* NOUN ["s"] ["which" | "that"] ["is" | "are"] adj ["but is" adj] | |
| ["either"] noun "or" noun -> disj | |
| "the" adj ["-"] "est" noun [adj] -> most | |
| noun "'s support" -> support | |
| "it" -> it | |
| "a stack which contains two" noun "and" noun -> stack | |
det: DET | |
adj: ADJ | |
| ADJ ["-"] "er than" noun -> join | |
| ADJ ["-"] "er than every" noun -> each | |
| "not as" ADJ "as" noun -> flipjoin2 | |
| "not" adj -> neg | |
| ["sitting"] prep noun [time] -> joint | |
| noun verb ["s"] -> flipjoin | |
| pred | |
pred: verb ["s"] noun -> join | |
prep: PREP | |
| "to the" DIR "of" | |
time: PREPT event -> join | |
| "since we began" | |
event: "I told you to put" noun prep noun -> told_put | |
| "you were doing that" -> that | |
| "you started to clean" noun "off" -> cleanoff |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pick up a big red block | |
pickup(big red block)! | |
pick up that pyramid | |
pickup(that pyramid)! | |
find a block which is taller than the one you are holding | |
block tall.holding? | |
put that into the box | |
in(that, box)! | |
what does the box contain | |
contain'.box? | |
what is that pyramid supported by | |
support[that pyramid]? | |
how many blocks are not in the box | |
#count(block ~in.box)? | |
is at least one of them narrower than the one which I told you to pick up | |
that narrow.command$pickup? | |
is that supported | |
support.that? | |
stack up two pyramids | |
stack(pyramid, pyramid) | |
the blue pyramid is mine | |
mine(blue pyramid). | |
I own blocks which are not red but I don't own anything which supports a pyramid | |
own(block ~red ~thing support.pyramid) | |
do I own the box | |
own box? | |
do I own anything in the box | |
own thing in.box? | |
will you please stack up both of the red blocks and either a green cube or a pyramid | |
stack(red block, red block, green cube | pyramid) | |
which cube is sitting on the table | |
cube on.table? | |
is there a large block behind a pyramid | |
large block behind.pyramid? | |
put a small block onto the green cube which supports a pyramid | |
on(small block, green cube support.pyramid)! | |
put the smallest pyramid on top of the small block | |
above(#most(small,pyramid), small block)! | |
does the shortest thing the tallest pyramid's support supports support anything green | |
#most(short,thing support'.support.#most(tall,pyramid)) support[thing green]? | |
which green thing does the shortest thing the tallest pyramid's support supports support | |
green thing support'[#most(short,thing support'.support.#most(tall,pyramid))]? | |
what colour is that | |
colour.that? | |
how many things are on top of green cubes | |
#count(thing above[green cube])? | |
had you touched any pyramid before I told you to put the green pyramid on the little cube | |
touch.pyramid before[goal.on(green pyramid,little cube)]? | |
how many objects did you touch while you were doing that | |
#count(touch.object while.that)? | |
what did the red cube support before you started to clean the red cube off | |
support'[red cube,before[cleanoff[red cube]]]? | |
which blocks were to the left of the box before you started to clean the red cube off | |
block left[box; before[cleanoff[red cube]]]? | |
put the blue pyramid on the block in the box | |
{'on(blue pyramid, block in.box)!', 'in(blue pyramid on.block, box)!'} | |
is there anything which is big-er than every pyramid but is not as wide as the thing that supports it | |
thing #each(big,pyramid) wide'[thing support.#it]? | |
a "steeple" is a stack which contains two green cubes and a pyramid | |
steeple(stack(green cube, green cube, pyramid)). | |
build a steeple | |
steeple! | |
call the big-est block "superblock" | |
superblock(#most(big,block)). | |
have you picked superblock up since we began | |
pick.superblock? | |
is there anything to the right of the red pyramid | |
thing right[red pyramid]? | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import lark | |
parser = lark.Lark(open('english.ebnf', 'r'), ambiguity='explicit') | |
@lark.v_args(inline=True) | |
class Sem(lark.Transformer): | |
def conj(self, *args): | |
return ' '.join(arg for arg in args if arg) | |
def disj(self, *args): | |
return ' | '.join(args) | |
def join(self, rel, *args): | |
if len(args) == 1 and ' ' not in args[0]: | |
return f"{rel}.{args[0]}" | |
return f"{rel}[{','.join(args)}]" | |
def flip(self, verb): | |
return f"{verb}'" | |
def neg(self, adj): | |
return f"~{adj}" | |
def flipjoin(self, noun, verb, *args): | |
return self.join(self.flip(verb), noun, *args) | |
def flipjoin2(self, verb, noun, *args): | |
return self.join(self.flip(verb), noun, *args) | |
def joint(self, rel, noun, time=None): | |
if not time: return self.join(rel, noun) | |
return f"{rel}[{noun}; {time}]" | |
def _ambig(self, args): | |
args = set(args) | |
if len(args) > 1: return args | |
return args.pop() | |
def command(self, verb, noun): | |
return f"{verb}({noun})!" | |
def put(self, noun, prep, location): | |
return f"{prep}({noun}, {location})!" | |
def stack(self, n1, n2=None): | |
if n2: return f"stack({n1}, {n1}, {n2})" | |
else: return f"stack({n1}, {n1})" | |
def build(self, noun): | |
return f"{noun}!" | |
def question(self, *args): | |
return self.conj(*args) + '?' | |
def passive(self, noun, verb): | |
return self.join(verb, noun) | |
def count(self, *args): | |
return f"#count({self.conj(*args)})" | |
def count2(self, noun, verb, time): | |
return f"#count({self.conj(self.join(verb, noun), time)})" | |
def qwhen(self, verb, noun, time): | |
return self.conj(self.join(verb, noun), time) | |
def statement(self, noun, adj): | |
return f"{adj}({noun})." | |
def but(self, v1, n1, v2, n2): | |
if v1 == v2: | |
return v1 + '(' + self.conj(n1, self.neg(n2)) + ')' | |
def define(self, noun, adj): | |
return f"{noun}({adj})." | |
def verb(self, name): | |
return name.replace(' ','') | |
def noun(self, *args): | |
return self.conj(*args) | |
def holding(self): | |
return 'holding' | |
def commanded(self, verb): | |
return f"command${verb}" | |
def that(self): | |
return 'that' | |
def most(self, adj, *args): | |
return f"#most({adj},{self.conj(*args)})" | |
def support(self, noun): | |
return self.join('support', noun) | |
def it(self): | |
return '#it' | |
def det(self, name): | |
if name == 'that': return name | |
return '' | |
def adj(self, name): | |
return name | |
def each(self, adj, noun): | |
return f"#each({adj},{noun})" | |
def prep(self, name): | |
if name.endswith('to'): name = name[:-2] | |
if name == 'on top of': name = 'above' | |
return name | |
def time(self): | |
return '' | |
def told_put(self, n1, p, n2): | |
return f"goal.{p}({n1},{n2})" | |
def cleanoff(self, noun): | |
return self.join('cleanoff', noun) | |
def main(): | |
tests = [ | |
'pick up a big red block', | |
'pick up that pyramid', | |
'find a block which is taller than the one you are holding', | |
'put that into the box', | |
'what does the box contain', | |
'what is that pyramid supported by', | |
'how many blocks are not in the box', | |
'is at least one of them narrower than the one which I told you to pick up', | |
'is that supported', | |
'stack up two pyramids', | |
'the blue pyramid is mine', | |
'I own blocks which are not red but I don\'t own anything which supports a pyramid', | |
'do I own the box', | |
'do I own anything in the box', | |
'will you please stack up both of the red blocks and either a green cube or a pyramid', | |
'which cube is sitting on the table', | |
'is there a large block behind a pyramid', | |
'put a small block onto the green cube which supports a pyramid', | |
'put the smallest pyramid on top of the small block', | |
'does the shortest thing the tallest pyramid\'s support supports support anything green', | |
'which green thing does the shortest thing the tallest pyramid\'s support supports support', | |
'what colour is that', | |
'how many things are on top of green cubes', | |
'had you touched any pyramid before I told you to put the green pyramid on the little cube', | |
'how many objects did you touch while you were doing that', | |
'what did the red cube support before you started to clean the red cube off', | |
'which blocks were to the left of the box before you started to clean the red cube off', | |
'put the blue pyramid on the block in the box', | |
'is there anything which is big-er than every pyramid but is not as wide as the thing that supports it', | |
'a "steeple" is a stack which contains two green cubes and a pyramid', | |
'build a steeple', | |
'call the big-est block "superblock"', | |
'have you picked superblock up since we began', | |
'is there anything to the right of the red pyramid', | |
] | |
for test in tests: | |
print(test) | |
tree = parser.parse(test) | |
#print(tree.pretty()) | |
print(Sem().transform(tree)) | |
print() | |
if __name__ == '__main__': main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment