Deutsch English Français Italiano |
<veeump$b5p9$1@solani.org> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!fu-berlin.de!weretis.net!feeder8.news.weretis.net!reader5.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Mild Shock <janburse@fastmail.fm> Newsgroups: comp.lang.prolog Subject: Re: variant_term/2 is faster than variant/1 (Was: Request for comments, Novacore the sequel to ISO modules) Date: Sun, 13 Oct 2024 00:54:18 +0200 Message-ID: <veeump$b5p9$1@solani.org> References: <db8a6771-3e54-485b-b391-310658dd6f52n@googlegroups.com> <aa869ef6-7f90-405b-a84a-2c11ac7979a3n@googlegroups.com> <vcukob$n3q2$1@solani.org> <veekkd$b9uf$1@solani.org> <veeq19$bcbb$1@solani.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Sat, 12 Oct 2024 22:54:17 -0000 (UTC) Injection-Info: solani.org; logging-data="366377"; mail-complaints-to="abuse@news.solani.org" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 SeaMonkey/2.53.19 Cancel-Lock: sha1:Q2PZr0zZLxrq9gUjOQks1WuP+Wo= In-Reply-To: <veeq19$bcbb$1@solani.org> X-User-ID: eJwFwQcBwEAIBDBL8HAMOWX5l9AEYmztajDF4arrzgg5spuRKRca1NjXV+bl8DmR9uIJ4i+0nj3y2Cls/mxjFeM= Bytes: 5033 Lines: 158 Ok, I have to redo my nok/2 test for Scryer Prolog, since Scryer Prolog doesn't work as per ISO spec: /* Scryer Prolog Playground */ ?- builtins:variant(f(A,B), f(C,D)). A = A, B = A, C = A, D = A. It should not leave some bindings. At least this is what other Prolog systems do: /* Trealla Prolog */ ?- variant(f(A,B), f(C,D)). true. /* SWI-Prolog */ ?- variant(f(A,B), f(C,D)). true. The performance tests are not affected, but I guess it is better to test nok/2 like this: nok2(L, R) :- length(L, 6), length(R, 6), enum_list(_, L), enum_list(_, R), boole(variant_term(L, R), A), boole(builtins:variant(L, R), B), A \== B. Besides the binding glitch, it seems to be ok: ?- nok2(L, R). false. Mild Shock schrieb: > So what can we do with this insight. Here is > a little performance of a new distinct/1, > that is eager und non-variant enumerating: > > /* eagerness */ > ?- distinct(repeat), !. > true. > > d(f(A,A)). > d(f(a,a)). > d(f(B,B)). > > /* non-variant enumerating */ > ?- distinct(d(X)). > X = f(_70321, _70321); > X = f(a, a); > fail. > > It is implemented with variant_term/2, since the > remembered list of archived witnesses so far, > is anyway copies of terms. So variant_term/2 > > is appropriate, we never have to check > two terms that have variables in common. > > Cool! > > Mild Shock schrieb: >> How much faster is it? >> >> Here some test harness: >> >> test :- length(L, 6), length(R, 6), >> enum_list(_, L), enum_list(_, R), >> variant(L, R), fail; true. >> >> test2 :- length(L, 6), length(R, 6), >> enum_list(_, L), enum_list(_, R), >> variant_term(L, R), fail; true. >> >> Here some results: >> >> - SWI-Prolog 9.3.11: >> >> ?- time(test). >> % 2,126,498 inferences, 0.734 CPU in 0.752 seconds >> (98% CPU, 2895657 Lips) >> true. >> >> ?- time(test2). >> % 2,159,795 inferences, 0.234 CPU in 0.236 seconds >> (99% CPU, 9215125 Lips) >> true. >> >> - Trealla Prolog 2.57.16: >> >> ?- time(test). >> % Time elapsed 3.128s, 14827949 Inferences, 4.741 MLips >> true. >> >> ?- time(test2). >> % Time elapsed 1.079s, 7775516 Inferences, 7.206 MLips >> true. >> >> - Scryer Prolog : >> >> ?- time(test3). >> % CPU time: 5.653s, 5_192_831 inferences >> true. >> >> ?- time(test2). >> % CPU time: 1.544s, 6_116_163 inferences >> true. >> >> Note: test3 is like test, only it uses builtins:variant/2. >> >> Mild Shock schrieb: >>> The ISO core standard probably set the >>> stage for a couple of performance sins. >>> In 7.1.6.1 Variants of a term we find >>> >>> these test cases: >>> >>> - f(A, B, A) is a variant of f(X, Y, X). >>> - g(A, B) is a variant of g(_, _). >>> - P+Q is a variant of P+Q. >>> >>> What is doubious here, is the last test >>> case with P+Q. Do we need to test terms >>> that have common variables? >>> >>> Lets assume we have situations where we >>> don't need variant working with common >>> variables in the two argument terms, what >>> >>> about then using this bootstrapping: >>> >>> variant_term(X, Y) :- >>> subsumes_term(X, Y), >>> subsumes_term(Y, X). >>> >>> Here some testing, does it work ok? Take this code: >>> >>> enum_arg(_, 1). >>> enum_arg(_, _). >>> enum_arg(X, X). >>> >>> enum_list(_, []). >>> enum_list(X, [H|T]) :- enum_arg(X, H), enum_list(X, T). >>> >>> boole(G, 1) :- G, !. >>> boole(_, 0). >>> >>> nok(L, R) :- length(L, 6), length(R, 6), >>> enum_list(_, L), enum_list(_, R), >>> boole(variant(L, R), A), boole(variant_term(L, R), B), >>> A \== B. >>> >>> Seems to work fine: >>> >>> ?- nok(L, R). >>> false. >>> >>> >> >