Entertaining prologue # 2
3r3406. 3r3-31.
Hi,
3r332 developer community. , 3r33333. 3r3406. It is necessary to finish the job. 3r33333. 3r3406. In the previous my opus there was a call to show how to use the Prologue language, and to show what fun it was. Turn this into an exercise. 3r33333. 3r3406. I'll try to continue
show off
to demonstrate. 3r33333. 3r3406. Briefly recall task: 3r3r94. 3r33395. 3r33333. 3r3406.
Wildcard Matching [/b]
For an 'implement implement implement implement implement implement and '
'. 3r33333. 3r3406. '?' Matches any single character. 3r33333. 3r3406. '
'Matches any sequence of characters (including the empty sequence). 3r33333. 3r3406. The matching input string (not partial). 3r33395. 3r3402. 3r3402. 3r33333. 3r3406.
Prove the completeness of the solution failed. On the site that provides the task there are 1808 tests that cannot be immediately seen, you need to write a program and get another test as an error. 3r33333. 3r3406. Hardcore I got 66 from him and checked my solution - while everything worked. But it can not be so simple. 3r33333. 3r3406. Why do so many tests, I want to check further 3r33333. 3r3406. I will try to rewrite this solution in the language
clear 3r348. available on this system (they reflect the popularity of modern programming languages). 3r33395. 3r33333. 3r3406.
So, choose Python. 3r33395.
3r33394. 3r33333. 3r3406.
The power of Prolog in the search procedure, rooted in the methods of the proof of 3r-359. theorem . Simply put, it has a built-in mechanism for unification and search with a return. It is even simpler to say mapping plus depth search in a decision tree. 3r33333. 3r3406. And Python is a modern Pascal (something already three languages on the letter "P")), and is available to write programs on it. schoolchildren . 3r33333. 3r3406. Now I will rewrite the solution that was laid in the previous implementation and quickly implement a similar prolog search with a return. 3r33333. 3r3406. Then I will launch it into the testing system, and I will see if the move (code) was correct. 3r33395. 3r33333. 3r3406.
Join now. 3r33383. 3r33333. 3r3406.
At the entrance, the tested string and pattern:
3r33333. 3r3406. 3r33357. def test (st, pat):
3r33375. 3r33333. 3r3406.
if st == "" and pat == "": yield True
if pat> "" and pat[0]== '*': yield test (st, pat[1:])
if st> "" and pat> "":
if st[0]== pat[0]or pat[0]== '?': yield test (st[1:], pat[1:])
if pat[0]== '*': yield test (st[1:], pat)
yield False
It seems to be very similar to the implementation of the Prologue:
3r33333. 3r3406. 3r33357. 3r33358. test_pattrn ([],[]). 3r3406. test_pattrn ([Ch|UnpTail],[Ch|PatTail]): - test_pattrn (UnpTail, PatTail). 3r3406. test_pattrn ([Ch|UnpTail],['?'|PatTail]): - test_pattrn (UnpTail, PatTail). 3r3406. test_pattrn ([Ch|UnpTail],['*'|PatTail]): - test_pattrn (UnpTail,['*'|PatTail]). 3r3406. test_pattrn (Str,['*'|PatTail]): - test_pattrn (Str, PatTail). 3r3406. 3r33375. 3r33333. 3r3406.
Five solutions, otherwise a lie. 3r33395. 3r33333. 3r3406.
But how to do a return search ?, for this I use yield, as it is called there, incomplete (lazy) calculations, closure, an element of the functional approach, tell me It will return something from which you can get the next solution, but if will not lead to the correct answer, then we move to the program branch with the next yield, this is the difference from return. 3r33333. 3r3406. This function will accept the result of the first test () at the input, if it is true then everything is fine, otherwise it will try to iterate more, and so will be a depth search similar to the prolog output. 3r33333. 3r3406. Here, return is already specifically needed:
3r33333. 3r3406. 3r33357. def run (r):
3r33375. 3r33333. 3r3406. 3r33132. Checking 1
if type (r) == bool:
if r == True: return True 3r3406. else:
for nr in r:
if run (nr): return True
return False
3r33333. 3r3406. Wow, this is the result, "939/1808 test cases passed." and "Status: Time Limit Exceeded". 3r33333. 3r3406. This is exactly what I expected, the declarative solution does not always lead to an effective implementation time. Transparent wording is not a quick wording. 3r33333. 3r3406. But, here is the result of the python, let's test the opened test in the implementation from the first article, and measure the time:
3r33333. 3r3406. 3r33357. import time
3r33375. 3r33333. 3r3406.
pt = time.time ()
print (run (test ("babaaababaabababbbbbbaabaabbababababababaaabbbaaab", "*** bba ** a * bbba ** aab ** b")))
print (time.time () - pt)
Runtime by Python ??? sec., Yes, but a bit too much. 3r33395. 3r33333. 3r3406.
Improved testing mechanism for Prolog:
3r33333. 3r3406. 3r33357. 3r33358. % unit-tests framework
assert_are_equal (Goal, false): - get_time (St), not (Goal),!, get_time (Fin), Per is Fin-St, writeln (Goal-> ok: Per /sec). 3r3406. assert_are_equal (Goal, true): - get_time (St), Goal,!, get_time (Fin), Per is Fin-St, writeln (Goal-> ok: Per /sec). 3r3406. assert_are_equal (Goal, Exp): - writeln (Goal-> failed: expected-Exp). 3r3406. 3r3406. : -assert_are_equal (isMatch (aaabababaaabaababbbaaaabbbbbbabbbbabbbabbaabbababab, '* ab *** ba ** b * b * aaab * b'), true). 3r3406. 3r33375. 3r33333. 3r3406.
And this is the result of Prologue (launching not in the online editor, locally, on the same hardware as the previous one): 3r3395. 3r33333. 3r3406. 3r33357. 3r33358. isMatch (aaabababaaabaababbbaaaabbbbbbabbbbabbbabbaabbababab, * ab *** ba ** b * b * aaab * b) -> ok: ??? /sec 3r33375. 3r33333. 3r3406.
It seems that I do not use the python badly ((, it is necessary to improve, not so clearly:
3rr3390. 3r3406. 3r33357. def test (st, pat):
3r33375. 3r33333. 3r3406.
if st == pat: return True
if pat> "" and pat[0]== '*':
if test (st, pat[1:]): return True
if st> "" and pat> "":
if st[0]== pat[0]or pat[0]== '?':
if test (st[1:], pat[1:]): return True
if pat[0]== '*':
if test (st[1:], pat): return True
return False
3r3406. import time
pt = time.time ()
print (test ("babaaababaabababbbbbbaabaabbababababababaaabbbaaab", "*** bba ** a * bbba ** aab ** b"))
print (time.time () - pt)
Here is the result: ??? sec. (this is closer to the original). 3r33333. 3r3406. We return to the arbitrator:
3r3406. 3r33333. 3r3406. I conclude that the total passing of tests goes beyond the time frame, because the last two options are solved very quickly. 3r33333. 3r3406. Need optimization on the order. 3r33395. 3r33333. 3r3406.
Checking 2. Need optimization. 3r33383. 3r33333. 3r3406.
What begs, for sure - search in width. 3r33333. 3r3406. Do not continue the decision of each branch until we get a lie and return to another branch, but look through the solutions by level, descending simultaneously for each option and gradually go deeper. 3r33333. 3r3406. I'll try to make it a python, and then I'll demonstrate the prologue. 3r33395. 3r33333. 3r3406. 3r33357. def test (st, pat):
3r33375. 3r33333. 3r3406.
if st == pat: return True
res =[]# I will collect all the options for going deep, these are the levels of the tree
if pat> "" and pat[0]== '*': res + =[(st,pat[1:])]3r3406. if st> "" and pat> "":
stt = st[1:]3r3406. if st[0]== pat[0]or pat[0]== '?': res + =[(stt,pat[1:])]3r3406. if pat[0]== '*': res + =[(stt,pat)]3r3406. return res
3r3406. def run (st, pat):
lev =[(st,pat)]3r3406. while len (lev)! = 0:
nxt = set () ## we collect all the underlying solutions into a set without duplicates
for s, p in lev:
one = test (s, p)
if one == True: return True 3r3406. else: nxt.update (set (one))
lev = nxt
return False
Here is the result for test 93? only ??? seconds. 3r33333. 3r3406. and , URA, this decision is taken
3r3406. Prologue
3r33333. 3r3406.
I will try to show how to implement a search in width, in a declarative implementation. To do this, there are special predicates of the second order, which can assemble solutions into a list, for example bagof, setof, findall. 3r33395. 3r33333. 3r3406.
bagof (+ Template,: Goal, -Bag)
3r3406. Unify Bag with the alternatives of Template. The bagof /3 will be able to track your bag. Not in the bind Var in Goal. bagof /3 fails if goal has no solutions. 3r33333. 3r3406. setof (+ Template, + Goal, -Set)
3r3406. This is a list of alternatives without duplicates.
The predicate setof works well. he already knows how to remove duplicates (in the python for this I had to learn about sets). 3r33333. 3r3406. So, I will make a predicate that gets a solution of one level, then we collect it with another predicate and delve into it, here’s the complete solution:
3r33333. 3r3406. 3r33357. 3r33358. atom_to_list (Str,[Ch|T]): -
atom_concat (Ch, Rest, Str), atom_length (Ch, 1),
atom_to_list (Rest, T). 3r3406. 3r3406. % conversion options
pattrn (X: X, true). % - everything is good when both are the same
pattrn ([Ch|UnpTail]:[Ch|PatTail], UnpTail: PatTail). 3r3406. pattrn ([_|UnpTail]:['?'|PatTail], UnpTail: PatTail). 3r3406. pattrn ([_|UnpTail]:['*'|PatTail], UnpTail:['*'|PatTail]). 3r3406. pattrn (Str:['*'|PatTail], Str: PatTail). 3r3406. 3r3406. % if it is true, then it is not necessary to search for more, otherwise the level check is below 3r3406. next_level (Lev): - member (true, Lev),!. 3r3406. next_level (Lev): - setof (One, SP ^ (member (SP, Lev), pattrn (SP, One)), Next),!, 3r3406. next_level (Next). 3r3406. 3r3406. test_pattrn (Str, Pat): - next_level ([Str:Pat]). 3r3406. 3r3406. isMatch (S, P): - atom_to_list (S, SL), atom_to_list (P, PL),!, 3r3406. test_pattrn (SL, PL),!. 3r3406. 3r3406. % unit-tests framework
assert_are_equal (Goal, false): - get_time (St), not (Goal)!! get_time (Fin), Per is Fin-St,
writeln (Goal-> ok: Per /sec). 3r3406. assert_are_equal (Goal, true): - get_time (St), Goal,!, get_time (Fin), Per is Fin-St,
writeln (Goal-> ok: Per /sec). 3r3406. assert_are_equal (Goal, Exp): - writeln (Goal-> failed: expected-Exp). 3r3406. 3r3406. % all test
: -assert_are_equal (isMatch (aa, a), false). 3r3406. : -assert_are_equal (isMatch (aa, '*'), true). 3r3406. : -assert_are_equal (isMatch (cb, '? a'), false). 3r3406. : -assert_are_equal (isMatch (adceb, '* a * b'), true). 3r3406. : -assert_are_equal (isMatch (acdcb, 'a * c? b'), false). 3r3406. : -assert_are_equal (isMatch (aab, 'c * a * b'), false). 3r3406. : -assert_are_equal (isMatch (mississippi, 'm ?? * ss *? i * pi'), false). 3r3406. : -assert_are_equal (isMatch (abefcdgiescdfimde, 'ab * cd? i * de'), true). 3r3406. : -assert_are_equal (isMatch (zacabz, '* a? b *'), false). 3r3406. : -assert_are_equal (isMatch (leetcode, '* e * t? d *'), false). 3r3406. : -assert_are_equal (isMatch (aaaa, '*** a'), true). 3r3406. : -assert_are_equal (isMatch (b, '*? *? *'), false). 3r3406. : -assert_are_equal (isMatch (aaabababaaabaababbbaaaabbbbbbabbbbabbbabbaabbababab, '* ab *** ba ** b * b * aaab * b'), true). 3r3406. : -assert_are_equal (isMatch (abbbbbbbaabbabaabaa, '***** a * ab'), false). 3r3406. : -assert_are_equal (isMatch (aaabababaaabaababbbaaaabbbbbbabbbbabbbabbaabbababab, '* ab *** ba ** b * b * aaab * b'), true). 3r3406. : -assert_are_equal (isMatch (babaaababaabababbbbbbaabaabbababababababaaabbbaaab, '*** bba ** a * bbba ** aab ** b'), false). 3r33375. 3r33333. 3r3406.
Here you can see that the rule that previously performed a pattern-based search, as if making a transition along a face in a graph, has now become a set of pattrn facts that contain possible transitions (connections between states) —that is a description of the graph, and not a code that implements it. 3r33395. 3r33333. 3r3406.
And the results of execution with the time in seconds .:
3r33333. 3r3406. 3r33357. 3r33358. isMatch (aa, a) -> ok: ??? /sec
isMatch (aa, *) -> ok: ???e-5 /sec
isMatch (cb,? a) -> ok: ???e-5 /sec
isMatch (adceb, * a * b) -> ok: ??? /sec
isMatch (acdcb, a * c? b) -> ok: ???e-5 /sec
isMatch (aab, c * a * b) -> ok: ???e-5 /sec
isMatch (mississippi, m ?? * ss *? i * pi) -> ok: ??? /sec
isMatch (abefcdgiescdfimde, ab * cd? i * de) -> ok: ??? /sec
isMatch (zacabz, * a? b *) -> ok: ???e-5 /sec
isMatch (leetcode, * e * t? d *) -> ok: ??? /sec
isMatch (aaaa, *** a) -> ok: ???e-5 /sec
isMatch (b, *? *? *) -> ok: ???e-5 /sec
isMatch (aaabababaaabaababbbaaaabbbbbbabbbbabbbabbaabbababab, * ab *** ba ** b * b * aaab * b) -> ok: ??? /sec
isMatch (abbbbbbbaabbabaabaa, ***** a * ab) -> ok: ??? /sec
isMatch (aaabababaaabaababbbaaaabbbbbbabbbbabbbabbaabbababab, * ab *** ba ** b * b * aaab * b) -> ok: ??? /sec
isMatch (babaaababaabababbbbbbaabaabbabababbaababbaaabbbaaab, *** bba ** a * bbba ** aab ** b) -> ok: ??? /sec 3r33375. 3r33333. 3r3406.
And this is already a successful decision not only logically but also in time. 3r33395. 3r33333. 3r3406. 3r33382. Conclusions
3r33333. 3r3406.
In the previous article, I wanted to see an interest in the topic of a declarative approach. The theme "niasilil such an approach" immediately opened, yet you can show interest. Here I showed that there is a performance problem, what is written clearly does not work quickly. Attempts to create a parallel prologue did not end with success. Maybe there is a question of the future, can a quantum computer ?? 3r33333. 3r3406. Total use puzzles on the above site, for a pleasant stay with the mind. 3r33395. 3r33333. 3r3406.
Well, next time, there will be an attempt to immediately solve effectively another of hard tasks . 3r33395. 3r3402. 3r3406. 3r3406. 3r33399. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33400. 3r3406. 3r3402. 3r3406. 3r3406. 3r3406. 3r3406.
It may be interesting
Here we introduce our top coupons that will help you for online shopping at discountable prices.Revounts bring you the best deals that slash the bills.If you are intrested in online shopping and want to save your savings then visit our site for best experience.