We load the Text-Fabric program and the BHSA data.
%load_ext autoreload
%autoreload 2
from tf.app import use
from util import getTfVerses, getShebanqData, compareResults, MQL_RESULTS
VERSION = "2017"
# A = use('bhsa', hoist=globals(), version=VERSION)
A = use("bhsa:clone", checkout="clone", hoist=globals(), version=VERSION)
Reinoud Oosting: verb שׂים ('to set/place') with double object
[clause FOCUS
[phrase function IN (PreO, PtcO)
[word sp = verb AND vs = qal AND lex = "FJM[" ]
]
..
[phrase function = Objc ]
]
OR
[clause FOCUS
[phrase function = Objc ]
..
[phrase function IN (PreO, PtcO)
[word sp = verb AND vs = qal AND lex = "FJM[" ]
]
]
OR
[clause FOCUS
[phrase typ = VP AND NOT function IN(PreO, PtcO)
[word sp = verb AND vs = qal AND lex = "FJM[" ]
]
..
[phrase function = Objc ]
..
[phrase function = Objc ]
]
OR
[clause FOCUS
[phrase function = Objc ]
..
[phrase typ = VP AND NOT function IN (PreO, PtcO)
[word sp = verb AND vs = qal AND lex = "FJM[" ]
]
..
[phrase function = Objc ]
]
OR
[clause FOCUS
[phrase function = Objc ]
..
[phrase function = Objc ]
..
[phrase typ = VP AND NOT function IN (PreO, PtcO)
[word sp = verb AND vs = qal AND lex = "FJM[" ]
]
]
(verses, words) = getShebanqData(A, MQL_RESULTS, 7)
62 results in 61 verses with 348 words
There is no OR
in TF-Query.
Instead, we run a separate query for each alternative and combine the results.
However, we can rewrite the first two alternatives into one query.
Note that they both specify a clause in which 2 phrases of a certain type occur.
The two alternatives specify the two different orders in which these phrases occur.
In TF-query there is no implicit order between the members of a template,
so we do not have to separate cases.
In MQL there is the UNORDERED GROUP
construction with the same effect, which Reinoud could have used.
The same holds for alternatives 3, 4, 5, which are merely order variants of 3 phrases within a clause.
In TF we have to stipulate that the two Objc
phrases are not the same one,
because in TF-Query it is not assumed that the different blocks should be matched by
different parts in the text.
We could do that by means of the inequality operator:
phrase function=Objc
# phrase function=Objc
but that will duplicate the results, because if phrase1, phrase2 is a result, then phrase2, phrase1 is also a result.
So it is better to stipulate that one of them comes before the other:
phrase function=Objc
< phrase function=Objc
query1 = """
clause
phrase function=PreO|PtcO
word sp=verb vs=qal lex=FJM[
phrase function=Objc
"""
query2 = """
clause
phrase typ=VP function#PreO|PtcO
word sp=verb vs=qal lex=FJM[
phrase function=Objc
< phrase function=Objc
"""
results1 = A.search(query1)
results2 = A.search(query2)
0.84s 21 results 1.31s 41 results
The number of results nicely add up to the expected 62.
(tfVerses1, tfWords1) = getTfVerses(A, results1, (0,))
(tfVerses2, tfWords2) = getTfVerses(A, results2, (0,))
21 verses 108 words 40 verses 240 words
We combine the verses and words and test for equality.
tfVerses = sorted(set(tfVerses1) | set(tfVerses2))
tfWords = sorted(set(tfWords1) | set(tfWords2))
compareResults(A, verses, words, tfVerses, tfWords)
VERSES EQUAL WORDS EQUAL
In order to show results in the natural order, we have to merge them.
results = sorted(results1 + results2)
Note that the results of the first query have one member less than the results of the second query.
Let's find the first result of the first query in the merged list.
for (i, r) in enumerate(results):
if len(r) == 4:
break
i + 1
1
A.show(results, end=3, condenseType="clause")
result 1
result 2
result 3