From 220e1e8d837e79361402c63d582f68d17c2edb88 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Mon, 22 Nov 2021 19:55:34 +0100 Subject: [PATCH 1/3] ADDED: must_be(chars, ...) and can_be(chars, ...) for string tests. Internal features of Scryer Prolog are used to make these tests fast. --- src/lib/error.pl | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/lib/error.pl b/src/lib/error.pl index a79bd560..d6bf8708 100644 --- a/src/lib/error.pl +++ b/src/lib/error.pl @@ -1,3 +1,8 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Written September 2018 by Markus Triska (triska@metalevel.at) + I place this code in the public domain. Use it in any way you want. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + :- module(error, [must_be/2, can_be/2, instantiation_error/1, @@ -5,12 +10,6 @@ type_error/3 ]). -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written September 2018 by Markus Triska (triska@metalevel.at) - I place this code in the public domain. Use it in any way you want. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - must_be(Type, Term) @@ -25,10 +24,12 @@ Currently, the following types are supported: - - integer - atom - - list - boolean + - character + - chars + - integer + - list - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ must_be(Type, Term) :- @@ -45,10 +46,27 @@ must_be_(var, Term) :- must_be_(integer, Term) :- check_(integer, integer, Term). must_be_(atom, Term) :- check_(atom, atom, Term). must_be_(character, T) :- check_(error:character, character, T). +must_be_(chars, Ls) :- + ( ground(Ls), '$is_partial_string'(Ls) -> + % The expected case (success) uses a very fast test. + % We cannot use partial_string/1 from library(iso_ext), + % because that library itself imports library(error). + true + ; must_be(list, Ls), + all_characters(Ls) + ). must_be_(list, Term) :- check_(error:ilist, list, Term). must_be_(type, Term) :- check_(error:type, type, Term). must_be_(boolean, Term) :- check_(error:boolean, boolean, Term). +% We cannot use maplist(must_be(character), Cs), because library(lists) +% uses library(error), so importing it would create a cyclic dependency. + +all_characters([]). +all_characters([C|Cs]) :- + must_be(character, C), + all_characters(Cs). + check_(Pred, Type, Term) :- ( var(Term) -> instantiation_error(must_be/2) ; call(Pred, Term) -> true @@ -69,6 +87,7 @@ type(type). type(integer). type(atom). type(character). +type(chars). type(list). type(var). type(boolean). @@ -97,6 +116,7 @@ can_be(Type, Term) :- can_(integer, Term) :- integer(Term). can_(atom, Term) :- atom(Term). can_(character, T) :- character(T). +can_(chars, Ls) :- '$is_partial_string'(Ls). can_(list, Term) :- list_or_partial_list(Term). can_(boolean, Term) :- boolean(Term). From fe291e90f095769667eee676cc8e197d953c9915 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Mon, 22 Nov 2021 19:58:36 +0100 Subject: [PATCH 2/3] use newly available must_be(chars, ...) for fast string tests --- src/lib/crypto.pl | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/lib/crypto.pl b/src/lib/crypto.pl index 3d19a72b..efc478ae 100644 --- a/src/lib/crypto.pl +++ b/src/lib/crypto.pl @@ -1,5 +1,5 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written May 2020 by Markus Triska (triska@metalevel.at) + Written 2020, 2021 by Markus Triska (triska@metalevel.at) Part of Scryer Prolog. Predicates for cryptographic applications. @@ -46,7 +46,6 @@ :- use_module(library(format)). :- use_module(library(charsio)). :- use_module(library(si)). -:- use_module(library(iso_ext), [partial_string/1]). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - hex_bytes(?Hex, ?Bytes) is det. @@ -105,21 +104,12 @@ must_be_bytes(Bytes, Context) :- must_be_byte_chars(Chars, Context) :- - ( partial_string(Chars) -> - ( '$first_non_octet'(Chars, F) -> - domain_error(byte_char, F, Context) - ; true - ) - ; must_be(list, Chars), - ( member(Char, Chars), - char_code(Char, Code), - \+ between(0, 255, Code) -> - domain_error(byte_char, Char, Context) - ; true - ) + must_be(chars, Chars), + ( '$first_non_octet'(Chars, F) -> + domain_error(byte_char, F, Context) + ; true ). - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cryptographically secure random numbers ======================================= @@ -620,11 +610,7 @@ encoding_chars(octet, Bs, Cs) :- ), must_be_byte_chars(Cs, crypto_encoding). encoding_chars(utf8, Cs, Cs) :- - ( partial_string(Cs) -> - true - ; must_be(list, Cs), - maplist(must_be(character), Cs) - ). + must_be(chars, Cs). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Digital signatures with Ed25519 From 0d4c38138aef1c04e3d9e5fdc0ca98a4a153d5be Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Mon, 22 Nov 2021 20:00:06 +0100 Subject: [PATCH 3/3] use newly available must_be(chars, ...) for fast string tests --- src/lib/charsio.pl | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/lib/charsio.pl b/src/lib/charsio.pl index 3c5affa9..5ff611f6 100644 --- a/src/lib/charsio.pl +++ b/src/lib/charsio.pl @@ -260,18 +260,11 @@ chars_base64(Cs, Bs, Options) :- ; domain_error(charset, Charset, chars_base64/3) ), ( var(Cs) -> - must_be_characters(Bs), + must_be(chars, Bs), '$chars_base64'(Cs, Bs, Padding, Charset) - ; must_be_characters(Cs), + ; must_be(chars, Cs), ( '$first_non_octet'(Cs, N) -> domain_error(byte_char, N, chars_base64/3) ; '$chars_base64'(Cs, Bs, Padding, Charset) ) ). - -must_be_characters(Cs) :- - ( partial_string(Cs) -> - true - ; must_be(list, Cs), - maplist(must_be(character), Cs) - ).