drt.doctest 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. .. Copyright (C) 2001-2019 NLTK Project
  2. .. For license information, see LICENSE.TXT
  3. ================================
  4. Discourse Representation Theory
  5. ================================
  6. >>> from nltk.sem import logic
  7. >>> from nltk.inference import TableauProver
  8. Overview
  9. ========
  10. A DRS can be created with the ``DRS()`` constructor. This takes two arguments: a list of
  11. discourse referents and list of conditions. .
  12. >>> from nltk.sem.drt import *
  13. >>> dexpr = DrtExpression.fromstring
  14. >>> man_x = dexpr('man(x)')
  15. >>> walk_x = dexpr('walk(x)')
  16. >>> x = dexpr('x')
  17. >>> print(DRS([x], [man_x, walk_x]))
  18. ([x],[man(x), walk(x)])
  19. The ``parse()`` method can also be applied directly to DRS
  20. expressions, which allows them to be specified more
  21. easily.
  22. >>> drs1 = dexpr('([x],[man(x),walk(x)])')
  23. >>> print(drs1)
  24. ([x],[man(x), walk(x)])
  25. DRSs can be *merged* using the ``+`` operator.
  26. >>> drs2 = dexpr('([y],[woman(y),stop(y)])')
  27. >>> drs3 = drs1 + drs2
  28. >>> print(drs3)
  29. (([x],[man(x), walk(x)]) + ([y],[woman(y), stop(y)]))
  30. >>> print(drs3.simplify())
  31. ([x,y],[man(x), walk(x), woman(y), stop(y)])
  32. We can embed DRSs as components of an ``implies`` condition.
  33. >>> s = '([], [(%s -> %s)])' % (drs1, drs2)
  34. >>> print(dexpr(s))
  35. ([],[(([x],[man(x), walk(x)]) -> ([y],[woman(y), stop(y)]))])
  36. The ``fol()`` method converts DRSs into FOL formulae.
  37. >>> print(dexpr(r'([x],[man(x), walks(x)])').fol())
  38. exists x.(man(x) & walks(x))
  39. >>> print(dexpr(r'([],[(([x],[man(x)]) -> ([],[walks(x)]))])').fol())
  40. all x.(man(x) -> walks(x))
  41. In order to visualize a DRS, the ``pretty_format()`` method can be used.
  42. >>> print(drs3.pretty_format())
  43. _________ __________
  44. | x | | y |
  45. (|---------| + |----------|)
  46. | man(x) | | woman(y) |
  47. | walk(x) | | stop(y) |
  48. |_________| |__________|
  49. Parse to semantics
  50. ------------------
  51. ..
  52. >>> logic._counter._value = 0
  53. DRSs can be used for building compositional semantics in a feature
  54. based grammar. To specify that we want to use DRSs, the appropriate
  55. logic parser needs be passed as a parameter to ``load_earley()``
  56. >>> from nltk.parse import load_parser
  57. >>> from nltk.sem.drt import DrtParser
  58. >>> parser = load_parser('grammars/book_grammars/drt.fcfg', trace=0, logic_parser=DrtParser())
  59. >>> for tree in parser.parse('a dog barks'.split()):
  60. ... print(tree.label()['SEM'].simplify())
  61. ...
  62. ([x],[dog(x), bark(x)])
  63. Alternatively, a ``FeatStructReader`` can be passed with the ``logic_parser`` set on it
  64. >>> from nltk.featstruct import FeatStructReader
  65. >>> from nltk.grammar import FeatStructNonterminal
  66. >>> parser = load_parser('grammars/book_grammars/drt.fcfg', trace=0, fstruct_reader=FeatStructReader(fdict_class=FeatStructNonterminal, logic_parser=DrtParser()))
  67. >>> for tree in parser.parse('every girl chases a dog'.split()):
  68. ... print(tree.label()['SEM'].simplify().normalize())
  69. ...
  70. ([],[(([z1],[girl(z1)]) -> ([z2],[dog(z2), chase(z1,z2)]))])
  71. Unit Tests
  72. ==========
  73. Parser
  74. ------
  75. >>> print(dexpr(r'([x,y],[sees(x,y)])'))
  76. ([x,y],[sees(x,y)])
  77. >>> print(dexpr(r'([x],[man(x), walks(x)])'))
  78. ([x],[man(x), walks(x)])
  79. >>> print(dexpr(r'\x.([],[man(x), walks(x)])'))
  80. \x.([],[man(x), walks(x)])
  81. >>> print(dexpr(r'\x.\y.([],[sees(x,y)])'))
  82. \x y.([],[sees(x,y)])
  83. >>> print(dexpr(r'([x,y],[(x = y)])'))
  84. ([x,y],[(x = y)])
  85. >>> print(dexpr(r'([x,y],[(x != y)])'))
  86. ([x,y],[-(x = y)])
  87. >>> print(dexpr(r'\x.([],[walks(x)])(john)'))
  88. (\x.([],[walks(x)]))(john)
  89. >>> print(dexpr(r'\R.\x.([],[big(x,R)])(\y.([],[mouse(y)]))'))
  90. (\R x.([],[big(x,R)]))(\y.([],[mouse(y)]))
  91. >>> print(dexpr(r'(([x],[walks(x)]) + ([y],[runs(y)]))'))
  92. (([x],[walks(x)]) + ([y],[runs(y)]))
  93. >>> print(dexpr(r'(([x,y],[walks(x), jumps(y)]) + (([z],[twos(z)]) + ([w],[runs(w)])))'))
  94. (([x,y],[walks(x), jumps(y)]) + ([z],[twos(z)]) + ([w],[runs(w)]))
  95. >>> print(dexpr(r'((([],[walks(x)]) + ([],[twos(x)])) + ([],[runs(x)]))'))
  96. (([],[walks(x)]) + ([],[twos(x)]) + ([],[runs(x)]))
  97. >>> print(dexpr(r'((([],[walks(x)]) + ([],[runs(x)])) + (([],[threes(x)]) + ([],[fours(x)])))'))
  98. (([],[walks(x)]) + ([],[runs(x)]) + ([],[threes(x)]) + ([],[fours(x)]))
  99. >>> print(dexpr(r'(([],[walks(x)]) -> ([],[runs(x)]))'))
  100. (([],[walks(x)]) -> ([],[runs(x)]))
  101. >>> print(dexpr(r'([x],[PRO(x), sees(John,x)])'))
  102. ([x],[PRO(x), sees(John,x)])
  103. >>> print(dexpr(r'([x],[man(x), -([],[walks(x)])])'))
  104. ([x],[man(x), -([],[walks(x)])])
  105. >>> print(dexpr(r'([],[(([x],[man(x)]) -> ([],[walks(x)]))])'))
  106. ([],[(([x],[man(x)]) -> ([],[walks(x)]))])
  107. >>> print(dexpr(r'DRS([x],[walk(x)])'))
  108. ([x],[walk(x)])
  109. >>> print(dexpr(r'DRS([x][walk(x)])'))
  110. ([x],[walk(x)])
  111. >>> print(dexpr(r'([x][walk(x)])'))
  112. ([x],[walk(x)])
  113. ``simplify()``
  114. --------------
  115. >>> print(dexpr(r'\x.([],[man(x), walks(x)])(john)').simplify())
  116. ([],[man(john), walks(john)])
  117. >>> print(dexpr(r'\x.\y.([z],[dog(z),sees(x,y)])(john)(mary)').simplify())
  118. ([z],[dog(z), sees(john,mary)])
  119. >>> print(dexpr(r'\R x.([],[big(x,R)])(\y.([],[mouse(y)]))').simplify())
  120. \x.([],[big(x,\y.([],[mouse(y)]))])
  121. >>> print(dexpr(r'(([x],[walks(x)]) + ([y],[runs(y)]))').simplify())
  122. ([x,y],[walks(x), runs(y)])
  123. >>> print(dexpr(r'(([x,y],[walks(x), jumps(y)]) + (([z],[twos(z)]) + ([w],[runs(w)])))').simplify())
  124. ([w,x,y,z],[walks(x), jumps(y), twos(z), runs(w)])
  125. >>> print(dexpr(r'((([],[walks(x)]) + ([],[runs(x)]) + ([],[threes(x)]) + ([],[fours(x)])))').simplify())
  126. ([],[walks(x), runs(x), threes(x), fours(x)])
  127. >>> dexpr(r'([x],[man(x)])+([x],[walks(x)])').simplify() == \
  128. ... dexpr(r'([x,z1],[man(x), walks(z1)])')
  129. True
  130. >>> dexpr(r'([y],[boy(y), (([x],[dog(x)]) -> ([],[chase(x,y)]))])+([x],[run(x)])').simplify() == \
  131. ... dexpr(r'([y,z1],[boy(y), (([x],[dog(x)]) -> ([],[chase(x,y)])), run(z1)])')
  132. True
  133. >>> dexpr(r'\Q.(([x],[john(x),walks(x)]) + Q)(([x],[PRO(x),leaves(x)]))').simplify() == \
  134. ... dexpr(r'([x,z1],[john(x), walks(x), PRO(z1), leaves(z1)])')
  135. True
  136. >>> logic._counter._value = 0
  137. >>> print(dexpr('([],[(([x],[dog(x)]) -> ([e,y],[boy(y), chase(e), subj(e,x), obj(e,y)]))])+([e,x],[PRO(x), run(e), subj(e,x)])').simplify().normalize().normalize())
  138. ([e02,z5],[(([z3],[dog(z3)]) -> ([e01,z4],[boy(z4), chase(e01), subj(e01,z3), obj(e01,z4)])), PRO(z5), run(e02), subj(e02,z5)])
  139. ``fol()``
  140. -----------
  141. >>> print(dexpr(r'([x,y],[sees(x,y)])').fol())
  142. exists x y.sees(x,y)
  143. >>> print(dexpr(r'([x],[man(x), walks(x)])').fol())
  144. exists x.(man(x) & walks(x))
  145. >>> print(dexpr(r'\x.([],[man(x), walks(x)])').fol())
  146. \x.(man(x) & walks(x))
  147. >>> print(dexpr(r'\x y.([],[sees(x,y)])').fol())
  148. \x y.sees(x,y)
  149. >>> print(dexpr(r'\x.([],[walks(x)])(john)').fol())
  150. \x.walks(x)(john)
  151. >>> print(dexpr(r'\R x.([],[big(x,R)])(\y.([],[mouse(y)]))').fol())
  152. (\R x.big(x,R))(\y.mouse(y))
  153. >>> print(dexpr(r'(([x],[walks(x)]) + ([y],[runs(y)]))').fol())
  154. (exists x.walks(x) & exists y.runs(y))
  155. >>> print(dexpr(r'(([],[walks(x)]) -> ([],[runs(x)]))').fol())
  156. (walks(x) -> runs(x))
  157. >>> print(dexpr(r'([x],[PRO(x), sees(John,x)])').fol())
  158. exists x.(PRO(x) & sees(John,x))
  159. >>> print(dexpr(r'([x],[man(x), -([],[walks(x)])])').fol())
  160. exists x.(man(x) & -walks(x))
  161. >>> print(dexpr(r'([],[(([x],[man(x)]) -> ([],[walks(x)]))])').fol())
  162. all x.(man(x) -> walks(x))
  163. >>> print(dexpr(r'([x],[man(x) | walks(x)])').fol())
  164. exists x.(man(x) | walks(x))
  165. >>> print(dexpr(r'P(x) + ([x],[walks(x)])').fol())
  166. (P(x) & exists x.walks(x))
  167. ``resolve_anaphora()``
  168. ----------------------
  169. >>> from nltk.sem.drt import AnaphoraResolutionException
  170. >>> print(resolve_anaphora(dexpr(r'([x,y,z],[dog(x), cat(y), walks(z), PRO(z)])')))
  171. ([x,y,z],[dog(x), cat(y), walks(z), (z = [x,y])])
  172. >>> print(resolve_anaphora(dexpr(r'([],[(([x],[dog(x)]) -> ([y],[walks(y), PRO(y)]))])')))
  173. ([],[(([x],[dog(x)]) -> ([y],[walks(y), (y = x)]))])
  174. >>> print(resolve_anaphora(dexpr(r'(([x,y],[]) + ([],[PRO(x)]))')).simplify())
  175. ([x,y],[(x = y)])
  176. >>> try: print(resolve_anaphora(dexpr(r'([x],[walks(x), PRO(x)])')))
  177. ... except AnaphoraResolutionException as e: print(e)
  178. Variable 'x' does not resolve to anything.
  179. >>> print(resolve_anaphora(dexpr('([e01,z6,z7],[boy(z6), PRO(z7), run(e01), subj(e01,z7)])')))
  180. ([e01,z6,z7],[boy(z6), (z7 = z6), run(e01), subj(e01,z7)])
  181. ``equiv()``:
  182. ----------------
  183. >>> a = dexpr(r'([x],[man(x), walks(x)])')
  184. >>> b = dexpr(r'([x],[walks(x), man(x)])')
  185. >>> print(a.equiv(b, TableauProver()))
  186. True
  187. ``replace()``:
  188. --------------
  189. >>> a = dexpr(r'a')
  190. >>> w = dexpr(r'w')
  191. >>> x = dexpr(r'x')
  192. >>> y = dexpr(r'y')
  193. >>> z = dexpr(r'z')
  194. replace bound
  195. -------------
  196. >>> print(dexpr(r'([x],[give(x,y,z)])').replace(x.variable, a, False))
  197. ([x],[give(x,y,z)])
  198. >>> print(dexpr(r'([x],[give(x,y,z)])').replace(x.variable, a, True))
  199. ([a],[give(a,y,z)])
  200. replace unbound
  201. ---------------
  202. >>> print(dexpr(r'([x],[give(x,y,z)])').replace(y.variable, a, False))
  203. ([x],[give(x,a,z)])
  204. >>> print(dexpr(r'([x],[give(x,y,z)])').replace(y.variable, a, True))
  205. ([x],[give(x,a,z)])
  206. replace unbound with bound
  207. --------------------------
  208. >>> dexpr(r'([x],[give(x,y,z)])').replace(y.variable, x, False) == \
  209. ... dexpr('([z1],[give(z1,x,z)])')
  210. True
  211. >>> dexpr(r'([x],[give(x,y,z)])').replace(y.variable, x, True) == \
  212. ... dexpr('([z1],[give(z1,x,z)])')
  213. True
  214. replace unbound with unbound
  215. ----------------------------
  216. >>> print(dexpr(r'([x],[give(x,y,z)])').replace(y.variable, z, False))
  217. ([x],[give(x,z,z)])
  218. >>> print(dexpr(r'([x],[give(x,y,z)])').replace(y.variable, z, True))
  219. ([x],[give(x,z,z)])
  220. replace unbound
  221. ---------------
  222. >>> print(dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,z)])').replace(z.variable, a, False))
  223. (([x],[P(x,y,a)]) + ([y],[Q(x,y,a)]))
  224. >>> print(dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,z)])').replace(z.variable, a, True))
  225. (([x],[P(x,y,a)]) + ([y],[Q(x,y,a)]))
  226. replace bound
  227. -------------
  228. >>> print(dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,z)])').replace(x.variable, a, False))
  229. (([x],[P(x,y,z)]) + ([y],[Q(x,y,z)]))
  230. >>> print(dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,z)])').replace(x.variable, a, True))
  231. (([a],[P(a,y,z)]) + ([y],[Q(a,y,z)]))
  232. replace unbound with unbound
  233. ----------------------------
  234. >>> print(dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,z)])').replace(z.variable, a, False))
  235. (([x],[P(x,y,a)]) + ([y],[Q(x,y,a)]))
  236. >>> print(dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,z)])').replace(z.variable, a, True))
  237. (([x],[P(x,y,a)]) + ([y],[Q(x,y,a)]))
  238. replace unbound with bound on same side
  239. ---------------------------------------
  240. >>> dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,w)])').replace(z.variable, x, False) == \
  241. ... dexpr(r'(([z1],[P(z1,y,x)]) + ([y],[Q(z1,y,w)]))')
  242. True
  243. >>> dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,w)])').replace(z.variable, x, True) == \
  244. ... dexpr(r'(([z1],[P(z1,y,x)]) + ([y],[Q(z1,y,w)]))')
  245. True
  246. replace unbound with bound on other side
  247. ----------------------------------------
  248. >>> dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,w)])').replace(w.variable, x, False) == \
  249. ... dexpr(r'(([z1],[P(z1,y,z)]) + ([y],[Q(z1,y,x)]))')
  250. True
  251. >>> dexpr(r'([x],[P(x,y,z)])+([y],[Q(x,y,w)])').replace(w.variable, x, True) == \
  252. ... dexpr(r'(([z1],[P(z1,y,z)]) + ([y],[Q(z1,y,x)]))')
  253. True
  254. replace unbound with double bound
  255. ---------------------------------
  256. >>> dexpr(r'([x],[P(x,y,z)])+([x],[Q(x,y,w)])').replace(z.variable, x, False) == \
  257. ... dexpr(r'(([z1],[P(z1,y,x)]) + ([z1],[Q(z1,y,w)]))')
  258. True
  259. >>> dexpr(r'([x],[P(x,y,z)])+([x],[Q(x,y,w)])').replace(z.variable, x, True) == \
  260. ... dexpr(r'(([z1],[P(z1,y,x)]) + ([z1],[Q(z1,y,w)]))')
  261. True
  262. regression tests
  263. ----------------
  264. >>> d = dexpr('([x],[A(c), ([y],[B(x,y,z,a)])->([z],[C(x,y,z,a)])])')
  265. >>> print(d)
  266. ([x],[A(c), (([y],[B(x,y,z,a)]) -> ([z],[C(x,y,z,a)]))])
  267. >>> print(d.pretty_format())
  268. ____________________________________
  269. | x |
  270. |------------------------------------|
  271. | A(c) |
  272. | ____________ ____________ |
  273. | | y | | z | |
  274. | (|------------| -> |------------|) |
  275. | | B(x,y,z,a) | | C(x,y,z,a) | |
  276. | |____________| |____________| |
  277. |____________________________________|
  278. >>> print(str(d))
  279. ([x],[A(c), (([y],[B(x,y,z,a)]) -> ([z],[C(x,y,z,a)]))])
  280. >>> print(d.fol())
  281. exists x.(A(c) & all y.(B(x,y,z,a) -> exists z.C(x,y,z,a)))
  282. >>> print(d.replace(Variable('a'), DrtVariableExpression(Variable('r'))))
  283. ([x],[A(c), (([y],[B(x,y,z,r)]) -> ([z],[C(x,y,z,r)]))])
  284. >>> print(d.replace(Variable('x'), DrtVariableExpression(Variable('r'))))
  285. ([x],[A(c), (([y],[B(x,y,z,a)]) -> ([z],[C(x,y,z,a)]))])
  286. >>> print(d.replace(Variable('y'), DrtVariableExpression(Variable('r'))))
  287. ([x],[A(c), (([y],[B(x,y,z,a)]) -> ([z],[C(x,y,z,a)]))])
  288. >>> print(d.replace(Variable('z'), DrtVariableExpression(Variable('r'))))
  289. ([x],[A(c), (([y],[B(x,y,r,a)]) -> ([z],[C(x,y,z,a)]))])
  290. >>> print(d.replace(Variable('x'), DrtVariableExpression(Variable('r')), True))
  291. ([r],[A(c), (([y],[B(r,y,z,a)]) -> ([z],[C(r,y,z,a)]))])
  292. >>> print(d.replace(Variable('y'), DrtVariableExpression(Variable('r')), True))
  293. ([x],[A(c), (([r],[B(x,r,z,a)]) -> ([z],[C(x,r,z,a)]))])
  294. >>> print(d.replace(Variable('z'), DrtVariableExpression(Variable('r')), True))
  295. ([x],[A(c), (([y],[B(x,y,r,a)]) -> ([r],[C(x,y,r,a)]))])
  296. >>> print(d == dexpr('([l],[A(c), ([m],[B(l,m,z,a)])->([n],[C(l,m,n,a)])])'))
  297. True
  298. >>> d = dexpr('([],[([x,y],[B(x,y,h), ([a,b],[dee(x,a,g)])])->([z,w],[cee(x,y,f), ([c,d],[E(x,c,d,e)])])])')
  299. >>> sorted(d.free())
  300. [Variable('B'), Variable('E'), Variable('e'), Variable('f'), Variable('g'), Variable('h')]
  301. >>> sorted(d.variables())
  302. [Variable('B'), Variable('E'), Variable('e'), Variable('f'), Variable('g'), Variable('h')]
  303. >>> sorted(d.get_refs(True))
  304. [Variable('a'), Variable('b'), Variable('c'), Variable('d'), Variable('w'), Variable('x'), Variable('y'), Variable('z')]
  305. >>> sorted(d.conds[0].get_refs(False))
  306. [Variable('x'), Variable('y')]
  307. >>> print(dexpr('([x,y],[A(x,y), (x=y), ([],[B(x,y)])->([],[C(x,y)]), ([x,y],[D(x,y)])->([],[E(x,y)]), ([],[F(x,y)])->([x,y],[G(x,y)])])').eliminate_equality())
  308. ([x],[A(x,x), (([],[B(x,x)]) -> ([],[C(x,x)])), (([x,y],[D(x,y)]) -> ([],[E(x,y)])), (([],[F(x,x)]) -> ([x,y],[G(x,y)]))])
  309. >>> print(dexpr('([x,y],[A(x,y), (x=y)]) -> ([],[B(x,y)])').eliminate_equality())
  310. (([x],[A(x,x)]) -> ([],[B(x,x)]))
  311. >>> print(dexpr('([x,y],[A(x,y)]) -> ([],[B(x,y), (x=y)])').eliminate_equality())
  312. (([x,y],[A(x,y)]) -> ([],[B(x,x)]))
  313. >>> print(dexpr('([x,y],[A(x,y), (x=y), ([],[B(x,y)])])').eliminate_equality())
  314. ([x],[A(x,x), ([],[B(x,x)])])
  315. >>> print(dexpr('([x,y],[A(x,y), ([],[B(x,y), (x=y)])])').eliminate_equality())
  316. ([x,y],[A(x,y), ([],[B(x,x)])])
  317. >>> print(dexpr('([z8 z9 z10],[A(z8), z8=z10, z9=z10, B(z9), C(z10), D(z10)])').eliminate_equality())
  318. ([z9],[A(z9), B(z9), C(z9), D(z9)])
  319. >>> print(dexpr('([x,y],[A(x,y), (x=y), ([],[B(x,y)]), ([x,y],[C(x,y)])])').eliminate_equality())
  320. ([x],[A(x,x), ([],[B(x,x)]), ([x,y],[C(x,y)])])
  321. >>> print(dexpr('([x,y],[A(x,y)]) + ([],[B(x,y), (x=y)]) + ([],[C(x,y)])').eliminate_equality())
  322. ([x],[A(x,x), B(x,x), C(x,x)])
  323. >>> print(dexpr('([x,y],[B(x,y)])+([x,y],[C(x,y)])').replace(Variable('y'), DrtVariableExpression(Variable('x'))))
  324. (([x,y],[B(x,y)]) + ([x,y],[C(x,y)]))
  325. >>> print(dexpr('(([x,y],[B(x,y)])+([],[C(x,y)]))+([],[D(x,y)])').replace(Variable('y'), DrtVariableExpression(Variable('x'))))
  326. (([x,y],[B(x,y)]) + ([],[C(x,y)]) + ([],[D(x,y)]))
  327. >>> print(dexpr('(([],[B(x,y)])+([],[C(x,y)]))+([],[D(x,y)])').replace(Variable('y'), DrtVariableExpression(Variable('x'))))
  328. (([],[B(x,x)]) + ([],[C(x,x)]) + ([],[D(x,x)]))
  329. >>> print(dexpr('(([],[B(x,y), ([x,y],[A(x,y)])])+([],[C(x,y)]))+([],[D(x,y)])').replace(Variable('y'), DrtVariableExpression(Variable('x'))).normalize())
  330. (([],[B(z3,z1), ([z2,z3],[A(z3,z2)])]) + ([],[C(z3,z1)]) + ([],[D(z3,z1)]))
  331. Parse errors
  332. ============
  333. >>> def parse_error(drtstring):
  334. ... try: dexpr(drtstring)
  335. ... except logic.LogicalExpressionException as e: print(e)
  336. >>> parse_error(r'')
  337. End of input found. Expression expected.
  338. <BLANKLINE>
  339. ^
  340. >>> parse_error(r'(')
  341. End of input found. Expression expected.
  342. (
  343. ^
  344. >>> parse_error(r'()')
  345. Unexpected token: ')'. Expression expected.
  346. ()
  347. ^
  348. >>> parse_error(r'([')
  349. End of input found. Expected token ']'.
  350. ([
  351. ^
  352. >>> parse_error(r'([,')
  353. ',' is an illegal variable name. Constants may not be quantified.
  354. ([,
  355. ^
  356. >>> parse_error(r'([x,')
  357. End of input found. Variable expected.
  358. ([x,
  359. ^
  360. >>> parse_error(r'([]')
  361. End of input found. Expected token '['.
  362. ([]
  363. ^
  364. >>> parse_error(r'([][')
  365. End of input found. Expected token ']'.
  366. ([][
  367. ^
  368. >>> parse_error(r'([][,')
  369. Unexpected token: ','. Expression expected.
  370. ([][,
  371. ^
  372. >>> parse_error(r'([][]')
  373. End of input found. Expected token ')'.
  374. ([][]
  375. ^
  376. >>> parse_error(r'([x][man(x)]) |')
  377. End of input found. Expression expected.
  378. ([x][man(x)]) |
  379. ^
  380. Pretty Printing
  381. ===============
  382. >>> dexpr(r"([],[])").pretty_print()
  383. __
  384. | |
  385. |--|
  386. |__|
  387. >>> dexpr(r"([],[([x],[big(x), dog(x)]) -> ([],[bark(x)]) -([x],[walk(x)])])").pretty_print()
  388. _____________________________
  389. | |
  390. |-----------------------------|
  391. | ________ _________ |
  392. | | x | | | |
  393. | (|--------| -> |---------|) |
  394. | | big(x) | | bark(x) | |
  395. | | dog(x) | |_________| |
  396. | |________| |
  397. | _________ |
  398. | | x | |
  399. | __ |---------| |
  400. | | | walk(x) | |
  401. | |_________| |
  402. |_____________________________|
  403. >>> dexpr(r"([x,y],[x=y]) + ([z],[dog(z), walk(z)])").pretty_print()
  404. _________ _________
  405. | x y | | z |
  406. (|---------| + |---------|)
  407. | (x = y) | | dog(z) |
  408. |_________| | walk(z) |
  409. |_________|
  410. >>> dexpr(r"([],[([x],[]) | ([y],[]) | ([z],[dog(z), walk(z)])])").pretty_print()
  411. _______________________________
  412. | |
  413. |-------------------------------|
  414. | ___ ___ _________ |
  415. | | x | | y | | z | |
  416. | (|---| | |---| | |---------|) |
  417. | |___| |___| | dog(z) | |
  418. | | walk(z) | |
  419. | |_________| |
  420. |_______________________________|
  421. >>> dexpr(r"\P.\Q.(([x],[]) + P(x) + Q(x))(\x.([],[dog(x)]))").pretty_print()
  422. ___ ________
  423. \ | x | \ | |
  424. /\ P Q.(|---| + P(x) + Q(x))( /\ x.|--------|)
  425. |___| | dog(x) |
  426. |________|