Compare commits
139 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fc5be0d03 | ||
|
|
357ae7a8aa | ||
|
|
ac00ae4daf | ||
|
|
249f034a38 | ||
|
|
32c612b747 | ||
|
|
386f7cf65d | ||
|
|
320802633f | ||
|
|
dcc4b91b35 | ||
|
|
e7c27ed999 | ||
|
|
928c9c9aad | ||
|
|
4a90f13dee | ||
|
|
61dddcee3f | ||
|
|
4c510001ce | ||
|
|
82dfa690d2 | ||
|
|
2768beec4c | ||
|
|
bd0aa16322 | ||
|
|
a1746a5bf1 | ||
|
|
fb502fb66b | ||
|
|
c9a69263b6 | ||
|
|
f0c8056334 | ||
|
|
17dd9239b6 | ||
|
|
6c691d9223 | ||
|
|
920644afaf | ||
|
|
8668aee7fd | ||
|
|
4f386b3e5e | ||
|
|
0f4667d942 | ||
|
|
5705c42820 | ||
|
|
f5f0d00a75 | ||
|
|
ec75e21898 | ||
|
|
94e9e17c79 | ||
|
|
5134e64cae | ||
|
|
53d39ccb4b | ||
|
|
b227e160f0 | ||
|
|
88a2b82f7e | ||
|
|
0016365446 | ||
|
|
0fa8feb475 | ||
|
|
eb872f8fca | ||
|
|
5fd78320dd | ||
|
|
3195042c7d | ||
|
|
b0234fa8b7 | ||
|
|
2a629fee37 | ||
|
|
bf13700a95 | ||
|
|
83268f5ff6 | ||
|
|
1eb42654e0 | ||
|
|
e05c34d1ee | ||
|
|
8325bb11e2 | ||
|
|
c1b577f2c7 | ||
|
|
29a61db275 | ||
|
|
e2c61485a1 | ||
|
|
65f200e02c | ||
|
|
aa9432e24f | ||
|
|
30d1585468 | ||
|
|
376c5263f0 | ||
|
|
bcd6d4e8a7 | ||
|
|
32eb896c56 | ||
|
|
4603163e88 | ||
|
|
b3c9fb2fea | ||
|
|
d66ea07ba4 | ||
|
|
496279c92d | ||
|
|
e0ae925ca3 | ||
|
|
1799c19933 | ||
|
|
94eddd3b42 | ||
|
|
79829cb6d2 | ||
|
|
0d20ca0bf2 | ||
|
|
3ede5ea28f | ||
|
|
cfd15f4e02 | ||
|
|
1f9ff2dd88 | ||
|
|
7740a39a4d | ||
|
|
5eda2dfe0e | ||
|
|
1509c6a471 | ||
|
|
19acd608a5 | ||
|
|
bc81ff28d8 | ||
|
|
ba867e95c3 | ||
|
|
53f99ca434 | ||
|
|
8958ea036e | ||
|
|
d3563c30e7 | ||
|
|
0f017339b7 | ||
|
|
4d3a3d806f | ||
|
|
10a0f708b9 | ||
|
|
409d3c168d | ||
|
|
005220b6d4 | ||
|
|
8462b039d3 | ||
|
|
2e3cabce6b | ||
|
|
2c6b615b8c | ||
|
|
f910e013a6 | ||
|
|
5f1b03261c | ||
|
|
862197fc96 | ||
|
|
44ebd894d5 | ||
|
|
b85ff7db36 | ||
|
|
22fd216de5 | ||
|
|
2f02c428cc | ||
|
|
1732413ee1 | ||
|
|
33325f1574 | ||
|
|
4f288c6fd9 | ||
|
|
5ffb4597b3 | ||
|
|
d9de38b935 | ||
|
|
ad459b83c0 | ||
|
|
d96ea6b815 | ||
|
|
40c3e31955 | ||
|
|
f84c831cda | ||
|
|
904cf97f7d | ||
|
|
791e22dc24 | ||
|
|
c82a0b3d2d | ||
|
|
2fc887724b | ||
|
|
e16762a137 | ||
|
|
4a07ffac69 | ||
|
|
9331c4ce9e | ||
|
|
184ef94e7e | ||
|
|
d67740d44d | ||
|
|
7b30daf88d | ||
|
|
d5e76da475 | ||
|
|
5d91c1af81 | ||
|
|
bb013e78d2 | ||
|
|
c22816de08 | ||
|
|
9bb851d437 | ||
|
|
c8a9f8dcf5 | ||
|
|
e8653ffe32 | ||
|
|
5499df418a | ||
|
|
b586618411 | ||
|
|
3b5730be54 | ||
|
|
961c4a1b9c | ||
|
|
72c5908f09 | ||
|
|
2a588ff943 | ||
|
|
24f11b5ae9 | ||
|
|
1d44d99875 | ||
|
|
eebcdfb24f | ||
|
|
526b56a650 | ||
|
|
20675f56e6 | ||
|
|
e5fbdeb3a9 | ||
|
|
7cc92ec1c1 | ||
|
|
fe0bf6f2ef | ||
|
|
828c19d478 | ||
|
|
15db77558c | ||
|
|
18cf4a3bd3 | ||
|
|
e0378acfc2 | ||
|
|
53cb2af202 | ||
|
|
f74005a166 | ||
|
|
b0df981b01 | ||
|
|
cc9d6587a3 |
703
Cargo.lock
generated
703
Cargo.lock
generated
@@ -27,6 +27,12 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
@@ -45,6 +51,27 @@ version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
@@ -125,6 +152,17 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits 0.2.11",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
@@ -140,6 +178,22 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
|
||||
|
||||
[[package]]
|
||||
name = "cpu-time"
|
||||
version = "1.0.0"
|
||||
@@ -156,7 +210,7 @@ version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.0.0",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
@@ -239,6 +293,27 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
@@ -255,6 +330,16 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
|
||||
dependencies = [
|
||||
"mac",
|
||||
"new_debug_unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
@@ -292,9 +377,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34a97a52fdee1870a34fa6e4b77570cba531b27d1838874fef4429a791a3d657"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.10",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -318,13 +403,27 @@ dependencies = [
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ce65ac8028cf5a287a7dbf6c4e0a6cf2dcf022ed5b167a81bae66ebf599a8b7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mac",
|
||||
"markup5ever",
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -336,6 +435,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.39"
|
||||
@@ -397,6 +502,17 @@ version = "0.2.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
|
||||
|
||||
[[package]]
|
||||
name = "libsodium-sys"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a685b64f837b339074115f2e7f7b431ac73681d08d75b389db7498b8892b8a58"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.3.4"
|
||||
@@ -415,6 +531,29 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1af46a727284117e09780d05038b1ce6fc9c76cc6df183c3dae5a8955a25e21"
|
||||
dependencies = [
|
||||
"log",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"string_cache",
|
||||
"string_cache_codegen",
|
||||
"tendril",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "match_cfg"
|
||||
version = "0.1.0"
|
||||
@@ -464,6 +603,24 @@ dependencies = [
|
||||
"ws2_32-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.33"
|
||||
@@ -475,6 +632,12 @@ dependencies = [
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.15.0"
|
||||
@@ -513,7 +676,7 @@ version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.0.0",
|
||||
"num-integer",
|
||||
"num-traits 0.2.11",
|
||||
]
|
||||
@@ -524,7 +687,7 @@ version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.0.0",
|
||||
"num-traits 0.2.11",
|
||||
]
|
||||
|
||||
@@ -534,7 +697,7 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.0.0",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits 0.2.11",
|
||||
@@ -568,7 +731,7 @@ version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -583,6 +746,49 @@ version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "111.9.0+1.1.1g"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2dbe10ddd1eb335aba3780eb2eaa13e1b7b441d2562fd962398740927f39ec4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
|
||||
dependencies = [
|
||||
"autocfg 1.0.0",
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "0.5.2"
|
||||
@@ -617,26 +823,91 @@ dependencies = [
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.7.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.7.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.7.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand 0.6.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.7.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prolog_parser"
|
||||
version = "0.8.59"
|
||||
version = "0.8.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "029a4682cf40923b8eb05c4b943d1d6be73775e7bf80bcb0866b5ef29abb0802"
|
||||
checksum = "fdcfe8260335a150812e36b171ff985ce88f02de16c05f4a13fe4f10e8c247f8"
|
||||
dependencies = [
|
||||
"lexical",
|
||||
"num-rug-adapter",
|
||||
@@ -645,13 +916,178 @@ dependencies = [
|
||||
"unicode_reader",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2 1.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7",
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc 0.1.0",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -677,6 +1113,15 @@ version = "0.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
dependencies = [
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.13"
|
||||
@@ -703,6 +1148,15 @@ dependencies = [
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5001f134077069d87f77c8b9452b690df2445f7a43f1c7ca4a1af8dd505789d"
|
||||
dependencies = [
|
||||
"xmlparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rug"
|
||||
version = "1.8.0"
|
||||
@@ -720,7 +1174,7 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.11.0",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq",
|
||||
"crossbeam-utils",
|
||||
@@ -760,6 +1214,16 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@@ -768,9 +1232,11 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "scryer-prolog"
|
||||
version = "0.8.123"
|
||||
version = "0.8.126"
|
||||
dependencies = [
|
||||
"base64 0.12.3",
|
||||
"blake2",
|
||||
"chrono",
|
||||
"cpu-time",
|
||||
"crossterm",
|
||||
"dirs",
|
||||
@@ -781,19 +1247,57 @@ dependencies = [
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"native-tls",
|
||||
"nix 0.15.0",
|
||||
"num-rug-adapter",
|
||||
"openssl",
|
||||
"ordered-float",
|
||||
"prolog_parser",
|
||||
"ref_thread_local",
|
||||
"ring",
|
||||
"ripemd160",
|
||||
"roxmltree",
|
||||
"rug",
|
||||
"rustyline",
|
||||
"select",
|
||||
"sha3",
|
||||
"sodiumoxide",
|
||||
"unicode_reader",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "select"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac645958c62108d11f90f8d34e4dc2799c838fc995ed4c2075867a2a8d5be76b"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"html5ever",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
@@ -809,6 +1313,34 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93c5eaa17d0954cb481cdcfffe9d84fcfa7a1a9f2349271e678677be4c26ae31"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.10",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.8.2"
|
||||
@@ -843,6 +1375,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
@@ -864,6 +1402,17 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
|
||||
|
||||
[[package]]
|
||||
name = "sodiumoxide"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7038b67c941e23501573cb7242ffb08709abe9b11eb74bceff875bbda024a6a8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libsodium-sys",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
@@ -876,21 +1425,101 @@ version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"new_debug_unreachable",
|
||||
"phf_shared",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
"string_cache_codegen",
|
||||
"string_cache_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_codegen"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2 1.0.10",
|
||||
"quote 1.0.3",
|
||||
"string_cache_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_shared"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"proc-macro2 1.0.10",
|
||||
"quote 1.0.3",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rand 0.7.3",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendril"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b"
|
||||
dependencies = [
|
||||
"futf",
|
||||
"mac",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -911,6 +1540,12 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
@@ -942,12 +1577,24 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
@@ -979,9 +1626,9 @@ dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.10",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.18",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -991,7 +1638,7 @@ version = "0.2.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"quote 1.0.3",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
@@ -1001,9 +1648,9 @@ version = "0.2.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.10",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.18",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -1067,3 +1714,9 @@ dependencies = [
|
||||
"winapi 0.2.8",
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmlparser"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52613e655f6f11f63c0fe7d1c3b5ef69e44d96df9b65dab296b441ed0e1125f5"
|
||||
|
||||
13
Cargo.toml
13
Cargo.toml
@@ -1,13 +1,13 @@
|
||||
[package]
|
||||
name = "scryer-prolog"
|
||||
version = "0.8.123"
|
||||
version = "0.8.127"
|
||||
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A modern Prolog implementation written mostly in Rust."
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/mthom/scryer-prolog"
|
||||
license = "BSD-3-Clause"
|
||||
keywords = ["prolog", "prolog-interpreter", "prolog-implementation"]
|
||||
keywords = ["prolog", "prolog-interpreter", "prolog-system"]
|
||||
categories = ["command-line-utilities"]
|
||||
build = "build.rs"
|
||||
|
||||
@@ -32,7 +32,7 @@ libc = "0.2.62"
|
||||
nix = "0.15.0"
|
||||
num-rug-adapter = { optional = true, version = "0.1.3" }
|
||||
ordered-float = "0.5.0"
|
||||
prolog_parser = { version = "0.8.59", default-features = false }
|
||||
prolog_parser = { version = "0.8.65", default-features = false }
|
||||
ref_thread_local = "0.0.0"
|
||||
rug = { version = "1.4.0", optional = true }
|
||||
rustyline = "6.0.0"
|
||||
@@ -41,3 +41,10 @@ ring = "0.16.13"
|
||||
ripemd160 = "0.8.0"
|
||||
sha3 = "0.8.2"
|
||||
blake2 = "0.8.1"
|
||||
openssl = { version = "0.10.29", features = ["vendored"] }
|
||||
native-tls = "0.2.4"
|
||||
chrono = "0.4.11"
|
||||
select = "0.4.3"
|
||||
roxmltree = "0.11.0"
|
||||
base64 = "0.12.3"
|
||||
sodiumoxide = "0.2.6"
|
||||
|
||||
142
README.md
142
README.md
@@ -5,6 +5,8 @@ source industrial strength production environment that is also a
|
||||
testbed for bleeding edge research in logic and constraint
|
||||
programming, which is itself written in a high-level language.
|
||||
|
||||

|
||||
|
||||
## Phase 1
|
||||
|
||||
Produce an implementation of the Warren Abstract Machine in Rust, done
|
||||
@@ -269,8 +271,13 @@ the above example, posting <tt>Ls0 = [a,b,c|Ls]</tt> yields
|
||||
the exact same internal representation, and has the advantage that
|
||||
only the standard predicate `(=)/2` is used.
|
||||
|
||||
Definite clause grammars as provided by `library(dcgs)` are ideally
|
||||
suited for reasoning about strings.
|
||||
Definite clause grammars as provided by
|
||||
[`library(dcgs)`](src/lib/lists.pl), and the predicates from
|
||||
[`library(lists)`](src/lib/lists.pl), are ideally suited for reasoning
|
||||
about strings.
|
||||
|
||||
Partial strings were first proposed by Ulrich Neumerkel in issue
|
||||
[#95](https://github.com/mthom/scryer-prolog/issues/95).
|
||||
|
||||
### Tabling (SLG resolution)
|
||||
|
||||
@@ -287,7 +294,7 @@ even if one exists.
|
||||
Scryer Prolog supports an alternative execution strategy which is
|
||||
called *tabling* and also known as tabled execution and
|
||||
SLG resolution. To enable tabled execution for a predicate, use
|
||||
[`library(tabling)`](src/prolog/lib/tabling.pl) and add a `(table)/1`
|
||||
[`library(tabling)`](src/lib/tabling.pl) and add a `(table)/1`
|
||||
directive for the desired predicate indicator. For example, if we
|
||||
write:
|
||||
|
||||
@@ -312,14 +319,14 @@ Scryer Prolog provides excellent support for Constraint Logic
|
||||
Programming (CLP), which is the amalgamation of
|
||||
Logic Programming (LP) and Constraints.
|
||||
|
||||
In addition to built-in support for [`dif/2`](src/prolog/lib/dif.pl),
|
||||
[`freeze/2`](src/prolog/lib/freeze.pl),
|
||||
[CLP(B)](src/prolog/lib/clpb.pl) and [CLP(ℤ)](src/prolog/lib/clpz.pl),
|
||||
In addition to built-in support for [`dif/2`](src/lib/dif.pl),
|
||||
[`freeze/2`](src/lib/freeze.pl),
|
||||
[CLP(B)](src/lib/clpb.pl) and [CLP(ℤ)](src/lib/clpz.pl),
|
||||
Scryer provides a convenient way to implement new user-defined
|
||||
constraints: *Attributed variables* are available via
|
||||
[`library(atts)`](src/prolog/lib/atts.pl) as in SICStus Prolog,
|
||||
[`library(atts)`](src/lib/atts.pl) as in SICStus Prolog,
|
||||
which is one of the most sophisticated and fastest constraint systems
|
||||
in existence. In [`library(iso_ext)`](src/prolog/lib/iso_ext.pl),
|
||||
in existence. In [`library(iso_ext)`](src/lib/iso_ext.pl),
|
||||
Scryer provides predicates for backtrackable (`bb_b_put/2`) and
|
||||
non-backtrackable (`bb_put/2`) global variables, which are needed to
|
||||
implement certain types of constraint solvers.
|
||||
@@ -332,7 +339,7 @@ learning and developing portable CLP applications.
|
||||
Scryer has a simple predicate-based module system. It provides a
|
||||
way to separate units of code into distinct namespaces, for both
|
||||
predicates and operators. See the files
|
||||
[`src/prolog/lib/*.pl`](src/prolog/lib) for
|
||||
[`src/lib/*.pl`](src/lib) for
|
||||
examples.
|
||||
|
||||
At the time of this writing, many predicates reside in their own
|
||||
@@ -340,31 +347,31 @@ modules that need to be imported before they can be used.
|
||||
The modules that ship with Scryer Prolog are also called
|
||||
*library* modules or *libraries*, and include:
|
||||
|
||||
* [`lists`](src/prolog/lib/lists.pl)
|
||||
* [`lists`](src/lib/lists.pl)
|
||||
providing `length/2`, `member/2`, `select/3`, `append/[2,3]`,
|
||||
`foldl/[4,5]`, `maplist/[2-9]`, `same_length/2`, `transpose/2` etc.
|
||||
* [`dcgs`](src/prolog/lib/dcgs.pl)
|
||||
* [`dcgs`](src/lib/dcgs.pl)
|
||||
Definite Clause Grammars (DCGs), a built-in grammar mechanism
|
||||
that uses the operator `(-->)/2` to define grammar rules,
|
||||
and the predicates `phrase/[2,3]` to invoke them.
|
||||
* [`dif`](src/prolog/lib/dif.pl)
|
||||
* [`dif`](src/lib/dif.pl)
|
||||
The predicate `dif/2` provides declarative disequality:
|
||||
It is true if and only if its arguments are different, and
|
||||
delays the test until a sound decision can be made.
|
||||
* [`reif`](src/prolog/lib/reif.pl)
|
||||
* [`reif`](src/lib/reif.pl)
|
||||
providing `if_/3`, `tfilter/3` and related predicates
|
||||
as described in *Indexing dif/2*.
|
||||
* [`clpz`](src/prolog/lib/clpz.pl)
|
||||
* [`clpz`](src/lib/clpz.pl)
|
||||
CLP(ℤ): Constraint Logic Programming over Integers,
|
||||
providing declarative integer arithmetic via `(#=)/2`, `(#\=)/2`,
|
||||
`(#>=)/2` etc., and various global constraints and
|
||||
enumeration predicates for solving combinatorial tasks.
|
||||
* [`pairs`](src/prolog/lib/pairs.pl)
|
||||
* [`pairs`](src/lib/pairs.pl)
|
||||
By convention, *pairs* are Prolog terms with
|
||||
principal functor `(-)/2`, written as `Key-Value`.
|
||||
This library provides `pairs_keys_values/3`,
|
||||
`pairs_keys/2`, and other predicates to reason about pairs.
|
||||
* [`si`](src/prolog/lib/si.pl)
|
||||
* [`si`](src/lib/si.pl)
|
||||
The predicates `atom_si/1`, `integer_si/1`, `atomic_si/1`
|
||||
and `list_si/1` implement sound type checks. They raise
|
||||
instantiation errors if no decision can be made.
|
||||
@@ -373,51 +380,84 @@ The modules that ship with Scryer Prolog are also called
|
||||
write `integer_si(X)` to ensure soundness of your programs.
|
||||
"si" stands for *sufficiently instantiated*, and also for
|
||||
*sound inference*.
|
||||
* [`error`](src/prolog/lib/error.pl)
|
||||
`must_be/2` and `can_be/2` complement the type checks provided
|
||||
by `library(si)`, and are especially useful for Prolog library
|
||||
authors.
|
||||
* [`tabling`](src/prolog/lib/tabling.pl)
|
||||
* [`debug`](src/lib/debug.pl)
|
||||
Various predicates that allow for declarative debugging.
|
||||
* [`pio`](src/lib/pio.pl)
|
||||
`phrase_from_file/2` applies a DCG nonterminal to the contents of a
|
||||
file, reading lazily only as much as is needed. Due to the compact
|
||||
internal string representation, also extremely large files can be
|
||||
efficiently processed with Scryer Prolog in this way.
|
||||
* [`charsio`](src/lib/charsio.pl) Various predicates that are useful
|
||||
for parsing and reasoning about characters, notably `char_type/2` to
|
||||
classify characters according to their type, and conversion
|
||||
predicates for different encodings of strings.
|
||||
* [`error`](src/lib/error.pl)
|
||||
`must_be/2` and `can_be/2` complement the type checks provided by
|
||||
[`library(si)`](src/lib/si.pl), and are especially useful for
|
||||
Prolog library authors.
|
||||
* [`tabling`](src/lib/tabling.pl)
|
||||
The operator `(table)/1` is used in directives that prepare
|
||||
predicates for tabled execution (SLG resolution).
|
||||
* [`format`](src/prolog/lib/format.pl)
|
||||
* [`format`](src/lib/format.pl)
|
||||
The nonterminal `format_//2` is used to describe formatted output,
|
||||
arranging arguments according to a given format string.
|
||||
The predicates `format/[2,3]`, `portray_clause/1` and `listing/1`
|
||||
The predicates `format/[2,3]`, `portray_clause/[1,2]` and `listing/1`
|
||||
provide formatted *impure* output.
|
||||
* [`assoc`](src/prolog/lib/assoc.pl)
|
||||
* [`assoc`](src/lib/assoc.pl)
|
||||
providing `empty_assoc/1`, `get_assoc/3`, `put_assoc/4` etc.
|
||||
to manage elements in AVL trees which ensure
|
||||
*O*(log(*N*)) access.
|
||||
* [`ordsets`](src/prolog/lib/ordsets.pl)
|
||||
* [`ordsets`](src/lib/ordsets.pl)
|
||||
represents ordered sets as lists.
|
||||
* [`clpb`](src/prolog/lib/clpb.pl)
|
||||
* [`clpb`](src/lib/clpb.pl)
|
||||
CLP(B): Constraint Logic Programming over Boolean variables,
|
||||
a BDD-based SAT solver provided via the predicates
|
||||
`sat/1`, `taut/2`, `labeling/1` etc.
|
||||
* [`arithmetic`](src/prolog/lib/arithmetic.pl)
|
||||
* [`arithmetic`](src/lib/arithmetic.pl)
|
||||
Arithmetic predicates such as `lsb/2`, `msb/2` and
|
||||
`number_to_rational/2`.
|
||||
* [`time`](src/prolog/lib/time.pl)
|
||||
`time/1` reports the CPU time of a goal. It is useful
|
||||
for measuring the performance of your code.
|
||||
* [`cont`](src/prolog/lib/cont.pl)
|
||||
* [`time`](src/lib/time.pl) Predicates for reasoning about
|
||||
time, including `time/1` to measure the CPU time of a goal,
|
||||
`current_time/1` to obtain the current system time, the nonterminal
|
||||
`format_time//2` to describe strings with dates and times, and
|
||||
`sleep/1` to slow down a computation.
|
||||
* [`files`](src/lib/files.pl)
|
||||
Predicates for reasoning about files and directories, such as
|
||||
`directory_files/2`, `file_exists/1` and `file_size/2`.
|
||||
* [`cont`](src/lib/cont.pl)
|
||||
Provides *delimited continuations* via `reset/3` and `shift/1`.
|
||||
* [`random`](src/prolog/lib/random.pl)
|
||||
* [`random`](src/lib/random.pl)
|
||||
Probabilistic predicates and random number generators.
|
||||
* [`sockets`](src/prolog/lib/sockets.pl)
|
||||
* [`http/http_open`](src/lib/http/http_open.pl) Open a stream to
|
||||
read answers from web servers. HTTPS is also supported.
|
||||
* [`sgml`](src/lib/sgml.pl)
|
||||
`load_html/3` and `load_xml/3` represent HTML and XML documents
|
||||
as Prolog terms for convenient and efficient reasoning. Use
|
||||
[`library(xpath)`](src/lib/iso_ext.pl) to extract information from
|
||||
parsed documents.
|
||||
* [`csv`](src/lib/csv.pl)
|
||||
`parse_csv//1` and `parse_csv//2` can be used with [`phrase_from_file/2`](src/lib/pio.pl)
|
||||
or [`phrase/2`](src/lib/dcgs.pl) to parse csv
|
||||
* [`xpath`](src/lib/xpath.pl)
|
||||
The predicate `xpath/3` is used for convenient reasoning about HTML
|
||||
and XML documents, inspired by the XPath language. This library
|
||||
is often used together with [`library(sgml)`](src/lib/sgml.pl).
|
||||
* [`sockets`](src/lib/sockets.pl)
|
||||
Predicates for opening and accepting TCP connections as streams.
|
||||
* [`crypto`](src/prolog/lib/crypto.pl)
|
||||
Cryptographically secure random numbers and hashes, HMAC-based
|
||||
key derivation (HKDF), password-based key derivation (PBKDF2),
|
||||
public key signatures and signature verification with Ed25519,
|
||||
authenticated encryption, and reasoning about elliptic curves.
|
||||
|
||||
To read contents of external files, use `phrase_from_file/2` from
|
||||
[`library(pio)`](src/prolog/lib/pio.pl) to apply a DCG to
|
||||
file contents. The predicates in
|
||||
[`library(charsio)`](src/prolog/lib/charsio.pl) are also useful for
|
||||
parsing.
|
||||
TLS negotiation is performed via the option `tls(true)` in
|
||||
`socket_client_open/3`, yielding secure encrypted connections.
|
||||
* [`os`](src/lib/os.pl)
|
||||
Predicates for reasoning about environment variables.
|
||||
* [`iso_ext`](src/lib/iso_ext.pl)
|
||||
Conforming extensions to and candidates for inclusion in the Prolog
|
||||
ISO standard, such as `setup_call_cleanup/3` and
|
||||
`call_with_inference_limit/3`.
|
||||
* [`crypto`](src/lib/crypto.pl)
|
||||
Cryptographically secure random numbers and hashes, HMAC-based key
|
||||
derivation (HKDF), password-based key derivation (PBKDF2),
|
||||
public key signatures and signature verification with Ed25519,
|
||||
ECDH key exchange over Curve25519 (X25519), authenticated symmetric
|
||||
encryption with ChaCha20-Poly1305, and reasoning about elliptic curves.
|
||||
|
||||
To use predicates provided by the `lists` library, write:
|
||||
|
||||
@@ -462,3 +502,17 @@ local_member(X, Xs) :- member(X, Xs).
|
||||
|
||||
The user listing can also be terminated by placing `end_of_file.` at
|
||||
the end of the stream.
|
||||
|
||||
### Configuration file
|
||||
|
||||
At startup, Scryer Prolog consults the file `~/.scryerrc`, if the file
|
||||
exists. This file is useful to automatically load libraries and define
|
||||
predicates that you need often.
|
||||
|
||||
For example, a sensible starting point for `~/.scryerrc` is:
|
||||
|
||||
```
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(reif)).
|
||||
```
|
||||
|
||||
89
build.rs
89
build.rs
@@ -1,60 +1,55 @@
|
||||
extern crate indexmap;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use std::env;
|
||||
use std::fs::{File, copy, read_dir};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn main()
|
||||
{
|
||||
fn find_prolog_files(libraries: &mut File, prefix: &str, current_dir: &Path) {
|
||||
let entries = match current_dir.read_dir() {
|
||||
Ok(entries) => entries,
|
||||
Err(_) => return,
|
||||
};
|
||||
for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
|
||||
if entry.is_dir() {
|
||||
if let Some(file_name) = entry.file_name() {
|
||||
let new_prefix =
|
||||
prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||
find_prolog_files(libraries, &new_prefix, &entry);
|
||||
}
|
||||
} else if entry.is_file() {
|
||||
let ext = std::ffi::OsStr::new("pl");
|
||||
if entry.extension() == Some(ext) {
|
||||
let contain =
|
||||
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||
let name = entry.file_stem().unwrap().to_str().unwrap();
|
||||
let line = format!(
|
||||
" m.insert(\"{}\",\n{:?});\n",
|
||||
prefix.to_owned() + name,
|
||||
contain
|
||||
);
|
||||
|
||||
libraries.write_all(line.as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("libraries.rs");
|
||||
|
||||
let mut libraries = File::create(&dest_path).unwrap();
|
||||
let mut library_index = IndexSet::new();
|
||||
let lib_path = Path::new("src/lib");
|
||||
|
||||
let paths = read_dir("./src/prolog/lib").unwrap();
|
||||
|
||||
for item in paths {
|
||||
let item = item.unwrap().path();
|
||||
|
||||
if let Some(file_name) = item.file_name() {
|
||||
if let Some(ext) = item.extension() {
|
||||
if ext == "pl" {
|
||||
let file_stem = item.file_stem().unwrap();
|
||||
let file_str = file_stem.to_string_lossy().to_uppercase();
|
||||
let dest = Path::new(&out_dir).join(file_name);
|
||||
|
||||
match copy(&item, dest) {
|
||||
Ok(_) => {},
|
||||
Err(e) => panic!("die: {:?}", e)
|
||||
};
|
||||
|
||||
let include_line = format!("static {}: &str = include_str!(\"{}.pl\");\n",
|
||||
file_str, file_stem.to_string_lossy());
|
||||
|
||||
libraries.write_all(include_line.as_bytes()).unwrap();
|
||||
library_index.insert(file_stem.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libraries.write_all(b"\nref_thread_local! {
|
||||
libraries
|
||||
.write_all(
|
||||
b"ref_thread_local! {
|
||||
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
||||
let mut m = IndexMap::new();\n").unwrap();
|
||||
|
||||
for item in library_index {
|
||||
let line = format!("\n m.insert(\"{}\", {});", item, item.to_uppercase());
|
||||
libraries.write_all(line.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
libraries.write_all(b"\n\n m\n };
|
||||
}\n").unwrap();
|
||||
|
||||
libraries.write_all(b"\npub static PROJECT_DIR: &'static str = \"").unwrap();
|
||||
libraries.write_all(env::var("CARGO_MANIFEST_DIR").unwrap().as_bytes()).unwrap();
|
||||
libraries.write_all(b"\";\n").unwrap();
|
||||
let mut m = IndexMap::new();\n",
|
||||
)
|
||||
.unwrap();
|
||||
find_prolog_files(&mut libraries, "", &lib_path);
|
||||
libraries.write_all(b"\n m\n };\n}\n").unwrap();
|
||||
}
|
||||
|
||||
BIN
logo/scryer.png
Normal file
BIN
logo/scryer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
896
logo/scryer.svg
Normal file
896
logo/scryer.svg
Normal file
@@ -0,0 +1,896 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="300.000000pt" height="300.000000pt" viewBox="0 0 300.000000 300.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<path fill="#57d3de" d="M0 0 h 300 v 300 h -300 z"/>
|
||||
<g transform="translate(0.000000,300.000000) scale(0.100000,-0.100000)"
|
||||
fill="#800080" stroke="none">
|
||||
<path d="M2388 2423 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M2436 2422 c-3 -5 8 -6 25 -4 16 2 29 6 29 8 0 8 -49 4 -54 -4z"/>
|
||||
<path d="M2310 2416 c0 -10 28 -13 41 -5 10 6 7 9 -13 9 -16 0 -28 -2 -28 -4z"/>
|
||||
<path d="M2501 2415 c3 -2 23 -7 45 -9 86 -10 151 -37 181 -75 8 -10 12 -11
|
||||
13 -4 0 19 -81 69 -130 80 -50 11 -117 16 -109 8z"/>
|
||||
<path d="M2055 2373 c-60 -13 -126 -27 -145 -30 -19 -3 -38 -11 -42 -17 -6 -8
|
||||
-10 -7 -17 2 -7 11 -19 12 -62 3 -30 -6 -82 -12 -116 -14 -46 -1 -63 -6 -66
|
||||
-18 -5 -20 -107 -27 -107 -7 0 9 -3 9 -12 0 -19 -19 -41 -15 -33 6 4 11 3 13
|
||||
-3 7 -6 -5 -12 -19 -14 -30 -2 -11 -9 -19 -16 -18 -6 2 -9 -4 -6 -12 5 -11 11
|
||||
-12 24 -5 30 16 34 11 9 -9 -13 -11 -27 -15 -30 -10 -9 16 -39 -2 -39 -23 0
|
||||
-11 -5 -29 -11 -40 -14 -26 2 -37 45 -32 23 4 27 2 16 -5 -13 -9 -13 -11 3
|
||||
-12 26 -2 31 -4 44 -12 9 -6 11 -3 7 10 -5 17 -4 16 10 -1 8 -10 17 -23 18
|
||||
-28 2 -5 19 -1 39 9 22 11 34 23 31 32 -2 8 0 11 6 7 11 -6 22 16 22 42 -1 11
|
||||
-6 8 -16 -10 -8 -16 -19 -28 -24 -28 -6 0 -10 -7 -10 -15 0 -8 -4 -15 -9 -15
|
||||
-5 0 -16 -3 -25 -6 -11 -4 -16 -1 -16 10 0 16 -10 20 -42 17 -10 -1 -18 3 -18
|
||||
8 0 6 -9 11 -19 11 -47 0 -36 35 23 73 51 32 63 33 94 7 19 -16 21 -23 12 -40
|
||||
-11 -20 -21 -27 -19 -12 4 27 -2 44 -13 35 -7 -5 -26 -10 -43 -11 -64 -4 -47
|
||||
-40 25 -49 95 -13 99 89 4 107 -37 7 -37 8 -8 9 30 1 88 -21 80 -30 -2 -2 2
|
||||
-9 9 -16 10 -9 17 -7 31 9 16 18 17 21 2 15 -9 -3 -18 0 -21 6 -4 12 18 17 78
|
||||
17 20 0 38 10 57 30 15 18 33 28 41 24 8 -3 18 -1 21 5 4 6 16 6 36 -1 23 -7
|
||||
34 -7 45 2 10 8 15 9 15 2 0 -18 -34 -31 -53 -21 -11 7 -23 6 -34 -1 -17 -11
|
||||
-17 -11 0 -6 10 3 28 1 39 -5 16 -8 24 -7 41 8 12 11 29 19 37 18 8 0 22 7 31
|
||||
17 9 10 18 16 20 14 2 -2 23 -1 47 4 25 4 42 4 42 -2 0 -10 42 0 50 12 3 4 25
|
||||
15 50 23 67 24 14 19 -115 -10z m-415 -83 c0 -5 -4 -10 -10 -10 -5 0 -10 5
|
||||
-10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m82 3 c-6 -3 -9 -9 -6 -15 4 -6 1 -9
|
||||
-6 -6 -23 7 -21 24 2 25 13 0 17 -1 10 -4z"/>
|
||||
<path d="M2220 2395 c0 -7 30 -13 34 -7 3 4 -4 9 -15 9 -10 1 -19 0 -19 -2z"/>
|
||||
<path d="M2136 2328 l-21 -17 27 -1 c20 0 26 4 22 15 -5 11 0 15 17 14 13 0
|
||||
18 -3 11 -6 -19 -7 -4 -23 16 -16 15 5 15 4 2 -10 -8 -9 -26 -18 -40 -21 -14
|
||||
-2 -34 -8 -44 -12 -14 -5 -17 -4 -12 4 4 7 3 12 -2 12 -6 0 -12 -6 -15 -14 -4
|
||||
-11 -67 -30 -92 -27 -2 0 -23 -6 -46 -14 -49 -18 -62 -19 -54 -5 4 6 10 8 15
|
||||
5 4 -3 13 2 20 10 21 25 -6 17 -39 -11 -31 -26 -61 -27 -61 -1 0 7 5 18 12 25
|
||||
8 8 8 12 1 12 -6 0 -13 -7 -17 -15 -3 -8 -17 -15 -31 -15 -24 0 -30 9 -26 38
|
||||
1 6 -5 12 -14 12 -18 0 -19 -12 -3 -28 9 -9 8 -12 -7 -12 -10 0 -15 -3 -12 -7
|
||||
4 -3 1 -13 -5 -22 -9 -11 -5 -10 9 2 20 17 50 16 39 -2 -3 -4 5 -8 16 -8 26
|
||||
-2 30 -7 23 -26 -7 -16 -44 -29 -67 -24 -7 2 -10 2 -5 0 17 -10 5 -22 -20 -19
|
||||
-16 2 -22 1 -15 -1 7 -3 10 -9 7 -14 -4 -5 5 -8 19 -7 15 1 26 6 26 11 0 4 5
|
||||
5 10 2 6 -3 10 -2 10 3 0 13 70 49 110 57 19 4 78 19 130 35 52 15 114 33 137
|
||||
39 24 6 47 21 53 31 6 11 25 26 43 33 30 13 29 13 -37 13 -51 0 -74 -4 -90
|
||||
-18z"/>
|
||||
<path d="M2374 2341 c3 -5 15 -7 26 -4 28 7 25 13 -6 13 -14 0 -23 -4 -20 -9z"/>
|
||||
<path d="M1445 2329 c-194 -16 -394 -99 -536 -222 -14 -12 -72 -58 -129 -102
|
||||
-136 -106 -198 -162 -206 -189 -3 -11 -16 -32 -29 -46 -12 -14 -35 -47 -50
|
||||
-75 -15 -27 -32 -57 -39 -65 -10 -13 -9 -13 6 -1 26 20 22 5 -11 -37 -15 -20
|
||||
-42 -75 -58 -122 -17 -47 -38 -102 -47 -123 -9 -22 -12 -36 -7 -33 6 4 2 -13
|
||||
-9 -36 -26 -56 -25 -77 1 -44 11 14 17 30 14 36 -3 5 -1 10 4 10 6 0 11 -8 11
|
||||
-17 0 -15 2 -15 14 2 9 13 11 27 6 41 -11 29 -8 49 13 72 10 11 17 23 16 28
|
||||
-3 20 2 35 10 30 11 -7 23 22 15 35 -10 16 6 31 21 19 9 -8 15 -8 20 0 3 5 1
|
||||
10 -6 10 -8 0 -8 4 1 15 7 8 17 12 24 8 7 -4 6 -1 -1 9 -7 8 -10 18 -6 21 3 4
|
||||
4 7 0 7 -3 0 -13 -7 -21 -16 -17 -16 -36 -11 -36 9 0 8 3 7 9 -2 7 -11 11 -8
|
||||
16 10 4 13 16 30 27 37 10 8 15 19 11 25 -4 7 0 6 10 -2 9 -7 17 -12 18 -10 0
|
||||
2 2 19 4 37 2 19 12 40 22 48 22 16 10 18 -20 2 -12 -6 1 12 30 40 28 29 56
|
||||
52 62 52 13 0 15 27 2 34 -5 3 -8 -2 -7 -11 0 -9 -5 -18 -12 -20 -8 -3 -10 1
|
||||
-5 14 10 28 25 44 50 54 13 5 22 14 21 21 -2 6 6 14 17 16 11 2 25 9 30 14 7
|
||||
8 5 9 -5 4 -8 -4 -4 2 10 13 14 12 35 24 47 27 12 3 29 17 38 31 9 14 23 22
|
||||
30 19 9 -3 12 0 8 9 -3 9 3 18 13 21 11 4 33 17 51 30 34 26 123 43 123 24 0
|
||||
-6 5 -8 12 -4 11 7 26 10 83 18 11 2 24 -2 28 -8 6 -7 7 -6 5 4 -3 8 -15 17
|
||||
-28 20 -20 5 -21 7 -7 18 10 8 17 9 21 3 5 -7 14 -7 29 0 24 11 54 49 38 49
|
||||
-5 0 -11 -5 -13 -11 -2 -6 -23 -11 -46 -11 -23 0 -42 -4 -42 -9 0 -6 -3 -8 -7
|
||||
-6 -5 3 -14 -1 -21 -9 -11 -12 -10 -14 5 -14 16 0 16 -2 2 -15 -17 -17 -53
|
||||
-10 -42 8 4 6 1 7 -7 2 -7 -4 -28 -11 -47 -15 -29 -7 -32 -6 -22 6 7 8 14 12
|
||||
16 10 3 -3 15 7 28 22 20 24 24 25 41 12 10 -8 15 -10 11 -4 -11 19 21 51 60
|
||||
59 21 5 44 9 50 11 7 1 20 9 29 18 17 18 28 21 19 6 -3 -5 3 -10 14 -10 11 0
|
||||
23 5 26 11 4 5 18 14 32 20 13 5 22 13 19 18 -8 12 155 35 203 29 20 -3 47 -2
|
||||
61 2 39 10 -49 16 -135 9z m-940 -679 c3 -5 -1 -10 -10 -10 -9 0 -13 5 -10 10
|
||||
3 6 8 10 10 10 2 0 7 -4 10 -10z"/>
|
||||
<path d="M2490 2321 c-7 -11 -24 -21 -37 -24 -27 -5 -32 9 -5 16 15 4 15 5 -1
|
||||
6 -11 1 -21 -8 -24 -20 -5 -16 -11 -19 -30 -14 -19 4 -23 3 -17 -7 6 -10 5
|
||||
-11 -7 -1 -12 10 -19 8 -33 -8 -11 -13 -25 -19 -37 -16 -11 3 -32 -1 -47 -8
|
||||
-43 -21 -75 -29 -68 -17 4 6 -13 0 -37 -14 -25 -13 -63 -25 -86 -27 -22 -1
|
||||
-41 -5 -41 -9 0 -5 -9 -8 -20 -8 -52 0 -250 -68 -250 -86 0 -3 5 -2 10 1 6 3
|
||||
10 2 10 -4 0 -5 -4 -13 -10 -16 -5 -3 -10 -12 -9 -18 0 -9 2 -9 6 1 2 6 13 12
|
||||
23 12 10 0 22 5 25 10 4 6 11 8 16 5 5 -4 9 -1 9 4 0 6 3 10 8 10 4 -1 26 1
|
||||
49 6 32 6 40 11 36 23 -4 10 -2 13 5 8 7 -4 12 -3 12 2 0 5 6 9 13 9 38 1 102
|
||||
15 115 25 13 11 15 10 9 -4 -4 -12 -2 -15 8 -11 8 3 13 8 11 12 -2 3 9 7 25 8
|
||||
15 1 42 9 59 18 17 9 52 20 78 26 26 5 64 14 84 18 21 5 43 13 50 19 7 6 42
|
||||
15 78 22 36 6 79 16 96 21 41 12 94 11 94 -2 0 -6 -7 -17 -15 -25 -8 -9 -15
|
||||
-11 -15 -5 0 6 -7 8 -15 5 -9 -4 -15 0 -15 10 0 9 -5 16 -11 16 -7 0 -10 -12
|
||||
-7 -30 5 -34 -11 -45 -30 -21 -11 13 -13 13 -9 1 4 -15 -24 -41 -55 -53 -11
|
||||
-4 -21 0 -27 11 -10 16 -10 16 -11 0 0 -18 7 -21 43 -21 13 0 15 -3 6 -13 -14
|
||||
-16 -39 -19 -39 -3 0 5 -5 7 -11 3 -8 -4 -7 -9 2 -15 12 -8 11 -11 -1 -19 -8
|
||||
-5 -20 -10 -27 -10 -6 0 -14 -6 -17 -12 -5 -10 -7 -10 -12 0 -8 18 -24 15 -24
|
||||
-5 0 -9 -3 -14 -6 -10 -4 3 -22 -5 -41 -18 -20 -13 -44 -22 -54 -20 -11 2 -17
|
||||
0 -15 -4 3 -4 -14 -19 -37 -32 -23 -13 -54 -30 -69 -39 -103 -58 -157 -92
|
||||
-170 -107 -8 -10 -25 -45 -37 -78 -12 -33 -33 -74 -47 -92 -14 -18 -22 -33
|
||||
-18 -33 4 0 -1 -10 -12 -22 -17 -19 -56 -132 -69 -200 -2 -9 -8 -25 -13 -35
|
||||
-12 -21 -12 -22 -12 -70 0 -28 -3 -34 -10 -23 -8 12 -10 9 -10 -12 0 -14 -3
|
||||
-34 -7 -44 -5 -13 -3 -16 10 -11 14 5 17 0 17 -28 0 -18 5 -37 10 -40 16 -10
|
||||
12 -25 -7 -25 -11 0 -14 3 -7 8 8 5 6 12 -5 24 -15 15 -16 14 -15 -19 1 -19
|
||||
-2 -49 -7 -66 -5 -17 -5 -35 -1 -39 5 -5 14 9 21 31 15 53 31 61 25 14 -3 -21
|
||||
-6 -57 -8 -81 -1 -23 -8 -48 -15 -55 -10 -10 -12 -8 -9 8 4 24 -33 29 -39 5
|
||||
-4 -13 -3 -13 6 0 15 22 23 7 31 -57 6 -44 8 -50 9 -23 2 28 4 31 10 15 5 -11
|
||||
6 -25 4 -31 -2 -7 0 -29 6 -50 5 -22 13 -59 16 -83 3 -23 11 -54 16 -68 17
|
||||
-45 20 -104 7 -121 -7 -9 -8 -13 -2 -9 7 4 12 -2 12 -18 0 -14 -4 -22 -9 -19
|
||||
-5 2 -2 -11 6 -30 8 -20 15 -46 15 -59 0 -14 13 -35 30 -50 22 -20 30 -23 30
|
||||
-12 0 9 -10 20 -22 26 -18 8 -24 20 -26 51 -3 42 -3 42 18 23 20 -19 21 -19
|
||||
13 1 -4 10 -12 25 -19 31 -7 8 -10 28 -7 52 4 25 -6 84 -26 169 -27 110 -31
|
||||
147 -29 234 1 57 1 172 -1 256 -2 110 1 157 10 168 6 8 10 17 7 20 -3 3 3 37
|
||||
13 75 17 63 51 142 110 249 10 19 29 57 41 84 21 44 33 55 124 110 56 34 144
|
||||
81 195 105 127 59 148 70 219 116 34 22 99 64 146 94 46 29 84 57 84 63 0 5
|
||||
-5 6 -10 3 -6 -4 -26 -1 -45 5 -19 6 -67 12 -107 13 -40 1 -75 5 -78 9 -3 4
|
||||
-12 -1 -20 -11z m-697 -236 c-3 -9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13
|
||||
8 -4z"/>
|
||||
<path d="M2025 2320 c-17 -7 -15 -9 13 -9 17 -1 32 4 32 9 0 12 -17 12 -45 0z"/>
|
||||
<path d="M1910 2280 c-20 -12 -10 -19 14 -10 11 3 15 9 10 13 -6 3 -16 2 -24
|
||||
-3z"/>
|
||||
<path d="M1980 2274 c-29 -16 -8 -19 22 -3 16 8 23 8 30 -2 8 -11 9 -11 5 1
|
||||
-5 20 -26 21 -57 4z"/>
|
||||
<path d="M2065 2280 c-3 -5 1 -10 9 -10 9 0 16 5 16 10 0 6 -4 10 -9 10 -6 0
|
||||
-13 -4 -16 -10z"/>
|
||||
<path d="M1806 2271 c-12 -5 -15 -10 -9 -14 6 -4 16 0 23 8 14 17 13 17 -14 6z"/>
|
||||
<path d="M1340 2245 c-14 -8 -37 -14 -51 -15 -14 0 -34 -9 -44 -20 -18 -20
|
||||
-18 -21 -1 -38 14 -14 16 -14 11 -1 -7 19 20 44 57 53 14 3 34 9 44 13 12 4
|
||||
15 3 10 -5 -4 -7 -3 -12 3 -12 6 0 15 9 21 20 9 17 8 20 -7 20 -10 -1 -29 -7
|
||||
-43 -15z"/>
|
||||
<path d="M1190 2209 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1140 2199 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1330 2201 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5
|
||||
3 -10 2 -10 -4z"/>
|
||||
<path d="M1786 2184 c-11 -8 -16 -14 -10 -14 13 0 39 18 34 24 -3 2 -14 -2
|
||||
-24 -10z"/>
|
||||
<path d="M1294 2168 c6 -37 -36 -64 -48 -31 -3 8 -10 11 -16 8 -5 -3 -10 -1
|
||||
-10 6 0 7 -3 9 -6 6 -4 -4 -1 -13 5 -21 7 -8 11 -19 8 -23 -3 -4 16 -8 41 -8
|
||||
34 0 46 -4 44 -13 -1 -8 2 -11 8 -7 6 3 8 11 4 16 -3 6 2 17 12 25 18 14 18
|
||||
14 -3 5 -29 -15 -32 -14 -26 8 3 11 0 28 -6 38 -10 15 -10 14 -7 -9z"/>
|
||||
<path d="M2355 2150 c-3 -5 -3 -10 2 -10 4 -1 -3 -7 -16 -14 -14 -8 -31 -12
|
||||
-38 -9 -8 3 -13 0 -11 -8 2 -7 -9 -15 -27 -19 -25 -5 -27 -7 -11 -13 11 -5 25
|
||||
-2 35 6 26 22 87 47 115 47 14 0 26 4 26 10 0 6 -15 8 -36 4 -25 -4 -34 -2
|
||||
-29 5 3 6 4 11 1 11 -3 0 -8 -4 -11 -10z"/>
|
||||
<path d="M2135 2140 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M1676 2107 c-11 -8 -17 -18 -15 -23 2 -5 14 1 26 14 24 24 17 30 -11
|
||||
9z"/>
|
||||
<path d="M2025 2109 c-5 -7 -3 -10 6 -7 8 3 22 1 32 -4 11 -5 17 -5 17 2 0 5
|
||||
-4 10 -9 10 -5 0 -16 3 -24 6 -8 3 -18 0 -22 -7z"/>
|
||||
<path d="M2250 2109 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M2200 2099 c0 -5 -5 -7 -12 -3 -6 4 -8 3 -4 -4 3 -6 2 -13 -4 -17 -5
|
||||
-3 -10 -2 -10 3 0 6 -9 8 -20 5 -11 -3 -20 -9 -20 -14 0 -5 -7 -5 -17 -2 -10
|
||||
4 -14 2 -9 -5 9 -15 -13 -27 -27 -13 -13 13 -41 15 -33 3 11 -19 -15 -37 -55
|
||||
-37 -29 0 -44 -5 -46 -15 -4 -13 -3 -13 6 0 9 13 11 13 11 1 0 -12 3 -12 12
|
||||
-3 14 14 42 16 33 2 -7 -11 23 -3 41 11 6 5 15 5 19 1 5 -4 5 2 1 12 -6 16 -4
|
||||
17 10 6 13 -12 17 -11 24 0 5 8 12 11 16 7 4 -4 17 -1 28 6 12 7 35 12 52 12
|
||||
30 -1 31 0 22 27 -10 29 -18 36 -18 17z"/>
|
||||
<path d="M1967 2093 c-12 -12 -7 -22 8 -17 8 4 15 10 15 15 0 11 -14 12 -23 2z"/>
|
||||
<path d="M1367 2084 c-4 -4 -7 -17 -7 -28 1 -19 1 -20 11 -3 11 19 8 43 -4 31z"/>
|
||||
<path d="M1198 2073 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M1326 2065 c-3 -8 -1 -15 4 -15 13 0 22 18 11 24 -5 3 -11 -1 -15 -9z"/>
|
||||
<path d="M2000 2069 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1065 2055 c-27 -8 -51 -19 -53 -25 -2 -5 -8 -8 -13 -4 -5 3 -14 2
|
||||
-21 -2 -8 -5 -6 -10 8 -15 12 -4 26 -1 36 8 9 9 37 18 61 20 28 3 44 10 44 19
|
||||
0 16 3 16 -62 -1z"/>
|
||||
<path d="M1155 2049 c-23 -9 -21 -10 20 -14 146 -13 178 -14 145 -5 -19 5 -57
|
||||
12 -85 16 -27 3 -52 8 -55 9 -3 1 -14 -1 -25 -6z"/>
|
||||
<path d="M1675 2050 c4 -6 1 -17 -5 -26 -11 -12 -9 -14 11 -10 13 2 32 -1 42
|
||||
-6 13 -6 17 -5 17 7 0 9 -8 18 -17 21 -10 3 -26 10 -37 15 -13 8 -16 7 -11 -1z"/>
|
||||
<path d="M1800 2046 c0 -2 7 -6 15 -10 8 -3 15 -1 15 4 0 6 -7 10 -15 10 -8 0
|
||||
-15 -2 -15 -4z"/>
|
||||
<path d="M903 2029 c3 -9 0 -22 -6 -29 -16 -16 43 10 61 27 11 11 11 13 0 13
|
||||
-8 0 -20 -6 -26 -12 -10 -10 -15 -10 -23 2 -9 13 -10 13 -6 -1z"/>
|
||||
<path d="M1860 2030 c0 -13 11 -13 30 0 12 8 11 10 -7 10 -13 0 -23 -4 -23
|
||||
-10z"/>
|
||||
<path d="M1780 2017 c0 -10 -6 -14 -14 -11 -7 3 -16 -1 -19 -8 -3 -9 2 -14 14
|
||||
-14 19 0 37 32 25 43 -3 4 -6 -1 -6 -10z"/>
|
||||
<path d="M1105 2010 c-3 -5 1 -10 9 -10 9 0 16 5 16 10 0 6 -4 10 -9 10 -6 0
|
||||
-13 -4 -16 -10z"/>
|
||||
<path d="M1160 2005 c0 -17 7 -21 40 -22 22 -1 41 1 44 5 2 4 -12 8 -32 9 -19
|
||||
1 -39 8 -43 15 -6 9 -9 7 -9 -7z"/>
|
||||
<path d="M1896 2008 c3 -5 10 -6 15 -3 13 9 11 12 -6 12 -8 0 -12 -4 -9 -9z"/>
|
||||
<path d="M1020 1990 c-11 -11 -22 -20 -25 -19 -3 0 -11 -2 -18 -4 -6 -3 -2 -6
|
||||
10 -6 12 -1 28 6 36 14 9 8 17 11 20 7 2 -4 2 -1 1 6 -3 8 5 11 24 7 22 -4 24
|
||||
-4 7 4 -29 14 -33 13 -55 -9z"/>
|
||||
<path d="M1558 1993 c11 -19 9 -24 -9 -33 -11 -7 -27 -9 -35 -6 -8 3 -13 2 -9
|
||||
-3 8 -14 -17 -19 -43 -9 -17 6 -23 5 -20 -4 9 -26 68 -20 117 11 26 17 50 31
|
||||
54 31 3 0 5 -12 4 -27 -2 -18 -11 -32 -26 -39 -39 -20 -41 -29 -6 -29 18 0 31
|
||||
3 28 8 -2 4 7 7 21 7 16 0 26 6 26 14 0 8 6 17 13 19 6 3 0 6 -15 6 -33 1 -43
|
||||
15 -22 32 14 11 18 11 28 -1 6 -8 22 -15 36 -16 14 -1 34 -4 45 -8 19 -8 19
|
||||
-7 -1 11 -12 10 -24 26 -27 36 -4 10 -12 15 -18 11 -8 -4 -7 -9 2 -15 11 -6
|
||||
10 -9 -3 -14 -9 -4 -27 0 -40 8 -13 8 -36 13 -53 11 -16 -1 -36 2 -44 9 -12
|
||||
10 -13 9 -3 -10z"/>
|
||||
<path d="M1501 1989 c-14 -5 -36 -9 -50 -8 -44 3 -71 -1 -71 -10 0 -6 12 -6
|
||||
29 -1 16 4 32 6 35 3 8 -9 96 7 96 18 0 11 -8 11 -39 -2z"/>
|
||||
<path d="M815 1980 c-3 -6 1 -7 9 -4 18 7 21 14 7 14 -6 0 -13 -4 -16 -10z"/>
|
||||
<path d="M866 1972 c-4 -10 -13 -19 -21 -20 -8 -1 -22 -3 -30 -4 -8 -1 -12 -4
|
||||
-10 -8 2 -4 18 -5 35 -2 18 2 30 0 30 -7 0 -6 -9 -11 -20 -11 -11 0 -20 -5
|
||||
-20 -11 0 -7 8 -9 23 -4 12 4 46 9 75 12 29 3 55 10 59 16 4 6 -7 7 -31 3 -24
|
||||
-5 -36 -3 -36 4 0 6 5 8 10 5 6 -3 10 -1 10 4 0 15 -11 13 -34 -4 -25 -19 -38
|
||||
-10 -30 21 7 28 -2 33 -10 6z"/>
|
||||
<path d="M1300 1980 c-12 -8 -9 -10 13 -10 15 0 27 5 27 10 0 13 -20 13 -40 0z"/>
|
||||
<path d="M1803 1980 c2 -8 10 -14 17 -12 7 1 20 -3 29 -10 9 -7 13 -8 9 -4 -4
|
||||
5 -2 16 5 24 10 13 9 14 -3 7 -20 -12 -43 -12 -53 0 -5 6 -7 4 -4 -5z"/>
|
||||
<path d="M1160 1948 c0 -4 4 -8 9 -8 6 0 12 4 15 8 3 5 -1 9 -9 9 -8 0 -15 -4
|
||||
-15 -9z"/>
|
||||
<path d="M988 1918 c-21 -21 -11 -24 15 -4 10 8 15 16 10 18 -4 3 -16 -3 -25
|
||||
-14z"/>
|
||||
<path d="M1080 1927 c0 -11 -50 -27 -125 -42 -27 -6 -135 -58 -135 -67 0 -10
|
||||
44 3 55 16 13 16 57 32 125 46 30 7 64 17 75 23 28 15 88 20 80 7 -4 -6 6 -10
|
||||
24 -10 16 0 33 5 36 10 4 7 -3 9 -22 5 -21 -5 -24 -4 -13 4 12 9 9 11 -15 12
|
||||
-16 1 -42 3 -57 5 -17 2 -28 -2 -28 -9z"/>
|
||||
<path d="M735 1910 c-26 -28 -15 -31 12 -3 12 13 19 23 14 23 -4 0 -16 -9 -26
|
||||
-20z"/>
|
||||
<path d="M1667 1894 c-28 -15 -36 -26 -14 -21 7 1 11 -7 10 -18 -1 -11 3 -23
|
||||
9 -26 21 -13 -4 -30 -34 -24 -21 5 -28 4 -24 -4 4 -6 12 -9 17 -6 5 4 9 1 9
|
||||
-4 0 -16 16 -13 34 4 8 8 21 15 28 15 9 1 8 4 -3 10 -17 10 -15 59 4 71 21 14
|
||||
-10 16 -36 3z"/>
|
||||
<path d="M1430 1885 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M1485 1890 c-3 -5 3 -10 15 -10 12 0 18 5 15 10 -3 6 -10 10 -15 10
|
||||
-5 0 -12 -4 -15 -10z"/>
|
||||
<path d="M1255 1880 c3 -5 10 -10 16 -10 5 0 9 5 9 10 0 6 -7 10 -16 10 -8 0
|
||||
-12 -4 -9 -10z"/>
|
||||
<path d="M1720 1880 c-12 -8 -10 -10 8 -10 13 0 20 4 17 10 -7 12 -6 12 -25 0z"/>
|
||||
<path d="M685 1870 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M844 1864 c4 -11 1 -14 -12 -10 -13 4 -32 -7 -62 -34 -24 -22 -41
|
||||
-43 -38 -46 3 -3 25 13 48 36 22 22 46 38 51 34 13 -7 41 15 33 27 -9 15 -26
|
||||
10 -20 -7z"/>
|
||||
<path d="M1088 1866 c-26 -20 -22 -26 12 -16 19 6 32 5 36 -2 4 -7 2 -8 -4 -4
|
||||
-7 4 -12 2 -12 -3 0 -16 26 -13 40 4 15 19 13 21 -25 29 -18 3 -37 0 -47 -8z"/>
|
||||
<path d="M1525 1870 c-3 -5 1 -10 10 -10 8 0 24 -6 35 -12 15 -10 22 -10 32 0
|
||||
9 9 8 12 -5 12 -25 0 -30 1 -49 11 -10 6 -19 5 -23 -1z"/>
|
||||
<path d="M1315 1849 c-17 -17 -17 -19 -2 -14 20 8 23 -5 5 -23 -21 -21 8 -14
|
||||
33 8 13 11 20 20 14 19 -24 -3 -34 2 -29 16 8 20 3 18 -21 -6z"/>
|
||||
<path d="M1030 1851 c0 -8 -8 -11 -20 -8 -11 3 -20 1 -20 -4 0 -5 -3 -8 -7 -7
|
||||
-5 2 -19 -5 -33 -15 -30 -21 -22 -22 15 -3 15 8 33 12 40 10 14 -6 41 23 31
|
||||
33 -3 3 -6 1 -6 -6z"/>
|
||||
<path d="M1477 1842 c5 -12 1 -14 -20 -8 -14 3 -29 2 -32 -4 -3 -5 -14 -10
|
||||
-24 -10 -10 0 -25 -8 -32 -17 -13 -16 -12 -17 3 -4 10 7 38 14 62 16 24 2 49
|
||||
6 55 9 16 10 14 1 -9 -36 -11 -18 -20 -29 -20 -24 0 5 -6 4 -12 -1 -7 -6 -23
|
||||
-13 -35 -16 -18 -4 -23 -1 -23 15 0 10 -5 16 -10 13 -6 -4 -8 -10 -5 -15 3 -4
|
||||
-6 -10 -18 -14 -13 -3 -36 -17 -52 -30 -16 -14 -31 -24 -34 -24 -10 2 -81 -32
|
||||
-81 -38 0 -3 12 -3 26 0 17 5 23 3 19 -4 -3 -5 -2 -10 4 -10 6 0 15 -15 20
|
||||
-32 9 -30 10 -31 16 -11 7 22 31 37 45 28 4 -3 10 2 14 10 3 8 13 15 23 15 14
|
||||
0 15 2 4 9 -11 7 -6 13 18 26 22 11 31 21 27 31 -3 9 -2 12 5 9 5 -4 27 6 47
|
||||
22 20 15 38 26 39 23 2 -3 10 6 20 19 12 18 13 26 5 29 -7 2 -10 7 -8 11 2 3
|
||||
-6 11 -19 17 -19 10 -22 9 -18 -4z m-87 -111 c0 -13 -82 -77 -107 -83 -13 -4
|
||||
-23 -5 -23 -4 0 12 61 67 69 62 5 -4 15 3 21 14 11 20 40 28 40 11z"/>
|
||||
<path d="M930 1835 c-14 -8 -20 -14 -14 -15 5 0 19 7 30 15 24 18 16 19 -16 0z"/>
|
||||
<path d="M1220 1834 c0 -8 5 -12 10 -9 6 3 10 10 10 16 0 5 -4 9 -10 9 -5 0
|
||||
-10 -7 -10 -16z"/>
|
||||
<path d="M676 1809 c-21 -11 -41 -29 -43 -40 -3 -10 -9 -17 -12 -14 -4 2 -8
|
||||
-3 -8 -12 0 -10 12 -2 32 21 17 20 35 36 41 36 6 0 19 7 30 15 28 21 5 18 -40
|
||||
-6z"/>
|
||||
<path d="M1085 1817 c-22 -13 -31 -37 -15 -37 6 0 10 5 10 11 0 7 8 18 18 25
|
||||
21 17 14 17 -13 1z"/>
|
||||
<path d="M1233 1818 c-13 -6 -23 -15 -23 -20 0 -4 -4 -8 -10 -8 -5 0 -7 7 -4
|
||||
15 5 13 -13 15 -76 5 -3 0 1 -4 8 -9 12 -7 12 -12 1 -30 -8 -11 -18 -20 -24
|
||||
-19 -5 1 -28 -8 -50 -20 -26 -15 -31 -20 -15 -16 14 3 29 10 35 15 5 5 17 9
|
||||
27 9 9 0 21 6 25 14 9 16 43 24 58 14 6 -3 28 9 50 28 40 34 39 42 -2 22z"/>
|
||||
<path d="M1285 1810 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||
-7 -4 -4 -10z"/>
|
||||
<path d="M955 1774 c-71 -40 -62 -44 21 -9 32 13 53 24 46 25 -7 0 -10 5 -7
|
||||
10 8 12 11 14 -60 -26z"/>
|
||||
<path d="M804 1785 c-15 -11 -16 -14 -3 -15 8 0 24 7 35 15 15 11 16 14 3 15
|
||||
-8 0 -24 -7 -35 -15z"/>
|
||||
<path d="M1028 1779 c-14 -15 -15 -19 -4 -19 8 0 16 -6 19 -12 2 -7 4 2 5 20
|
||||
0 17 0 32 -1 31 -1 0 -10 -9 -19 -20z"/>
|
||||
<path d="M885 1780 c3 -6 -4 -14 -17 -19 -26 -10 -74 -56 -90 -86 -7 -12 5 -5
|
||||
30 18 23 20 52 37 65 38 13 0 16 3 8 6 -11 4 -9 10 9 23 20 15 20 18 6 23 -10
|
||||
4 -15 3 -11 -3z"/>
|
||||
<path d="M1270 1775 c-7 -8 -18 -15 -24 -14 -24 3 -36 -2 -61 -25 -18 -17 -22
|
||||
-26 -13 -29 7 -3 0 -6 -17 -6 -16 -1 -41 -4 -54 -8 -16 -4 -22 -3 -17 5 4 8
|
||||
-3 8 -26 1 -35 -10 -89 -59 -65 -59 8 0 22 10 31 23 10 14 14 16 10 5 -7 -20
|
||||
20 -26 31 -8 3 6 11 10 16 10 6 0 7 -5 3 -12 -5 -8 2 -9 26 -5 27 6 30 5 21
|
||||
-7 -6 -7 -39 -19 -74 -25 -98 -19 -136 -38 -108 -55 5 -3 20 3 34 14 26 21 57
|
||||
27 57 11 0 -10 -61 -41 -80 -41 -22 0 -80 -41 -80 -56 0 -12 4 -12 20 -2 11 7
|
||||
20 18 20 25 0 14 2 15 40 19 14 1 36 6 50 10 24 7 24 7 8 -13 -10 -11 -18 -22
|
||||
-18 -26 0 -3 8 -4 18 0 9 3 0 -11 -20 -33 -21 -22 -38 -45 -38 -52 0 -6 -9
|
||||
-16 -20 -22 -11 -6 -18 -15 -15 -21 4 -5 -1 -9 -9 -9 -8 0 -17 4 -21 10 -3 5
|
||||
-12 7 -20 3 -24 -9 -17 10 20 49 19 21 49 42 67 47 33 9 33 9 5 10 -19 1 -26
|
||||
5 -21 13 5 7 3 8 -5 4 -7 -5 -10 -10 -8 -13 3 -2 -13 -22 -36 -43 -22 -22 -41
|
||||
-50 -42 -62 -1 -13 -7 -22 -13 -21 -5 1 -15 -4 -21 -11 -10 -12 -6 -13 26 -5
|
||||
56 13 73 11 67 -6 -4 -8 1 -17 10 -21 29 -11 13 -89 -32 -151 -16 -23 -19 -31
|
||||
-8 -27 14 5 53 78 70 127 4 11 11 15 18 11 9 -5 8 -2 -1 10 -8 9 -10 16 -5 14
|
||||
5 -1 21 10 37 25 15 16 32 25 39 21 7 -4 8 -3 4 4 -4 7 -3 12 2 12 10 0 35 50
|
||||
28 57 -2 2 -7 -5 -11 -16 -3 -12 -19 -28 -34 -35 -15 -8 -33 -22 -40 -30 -19
|
||||
-23 -34 -20 -26 5 5 15 4 19 -4 15 -25 -16 -9 27 25 64 37 41 70 51 80 25 4
|
||||
-8 15 -15 26 -15 10 0 16 5 13 10 -4 6 -11 7 -17 4 -7 -4 -8 -2 -4 5 4 6 10 9
|
||||
14 7 4 -2 23 4 42 15 19 10 47 24 63 31 15 7 27 16 27 20 0 8 -66 -19 -90 -38
|
||||
-35 -26 -44 -28 -35 -8 4 10 7 27 7 37 0 9 3 15 9 12 5 -4 12 1 15 9 3 9 10
|
||||
16 16 16 5 0 6 -4 3 -10 -8 -13 -1 -13 40 4 18 8 39 24 45 36 l11 21 -41 -21
|
||||
c-57 -29 -73 -20 -25 13 24 16 33 27 23 27 -26 0 -68 -22 -68 -35 0 -7 -20
|
||||
-29 -45 -49 -25 -21 -45 -45 -46 -54 0 -13 -3 -11 -9 5 -10 24 1 76 21 99 7 8
|
||||
21 11 35 8 13 -3 24 -2 24 2 0 15 57 74 64 67 3 -3 6 0 6 8 0 19 23 69 32 69
|
||||
3 0 4 -9 1 -20 -3 -11 0 -20 6 -20 6 0 11 4 11 10 0 5 7 7 15 4 8 -4 15 -1 15
|
||||
5 0 6 6 11 13 11 6 0 21 8 32 16 20 15 19 16 -5 12 -16 -2 -24 2 -22 10 3 16
|
||||
-3 15 -18 -3z m-200 -89 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10
|
||||
11 6 0 10 -2 10 -4z m30 -186 c-6 -11 -18 -20 -27 -20 -14 0 -14 2 2 20 10 11
|
||||
22 20 27 20 5 0 4 -9 -2 -20z"/>
|
||||
<path d="M1542 1778 c-16 -16 -15 -25 3 -25 16 0 28 24 16 31 -4 3 -13 0 -19
|
||||
-6z"/>
|
||||
<path d="M683 1768 c-10 -18 -13 -39 -3 -33 8 5 21 45 15 45 -2 0 -7 -6 -12
|
||||
-12z"/>
|
||||
<path d="M950 1740 c-8 -5 -12 -11 -9 -14 2 -3 11 -1 19 4 8 5 12 11 9 14 -2
|
||||
3 -11 1 -19 -4z"/>
|
||||
<path d="M749 1713 l-24 -28 28 24 c25 23 32 31 24 31 -2 0 -14 -12 -28 -27z"/>
|
||||
<path d="M1656 1725 c-4 -13 -2 -14 14 -5 23 13 26 20 6 20 -8 0 -16 -7 -20
|
||||
-15z"/>
|
||||
<path d="M975 1715 c-16 -7 -34 -11 -39 -7 -5 3 -6 0 -2 -6 4 -6 -2 -17 -14
|
||||
-24 -11 -7 -20 -17 -20 -22 0 -5 11 1 25 14 14 13 28 20 32 15 5 -4 2 -10 -4
|
||||
-12 -7 -3 -13 -10 -13 -16 0 -6 10 -1 23 11 13 12 30 22 38 22 12 0 12 2 0 9
|
||||
-11 7 -11 9 0 13 8 3 12 7 9 10 -3 3 -18 -1 -35 -7z"/>
|
||||
<path d="M1485 1699 c-4 -17 -9 -28 -12 -25 -3 3 -17 -4 -31 -14 -27 -22 -54
|
||||
-28 -34 -8 7 7 12 16 12 21 0 5 -29 -20 -64 -56 -45 -45 -62 -58 -60 -43 2 12
|
||||
-5 2 -16 -21 -12 -26 -31 -46 -50 -55 -17 -7 -30 -18 -30 -23 0 -11 -69 -52
|
||||
-82 -48 -4 2 -5 -3 -2 -10 3 -8 0 -25 -5 -40 -7 -18 -7 -27 2 -30 7 -2 8 -8 4
|
||||
-13 -13 -13 -27 18 -21 46 5 22 3 22 -17 -8 -13 -19 -27 -31 -35 -28 -8 3 -14
|
||||
-1 -14 -9 0 -7 -6 -20 -13 -27 -27 -27 -67 -85 -67 -96 0 -7 5 -12 10 -12 6 0
|
||||
10 4 10 10 0 5 16 32 36 60 29 40 42 50 65 50 40 0 37 -23 -6 -49 -20 -11 -38
|
||||
-29 -42 -38 -3 -10 -15 -30 -25 -45 -16 -23 -17 -28 -4 -28 8 0 16 -8 19 -18
|
||||
2 -9 4 0 3 21 0 39 17 61 41 52 7 -2 10 2 7 9 -5 12 63 92 71 84 4 -4 12 -40
|
||||
14 -62 1 -4 7 -6 15 -3 24 9 39 -19 32 -58 -4 -19 -10 -35 -15 -35 -4 0 -8 -6
|
||||
-9 -12 -1 -7 -4 -26 -7 -43 -5 -27 -3 -26 14 10 11 22 20 48 20 59 1 14 4 16
|
||||
15 7 19 -16 5 -82 -29 -131 -16 -23 -32 -43 -37 -46 -4 -3 -8 -14 -8 -25 0
|
||||
-29 22 -18 31 15 8 29 36 66 50 66 15 0 15 -35 0 -53 -18 -22 -22 -118 -4
|
||||
-124 10 -4 10 37 -1 72 -2 6 1 19 6 30 8 18 8 18 4 -2 -2 -13 0 -23 6 -23 14
|
||||
0 31 20 61 71 17 29 34 46 45 45 18 -1 19 2 21 64 1 28 5 40 16 40 15 0 19 15
|
||||
16 57 -1 11 2 24 7 27 5 3 7 17 5 31 -3 13 -9 22 -14 20 -4 -3 -6 -12 -3 -20
|
||||
3 -8 -1 -21 -9 -29 -8 -8 -12 -25 -10 -39 3 -14 -2 -29 -12 -37 -15 -12 -16
|
||||
-8 -14 53 1 36 6 64 11 61 5 -3 6 6 2 20 -4 16 -2 26 4 26 6 0 18 15 27 33 12
|
||||
25 13 43 6 73 l-9 39 -1 -40 c-2 -56 -11 -85 -28 -85 -8 0 -12 -4 -9 -9 3 -5
|
||||
-12 -24 -33 -42 -22 -17 -42 -40 -44 -51 -3 -10 -11 -18 -17 -18 -8 0 -10 7
|
||||
-5 23 4 12 8 36 9 53 1 17 10 43 20 59 18 27 20 28 27 10 6 -17 8 -15 8 8 1
|
||||
16 7 43 15 60 45 106 49 131 6 42 -16 -33 -30 -53 -30 -45 0 8 -12 -9 -27 -38
|
||||
-15 -29 -30 -52 -34 -52 -5 0 -6 7 -3 15 4 8 2 15 -4 15 -11 0 -22 -23 -22
|
||||
-46 0 -8 3 -13 8 -13 20 3 32 -2 26 -12 -3 -6 -8 -32 -10 -58 -2 -37 0 -48 11
|
||||
-48 8 0 15 5 15 11 0 15 48 66 61 66 7 0 9 -16 6 -42 -3 -22 -1 -55 4 -72 7
|
||||
-24 6 -34 -7 -43 -10 -7 -11 -13 -5 -18 6 -3 11 -1 11 4 0 6 4 11 8 11 5 0 9
|
||||
-7 9 -15 0 -8 -6 -15 -13 -15 -8 0 -21 -14 -30 -32 -9 -18 -23 -38 -30 -46 -8
|
||||
-7 -14 -20 -14 -28 0 -8 -4 -14 -10 -14 -12 0 -12 2 -1 33 8 19 6 27 -5 31 -8
|
||||
3 -14 10 -14 16 0 6 5 8 11 4 9 -5 10 1 5 20 -4 15 -2 26 4 26 6 0 6 9 -1 26
|
||||
-5 15 -7 36 -4 48 5 15 4 17 -3 7 -10 -14 -17 -2 -27 51 -3 12 -9 24 -15 26
|
||||
-5 2 -10 13 -10 25 -1 22 -1 22 -17 2 -15 -19 -15 -18 -9 14 3 19 17 49 31 67
|
||||
27 36 30 44 15 44 -5 0 -10 -7 -10 -15 0 -8 -6 -15 -14 -15 -8 0 -16 -10 -18
|
||||
-22 -5 -36 -33 -28 -36 11 -2 21 0 31 7 26 6 -3 11 -1 11 4 0 6 6 11 13 11 7
|
||||
0 32 16 55 36 23 19 42 32 42 29 0 -4 6 -2 14 4 11 10 15 8 19 -6 3 -10 5 -3
|
||||
6 15 2 61 111 137 111 77 0 -7 -4 -15 -8 -17 -9 -4 -52 -63 -52 -72 0 -19 23
|
||||
-1 31 24 6 16 15 28 19 25 5 -3 15 14 22 37 16 47 36 55 54 21 6 -13 14 -20
|
||||
17 -16 4 3 7 -3 7 -15 0 -14 -5 -20 -13 -16 -14 5 -45 -69 -39 -93 2 -7 -2
|
||||
-13 -8 -13 -5 0 -10 6 -11 13 -4 58 -18 92 -20 46 0 -13 -2 -34 -3 -46 -4 -31
|
||||
11 -53 23 -34 5 7 14 10 20 7 7 -5 11 2 11 18 0 31 18 73 45 102 11 12 26 30
|
||||
34 39 8 10 23 15 37 12 17 -3 28 3 41 22 14 22 14 24 1 13 -9 -7 -25 -15 -37
|
||||
-17 -18 -3 -20 -1 -11 15 19 35 10 34 -25 -4 -19 -21 -39 -35 -46 -31 -7 5 2
|
||||
20 25 44 26 27 33 40 26 51 -7 10 -10 11 -10 3 0 -7 -11 -13 -25 -13 -27 0
|
||||
-34 17 -10 26 8 4 12 10 9 15 -10 17 -22 9 -29 -22z m19 -59 c-15 -16 -31 -27
|
||||
-36 -24 -12 8 31 54 49 54 8 0 3 -12 -13 -30z m-324 -374 c0 -3 -4 -8 -10 -11
|
||||
-5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z"/>
|
||||
<path d="M906 1707 c3 -10 9 -15 12 -12 3 3 0 11 -7 18 -10 9 -11 8 -5 -6z"/>
|
||||
<path d="M1438 1713 c-20 -5 -24 -23 -5 -23 6 0 21 7 31 15 20 15 11 18 -26 8z"/>
|
||||
<path d="M620 1689 c-22 -18 -22 -19 -3 -10 12 6 25 16 28 21 9 15 3 12 -25
|
||||
-11z"/>
|
||||
<path d="M833 1685 l-28 -26 38 22 c37 21 45 29 28 29 -6 0 -23 -11 -38 -25z"/>
|
||||
<path d="M712 1645 c-20 -19 -32 -35 -26 -35 5 0 25 16 44 35 44 45 31 45 -18
|
||||
0z"/>
|
||||
<path d="M870 1670 c-9 -6 -10 -10 -3 -10 6 0 15 5 18 10 8 12 4 12 -15 0z"/>
|
||||
<path d="M1645 1640 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M950 1626 c0 -8 -6 -17 -12 -19 -10 -4 -10 -6 -1 -6 7 -1 17 8 23 19
|
||||
7 14 7 20 0 20 -5 0 -10 -6 -10 -14z"/>
|
||||
<path d="M719 1613 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"/>
|
||||
<path d="M774 1621 c3 -5 -12 -25 -34 -45 -22 -20 -40 -38 -40 -41 0 -13 20
|
||||
-2 53 30 36 35 48 65 26 65 -5 0 -8 -4 -5 -9z"/>
|
||||
<path d="M842 1606 c-15 -17 -19 -25 -10 -28 8 -3 2 -16 -19 -36 -17 -18 -28
|
||||
-32 -23 -32 5 0 12 5 15 10 4 6 10 8 15 5 11 -7 23 13 26 43 2 13 11 33 20 43
|
||||
25 28 3 23 -24 -5z"/>
|
||||
<path d="M555 1609 c-11 -17 1 -21 15 -4 8 9 8 15 2 15 -6 0 -14 -5 -17 -11z"/>
|
||||
<path d="M900 1610 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M1627 1579 c-21 -22 -37 -47 -37 -56 0 -8 -9 -26 -20 -40 -15 -19
|
||||
-17 -30 -10 -44 10 -17 5 -60 -8 -84 -10 -16 -11 -55 -2 -55 4 0 7 10 6 23 -2
|
||||
12 3 28 10 35 10 9 14 -4 18 -66 2 -42 8 -96 11 -118 4 -26 3 -44 -4 -48 -6
|
||||
-4 -11 -12 -11 -19 0 -6 11 0 25 15 25 27 33 44 15 33 -5 -3 -7 9 -5 30 4 26
|
||||
1 35 -10 35 -8 0 -15 8 -14 18 0 10 3 12 6 5 10 -26 25 -13 20 17 -4 16 0 48
|
||||
8 71 20 56 19 60 -6 20 -25 -42 -37 -34 -14 11 22 42 36 98 24 98 -8 0 -13
|
||||
-22 -10 -42 0 -5 -3 -8 -9 -8 -5 0 -10 -7 -10 -15 0 -8 -4 -15 -10 -15 -13 0
|
||||
-13 45 1 93 7 27 15 37 25 33 17 -6 18 -1 4 24 -7 13 -7 21 2 26 7 4 8 3 4 -4
|
||||
-4 -7 -5 -12 -2 -12 3 0 15 18 26 40 11 22 19 40 17 40 -2 0 -20 -18 -40 -41z"/>
|
||||
<path d="M1696 1594 c-11 -7 -16 -17 -13 -21 4 -4 15 1 24 10 22 21 14 30 -11
|
||||
11z"/>
|
||||
<path d="M1442 1580 c-9 -14 -9 -20 -1 -20 8 0 7 -6 -2 -17 -11 -15 -11 -16 1
|
||||
-6 7 7 14 24 16 38 3 30 2 31 -14 5z"/>
|
||||
<path d="M652 1561 c-17 -17 -32 -33 -32 -37 0 -5 17 8 37 27 21 18 40 35 42
|
||||
37 2 1 0 2 -5 2 -5 0 -24 -13 -42 -29z"/>
|
||||
<path d="M1765 1581 c-3 -5 -2 -12 3 -15 5 -3 9 1 9 9 0 17 -3 19 -12 6z"/>
|
||||
<path d="M488 1573 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M1060 1565 c-7 -9 -8 -15 -2 -15 5 0 12 7 16 15 3 8 4 15 2 15 -2 0
|
||||
-9 -7 -16 -15z"/>
|
||||
<path d="M1722 1568 c-18 -18 -15 -38 5 -31 11 4 13 8 5 11 -10 3 -10 7 -1 18
|
||||
14 17 8 19 -9 2z"/>
|
||||
<path d="M784 1561 c7 -11 -28 -43 -38 -34 -4 4 -4 0 0 -10 3 -9 2 -17 -3 -17
|
||||
-5 0 -18 -8 -29 -18 -10 -10 -27 -21 -36 -25 -18 -6 -25 -27 -10 -27 12 0 132
|
||||
118 132 130 0 5 -5 10 -11 10 -5 0 -8 -4 -5 -9z"/>
|
||||
<path d="M528 1553 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M1544 1524 c3 -9 6 -18 6 -20 0 -3 4 -3 10 1 11 7 2 35 -12 35 -6 0
|
||||
-7 -7 -4 -16z"/>
|
||||
<path d="M1650 1510 c-7 -14 -7 -20 0 -20 5 0 10 6 10 14 0 8 6 17 13 19 9 4
|
||||
9 6 0 6 -7 1 -17 -8 -23 -19z"/>
|
||||
<path d="M820 1490 c-14 -10 -22 -21 -19 -24 3 -3 16 5 29 19 28 30 24 32 -10
|
||||
5z"/>
|
||||
<path d="M1509 1503 c-2 -29 -11 -58 -20 -70 -9 -10 -8 -13 4 -13 13 0 14 -6
|
||||
6 -36 -6 -19 -7 -48 -4 -64 3 -15 2 -31 -4 -34 -6 -4 -7 -14 -4 -22 5 -13 1
|
||||
-15 -18 -9 -20 7 -22 5 -13 -6 7 -8 14 -33 18 -56 4 -34 3 -41 -9 -36 -17 6
|
||||
-20 -14 -5 -37 8 -12 10 -12 10 5 2 44 21 -30 25 -93 1 -35 6 -66 9 -69 3 -4
|
||||
6 0 6 8 1 8 7 -2 14 -21 8 -19 20 -49 27 -66 11 -28 9 -39 -13 -101 -21 -56
|
||||
-23 -70 -12 -70 8 0 13 6 10 13 -3 8 5 20 17 29 20 14 21 15 2 16 -19 0 -19 1
|
||||
-2 8 10 4 18 10 18 14 -1 4 -1 19 -1 33 0 22 2 25 15 14 8 -7 15 -18 15 -24 0
|
||||
-6 9 -17 21 -24 19 -12 20 -12 13 10 -4 13 -8 42 -9 66 -2 24 -6 46 -9 49 -4
|
||||
4 -6 -6 -5 -23 4 -74 -17 -69 -27 7 -4 27 -10 52 -14 54 -5 3 -6 -4 -3 -15 10
|
||||
-37 -8 -20 -29 28 -34 76 -62 282 -39 282 6 0 11 10 11 23 0 13 3 27 6 30 11
|
||||
10 13 67 3 67 -11 0 -6 45 10 83 9 23 8 31 -4 43 -8 9 -15 12 -16 7z"/>
|
||||
<path d="M1665 1471 c-12 -40 -8 -102 9 -119 16 -16 16 -15 7 11 -8 21 -8 27
|
||||
2 26 23 -3 40 1 34 8 -4 3 -2 12 4 20 6 7 8 13 3 13 -5 0 -2 5 6 10 11 7 11
|
||||
10 2 10 -7 0 -18 -13 -23 -30 -14 -38 -30 -29 -25 14 5 41 -9 69 -19 37z"/>
|
||||
<path d="M532 1467 c-17 -20 -12 -40 6 -28 8 5 12 16 10 26 -3 17 -4 17 -16 2z"/>
|
||||
<path d="M638 1473 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
|
||||
<path d="M761 1466 c-13 -7 -19 -16 -14 -19 6 -4 18 2 28 13 21 23 19 24 -14
|
||||
6z"/>
|
||||
<path d="M482 1450 c-29 -28 -28 -34 3 -14 14 9 25 20 25 25 0 13 -4 11 -28
|
||||
-11z"/>
|
||||
<path d="M588 1449 l-23 -20 25 13 c14 6 31 11 38 10 17 -4 15 5 -3 11 -7 3
|
||||
-24 -3 -37 -14z"/>
|
||||
<path d="M701 1430 c-13 -11 -18 -20 -13 -20 6 0 14 5 17 10 4 6 10 8 14 6 4
|
||||
-3 8 1 8 9 0 8 -1 15 -1 15 -1 -1 -12 -10 -25 -20z"/>
|
||||
<path d="M815 1440 c-3 -5 3 -10 14 -10 12 0 21 5 21 10 0 6 -6 10 -14 10 -8
|
||||
0 -18 -4 -21 -10z"/>
|
||||
<path d="M913 1428 c-4 -7 -8 -20 -10 -28 -1 -10 3 -9 13 4 14 19 18 36 10 36
|
||||
-3 0 -8 -6 -13 -12z"/>
|
||||
<path d="M1026 1423 c-6 -14 -5 -15 5 -6 7 7 10 15 7 18 -3 3 -9 -2 -12 -12z"/>
|
||||
<path d="M1335 1420 c-5 -14 -2 -28 8 -37 13 -13 14 -11 11 18 -5 41 -10 46
|
||||
-19 19z"/>
|
||||
<path d="M778 1423 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M545 1400 c-3 -10 -19 -30 -36 -44 -16 -14 -28 -29 -27 -33 2 -5 -7
|
||||
-21 -18 -36 -16 -19 -27 -25 -40 -21 -17 6 -17 5 0 -8 19 -15 19 -16 -10 -48
|
||||
-16 -17 -40 -36 -54 -42 -22 -9 -23 -11 -7 -17 16 -6 15 -9 -9 -31 -15 -14
|
||||
-24 -20 -21 -13 4 6 3 23 -3 38 -8 20 -7 27 4 31 16 6 40 64 27 64 -4 0 -13
|
||||
-11 -19 -24 -6 -13 -18 -23 -28 -23 -15 2 -17 -6 -15 -49 1 -33 -2 -55 -10
|
||||
-60 -9 -5 -7 -9 7 -15 15 -6 35 10 102 79 45 47 81 90 79 96 -6 15 50 84 74
|
||||
91 10 4 17 11 13 16 -4 6 -11 6 -20 -2 -8 -7 -14 -7 -14 -1 0 5 7 15 16 22 21
|
||||
18 37 50 25 50 -5 0 -12 -9 -16 -20z"/>
|
||||
<path d="M609 1400 c-21 -17 -21 -19 -4 -13 11 3 29 12 40 20 16 10 16 13 3
|
||||
13 -9 0 -26 -9 -39 -20z"/>
|
||||
<path d="M785 1400 c-3 -6 1 -7 9 -4 18 7 21 14 7 14 -6 0 -13 -4 -16 -10z"/>
|
||||
<path d="M1429 1403 c0 -5 0 -35 1 -68 1 -33 -4 -73 -10 -89 -11 -30 0 -56 24
|
||||
-56 8 0 8 2 0 8 -6 4 -10 18 -8 32 1 14 3 31 3 39 1 7 7 11 14 8 10 -4 12 7 9
|
||||
46 -2 29 -9 55 -16 59 -8 6 -7 8 2 8 6 0 12 5 12 10 0 11 -30 14 -31 3z"/>
|
||||
<path d="M469 1387 c5 -5 17 -5 28 2 16 9 15 10 -9 9 -16 -2 -24 -6 -19 -11z"/>
|
||||
<path d="M620 1379 c-26 -14 -30 -19 -15 -19 11 0 34 9 50 20 38 25 12 24 -35
|
||||
-1z"/>
|
||||
<path d="M710 1375 c-30 -17 -43 -19 -35 -5 3 6 1 10 -5 10 -7 0 -10 -6 -7
|
||||
-12 5 -14 56 -12 71 3 17 15 2 18 -24 4z"/>
|
||||
<path d="M733 1347 c-27 -29 -27 -29 -4 -17 14 7 33 20 43 30 14 13 15 17 3
|
||||
17 -8 0 -27 -14 -42 -30z"/>
|
||||
<path d="M1402 1345 c0 -16 2 -22 5 -12 2 9 2 23 0 30 -3 6 -5 -1 -5 -18z"/>
|
||||
<path d="M1300 1340 c0 -11 4 -20 8 -20 4 0 8 9 9 20 1 11 -2 20 -8 20 -5 0
|
||||
-9 -9 -9 -20z"/>
|
||||
<path d="M1270 1335 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M574 1314 c-5 -21 -11 -25 -30 -21 -19 3 -22 2 -13 -9 9 -11 7 -15
|
||||
-5 -20 -9 -3 -14 -10 -11 -15 3 -4 -7 -15 -22 -24 -15 -9 -19 -13 -8 -10 11 4
|
||||
28 10 37 12 10 3 15 10 11 16 -4 6 0 8 10 4 10 -3 17 -2 17 3 0 5 10 19 23 31
|
||||
12 12 15 18 7 14 -12 -6 -13 -5 -2 6 14 16 16 39 2 39 -5 0 -13 -12 -16 -26z"/>
|
||||
<path d="M642 1310 c-63 -46 -53 -49 27 -9 20 10 30 18 23 19 -7 0 -10 5 -7
|
||||
10 10 16 0 12 -43 -20z"/>
|
||||
<path d="M410 1314 c0 -8 5 -12 10 -9 6 4 8 11 5 16 -9 14 -15 11 -15 -7z"/>
|
||||
<path d="M803 1313 c-7 -2 -13 -11 -13 -19 0 -8 -7 -14 -16 -14 -10 0 -14 -6
|
||||
-11 -14 8 -20 -16 -26 -29 -8 -10 14 -12 13 -18 -4 -3 -11 -20 -28 -37 -38
|
||||
-17 -10 -28 -20 -25 -23 3 -3 16 1 28 9 13 8 32 18 42 21 15 6 17 5 8 -6 -7
|
||||
-8 -9 -16 -6 -20 3 -3 -7 -13 -23 -23 -15 -10 -30 -19 -32 -20 -1 -2 0 -8 4
|
||||
-14 9 -14 41 19 81 82 16 27 35 48 42 48 7 0 10 5 7 10 -4 6 -1 9 5 8 7 -2 14
|
||||
5 15 15 3 17 -1 19 -22 10z"/>
|
||||
<path d="M900 1309 c0 -19 -52 -129 -61 -129 -5 0 -9 -4 -9 -10 0 -20 28 3 49
|
||||
41 29 51 42 97 30 104 -5 4 -9 1 -9 -6z"/>
|
||||
<path d="M1663 1285 c-7 -21 -8 -46 -3 -63 l8 -27 2 30 c1 17 4 45 6 63 5 42
|
||||
0 41 -13 -3z"/>
|
||||
<path d="M1710 1301 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5
|
||||
3 -10 2 -10 -4z"/>
|
||||
<path d="M735 1280 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0 -7
|
||||
-4 -4 -10z"/>
|
||||
<path d="M655 1264 c-11 -8 -25 -12 -33 -9 -7 2 -10 0 -7 -5 3 -6 -2 -10 -12
|
||||
-10 -10 -1 -29 -8 -43 -16 -17 -11 -19 -13 -5 -9 25 9 46 13 65 15 17 1 81 50
|
||||
65 50 -5 -1 -19 -7 -30 -16z"/>
|
||||
<path d="M1696 1265 c-3 -8 -1 -15 4 -15 6 0 10 7 10 15 0 8 -2 15 -4 15 -2 0
|
||||
-6 -7 -10 -15z"/>
|
||||
<path d="M842 1239 c-7 -11 -27 -26 -44 -33 -24 -10 -27 -14 -14 -19 21 -8 63
|
||||
18 72 45 8 27 1 31 -14 7z"/>
|
||||
<path d="M1534 1252 c4 -7 2 -12 -5 -12 -8 0 -10 -12 -5 -37 11 -68 17 -97 21
|
||||
-101 2 -2 -1 -15 -6 -29 -6 -16 -6 -31 1 -41 8 -15 10 -15 10 3 1 11 3 29 5
|
||||
40 14 84 13 115 -2 115 -11 0 -14 8 -11 30 3 17 0 34 -5 37 -6 3 -7 1 -3 -5z"/>
|
||||
<path d="M806 1235 c-3 -8 -1 -15 3 -15 5 0 11 7 15 15 3 8 1 15 -3 15 -5 0
|
||||
-11 -7 -15 -15z"/>
|
||||
<path d="M1296 1223 c-8 -25 -6 -39 6 -35 6 2 8 -8 6 -23 -3 -14 -1 -25 4 -25
|
||||
9 0 5 86 -5 96 -3 3 -8 -3 -11 -13z"/>
|
||||
<path d="M1693 1225 c0 -8 4 -15 9 -15 4 0 8 7 8 15 0 8 -4 15 -8 15 -5 0 -9
|
||||
-7 -9 -15z"/>
|
||||
<path d="M1730 1230 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1151 1207 c-16 -41 -13 -57 5 -24 8 16 13 34 11 40 -3 7 -10 -1 -16
|
||||
-16z"/>
|
||||
<path d="M1040 1194 c0 -8 5 -12 10 -9 6 4 8 11 5 16 -9 14 -15 11 -15 -7z"/>
|
||||
<path d="M1102 1189 c3 -8 -3 -21 -12 -29 -9 -8 -22 -30 -30 -48 -8 -21 -16
|
||||
-29 -20 -22 -5 9 -9 9 -14 1 -4 -6 -4 -15 -1 -21 3 -5 1 -10 -6 -10 -10 0 -10
|
||||
-3 -2 -11 13 -13 36 -3 28 12 -4 5 -1 9 4 9 6 0 11 6 11 14 0 8 3 16 8 18 4 2
|
||||
19 19 33 38 23 31 25 37 11 49 -13 12 -14 12 -10 0z"/>
|
||||
<path d="M480 1181 c0 -7 -7 -20 -16 -29 -18 -17 -48 -26 -38 -11 3 5 1 9 -4
|
||||
9 -8 0 -23 -22 -26 -40 -1 -3 -13 -22 -28 -43 -16 -25 -28 -34 -33 -27 -4 6 1
|
||||
21 11 34 11 12 8 11 -6 -4 -21 -21 -35 -25 -85 -26 -86 -2 -123 -8 -137 -22
|
||||
-6 -6 -16 -12 -21 -12 -4 0 -28 -14 -53 -30 -29 -21 -44 -38 -44 -52 0 -20 1
|
||||
-20 13 -5 6 9 28 27 47 41 19 14 45 33 57 41 17 13 26 14 42 5 14 -7 21 -7 21
|
||||
0 0 5 9 10 19 10 11 0 23 5 26 10 13 20 53 10 79 -21 31 -37 33 -69 6 -94 -13
|
||||
-12 -18 -25 -14 -38 4 -13 2 -17 -5 -13 -6 4 -11 1 -11 -7 0 -19 -28 -42 -38
|
||||
-32 -4 4 -1 10 6 12 6 3 12 9 12 15 0 16 -28 -11 -43 -40 -14 -29 -63 -69 -73
|
||||
-59 -4 3 6 20 20 38 28 33 29 53 1 25 -20 -20 -26 -20 -19 -1 4 9 0 15 -10 15
|
||||
-9 0 -15 -3 -15 -7 1 -5 1 -15 0 -23 -1 -12 -3 -13 -10 -1 -6 9 -11 10 -15 2
|
||||
-4 -6 -4 -11 0 -11 4 0 -1 -9 -10 -19 -10 -11 -25 -17 -34 -14 -13 4 -12 2 3
|
||||
-10 16 -13 17 -17 6 -31 -12 -14 -12 -16 4 -10 13 5 16 4 11 -4 -4 -7 -2 -12
|
||||
3 -12 6 0 11 7 11 15 0 8 6 15 14 15 8 0 16 5 18 12 3 8 13 2 28 -15 13 -15
|
||||
30 -27 37 -27 19 0 16 -10 -12 -36 -14 -13 -25 -27 -25 -32 0 -14 -57 -61 -66
|
||||
-54 -4 4 -4 1 1 -7 4 -8 2 -17 -6 -22 -8 -5 -9 -9 -3 -9 6 0 21 11 34 25 12
|
||||
13 28 22 34 18 6 -3 8 -3 4 1 -10 12 120 179 133 171 13 -9 21 15 9 30 -9 11
|
||||
-15 9 -35 -11 -14 -14 -25 -29 -25 -34 0 -11 -3 -12 -39 -14 -40 -2 -33 17 20
|
||||
53 60 41 104 94 95 117 -4 10 -1 14 6 12 20 -7 21 -38 3 -58 -11 -12 -13 -20
|
||||
-6 -25 6 -3 11 1 11 9 0 8 5 18 11 22 8 4 9 -1 3 -17 -4 -13 -9 -37 -10 -52
|
||||
-1 -15 -7 -34 -13 -41 -6 -7 -8 -15 -6 -18 3 -3 1 -17 -4 -32 -9 -23 -9 -25 7
|
||||
-15 16 10 19 21 25 89 2 30 11 38 22 20 3 -5 14 -9 23 -9 15 1 15 2 -1 6 -9 2
|
||||
-14 9 -11 15 4 7 2 8 -4 4 -7 -4 -12 -1 -12 8 0 8 10 17 23 19 l22 4 -22 2
|
||||
c-13 0 -23 4 -24 9 -8 75 -5 102 12 102 6 0 7 -10 3 -22 -6 -20 -4 -20 16 5
|
||||
12 15 20 31 16 34 -3 4 -6 1 -6 -5 0 -7 -4 -12 -10 -12 -5 0 -10 7 -10 15 0 9
|
||||
-6 12 -15 9 -8 -4 -15 -2 -15 2 0 12 20 41 20 31 0 -5 8 -1 17 9 13 13 15 18
|
||||
5 22 -9 3 -6 10 9 23 12 10 17 19 11 19 -14 0 76 84 92 86 24 3 56 17 56 25 0
|
||||
16 -30 10 -37 -7 -6 -15 -8 -15 -20 2 -7 10 -13 13 -13 5z m-355 -415 c-18
|
||||
-28 -42 -40 -50 -26 -4 6 0 10 8 10 8 0 22 9 32 20 25 27 29 25 10 -4z"/>
|
||||
<path d="M922 1156 c-21 -20 -42 -33 -46 -29 -3 3 -6 -1 -6 -10 0 -27 22 -19
|
||||
64 23 50 51 41 63 -12 16z"/>
|
||||
<path d="M620 1170 c-12 -8 -10 -10 8 -10 13 0 20 4 17 10 -7 12 -6 12 -25 0z"/>
|
||||
<path d="M743 1156 c-15 -13 -26 -26 -23 -29 3 -3 21 8 40 24 19 16 29 29 23
|
||||
29 -7 0 -25 -11 -40 -24z"/>
|
||||
<path d="M1393 1113 c-11 -38 -26 -67 -32 -65 -6 1 -11 -1 -12 -5 0 -5 -2 -16
|
||||
-4 -27 -3 -14 -1 -16 8 -7 14 14 30 15 22 1 -3 -5 -1 -10 5 -10 7 0 10 6 7 14
|
||||
-3 8 0 33 7 56 17 57 31 35 35 -55 2 -38 7 -75 12 -82 7 -7 6 -14 -1 -18 -14
|
||||
-8 -13 -52 2 -61 6 -4 8 -3 4 4 -3 6 -1 23 6 39 6 15 12 42 13 58 1 17 5 41 8
|
||||
55 4 14 4 19 1 13 -13 -30 -26 -11 -20 28 4 26 3 38 -4 34 -6 -3 -7 0 -4 9 4
|
||||
11 0 16 -13 16 -16 0 -18 6 -15 35 6 53 -2 42 -25 -32z"/>
|
||||
<path d="M1683 1174 c3 -3 1 -17 -4 -31 -6 -16 -6 -31 1 -41 7 -14 9 -11 10
|
||||
15 0 17 3 38 6 47 4 10 1 16 -7 16 -7 0 -10 -3 -6 -6z"/>
|
||||
<path d="M749 1120 c-28 -27 -56 -50 -63 -50 -12 0 -66 -39 -54 -40 4 0 24 9
|
||||
45 19 21 11 45 21 53 23 8 2 27 19 42 38 15 19 32 41 38 48 7 8 7 12 0 12 -5
|
||||
0 -33 -22 -61 -50z"/>
|
||||
<path d="M1263 1149 c-2 -17 1 -18 13 -9 17 15 18 30 1 30 -7 0 -13 -9 -14
|
||||
-21z"/>
|
||||
<path d="M560 1150 c-13 -9 -13 -10 0 -10 8 0 22 5 30 10 13 9 13 10 0 10 -8
|
||||
0 -22 -5 -30 -10z"/>
|
||||
<path d="M1119 1133 c-10 -11 -10 -14 -1 -9 6 4 12 2 12 -3 0 -6 -5 -11 -12
|
||||
-11 -6 0 -8 -3 -4 -7 9 -9 -54 -73 -73 -74 -9 0 -11 -3 -5 -5 22 -9 87 45 101
|
||||
84 15 45 15 42 4 42 -5 0 -15 -8 -22 -17z"/>
|
||||
<path d="M494 1124 c-18 -15 -18 -15 2 -5 12 6 24 7 28 4 3 -3 6 -1 6 5 0 16
|
||||
-12 15 -36 -4z"/>
|
||||
<path d="M591 1124 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M610 1131 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5 3
|
||||
-10 2 -10 -4z"/>
|
||||
<path d="M953 1110 c-9 -11 -20 -15 -23 -10 -3 5 -14 -5 -24 -23 -14 -26 -14
|
||||
-28 -1 -12 9 11 21 19 27 17 5 -1 16 2 22 8 7 5 15 7 18 5 3 -3 8 3 11 15 7
|
||||
26 -8 26 -30 0z"/>
|
||||
<path d="M1280 1115 c-9 -11 -9 -15 -1 -15 7 0 9 -5 5 -12 -4 -7 -3 -10 1 -5
|
||||
8 6 16 47 10 47 -2 0 -8 -7 -15 -15z"/>
|
||||
<path d="M790 1095 c-20 -24 -6 -27 20 -5 17 15 19 20 8 20 -9 0 -21 -7 -28
|
||||
-15z"/>
|
||||
<path d="M547 1084 c4 -10 10 -11 24 -3 24 13 24 14 -5 15 -17 1 -23 -2 -19
|
||||
-12z"/>
|
||||
<path d="M1625 1090 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M864 1082 c3 -5 -4 -19 -15 -30 -11 -12 -16 -22 -11 -22 12 0 42 34
|
||||
42 48 0 7 -5 12 -11 12 -5 0 -8 -4 -5 -8z"/>
|
||||
<path d="M1261 1074 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M440 1069 c0 -5 11 -9 25 -9 14 0 25 2 25 4 0 2 -11 6 -25 8 -14 3
|
||||
-25 1 -25 -3z"/>
|
||||
<path d="M967 1062 c-24 -27 -21 -36 4 -11 11 11 19 23 16 25 -2 2 -11 -4 -20
|
||||
-14z"/>
|
||||
<path d="M580 1055 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M1612 1039 c-2 -18 2 -28 8 -24 5 3 8 15 7 25 -5 32 -13 31 -15 -1z"/>
|
||||
<path d="M1143 1048 c-13 -16 -26 -58 -19 -58 8 0 38 61 33 66 -2 3 -9 -1 -14
|
||||
-8z"/>
|
||||
<path d="M694 1035 c-10 -8 -14 -15 -8 -15 6 0 17 7 24 15 16 19 9 19 -16 0z"/>
|
||||
<path d="M722 1028 c-15 -15 -16 -31 0 -26 6 2 12 12 14 21 3 20 2 21 -14 5z"/>
|
||||
<path d="M970 1000 c-17 -22 -27 -40 -21 -40 6 0 11 4 11 9 0 5 14 23 31 40
|
||||
17 17 26 31 21 31 -6 0 -25 -18 -42 -40z"/>
|
||||
<path d="M1095 1020 c-20 -22 -85 -63 -84 -52 5 30 -3 34 -19 9 -10 -15 -28
|
||||
-36 -40 -48 -12 -11 -22 -24 -22 -29 0 -12 30 -14 30 -2 0 4 10 18 21 32 17
|
||||
21 20 22 15 5 -6 -19 -5 -19 8 -2 8 10 17 18 20 18 15 -2 85 52 89 70 6 24 4
|
||||
24 -18 -1z"/>
|
||||
<path d="M1664 1015 c7 -36 12 -41 19 -16 3 11 -2 26 -10 32 -12 10 -13 8 -9
|
||||
-16z"/>
|
||||
<path d="M1710 1030 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M433 1023 c-7 -2 -13 -9 -13 -15 0 -7 4 -7 13 0 6 5 21 12 32 15 20
|
||||
5 20 5 0 5 -11 0 -26 -2 -32 -5z"/>
|
||||
<path d="M591 1013 c-1 -17 16 -25 25 -12 4 7 3 9 -4 5 -5 -3 -13 0 -15 6 -4
|
||||
9 -6 10 -6 1z"/>
|
||||
<path d="M790 1005 c-6 -8 -10 -19 -8 -24 4 -14 51 10 54 27 1 7 0 8 -3 2 -3
|
||||
-8 -9 -8 -18 0 -9 7 -16 6 -25 -5z"/>
|
||||
<path d="M912 1011 c-11 -6 -10 -10 4 -15 15 -6 13 -11 -14 -37 -18 -17 -32
|
||||
-36 -32 -41 0 -5 -10 -6 -22 -3 -13 3 -18 3 -13 -2 10 -7 11 -15 6 -40 0 -4
|
||||
-6 -2 -13 5 -7 7 -17 12 -22 12 -6 0 -1 -7 11 -15 18 -13 26 -13 43 -3 11 7
|
||||
20 18 20 24 0 6 16 33 35 60 19 27 35 52 35 56 0 10 -22 10 -38 -1z"/>
|
||||
<path d="M241 994 c0 -12 -18 -43 -40 -70 -36 -46 -37 -49 -16 -49 14 0 21 5
|
||||
18 13 -7 17 17 44 33 38 8 -3 20 1 28 9 19 20 26 19 27 -2 0 -15 2 -15 8 2 8
|
||||
21 4 45 -7 43 -24 -3 -41 4 -45 20 -4 13 -5 13 -6 -4z"/>
|
||||
<path d="M455 994 c-16 -7 -33 -10 -37 -7 -5 2 -8 -3 -8 -13 0 -12 4 -14 13
|
||||
-7 12 10 58 24 89 28 30 3 30 12 1 12 -16 0 -41 -6 -58 -13z"/>
|
||||
<path d="M630 980 c-13 -11 -21 -22 -18 -25 3 -3 17 6 32 20 32 30 20 34 -14
|
||||
5z"/>
|
||||
<path d="M116 974 c-3 -8 -10 -13 -15 -9 -5 3 -13 -5 -17 -17 -4 -13 -11 -26
|
||||
-17 -29 -6 -4 -5 -13 2 -25 9 -17 10 -17 11 -1 0 9 6 17 14 17 7 0 16 14 20
|
||||
31 3 17 10 28 16 24 5 -3 10 -2 10 4 0 17 -18 21 -24 5z"/>
|
||||
<path d="M1317 965 c-2 -14 -1 -27 2 -29 4 -3 8 -18 9 -35 2 -24 -1 -29 -13
|
||||
-25 -10 4 -15 0 -15 -12 0 -11 -9 -32 -20 -49 -11 -16 -20 -37 -20 -45 0 -8
|
||||
11 5 25 29 14 23 25 50 25 59 0 14 2 14 13 -1 11 -15 12 -14 14 10 0 15 6 29
|
||||
12 31 6 2 10 22 10 45 -2 31 -3 34 -6 14 -2 -15 -8 -25 -13 -22 -4 3 -6 14 -3
|
||||
24 3 10 0 21 -5 25 -5 3 -12 -6 -15 -19z"/>
|
||||
<path d="M728 964 c-16 -8 -28 -20 -28 -27 0 -9 2 -9 8 0 4 6 20 15 35 18 15
|
||||
4 27 11 27 16 0 12 -10 11 -42 -7z"/>
|
||||
<path d="M475 960 c-3 -5 -14 -10 -25 -10 -10 0 -21 -7 -24 -16 -9 -24 -1 -28
|
||||
17 -9 17 17 31 20 22 5 -12 -19 26 -23 58 -7 31 16 31 16 5 11 -40 -9 -64 2
|
||||
-48 21 7 8 10 15 7 15 -3 0 -9 -4 -12 -10z"/>
|
||||
<path d="M1650 963 c5 -2 8 -9 4 -14 -3 -5 0 -9 6 -9 15 0 7 23 -8 26 -7 1 -8
|
||||
0 -2 -3z"/>
|
||||
<path d="M777 930 c3 -11 10 -23 16 -27 6 -4 7 -1 2 7 -6 10 -4 12 9 7 22 -9
|
||||
11 9 -14 23 -15 8 -17 7 -13 -10z"/>
|
||||
<path d="M1095 920 c-16 -16 -27 -31 -24 -33 2 -2 17 11 32 30 36 41 31 43 -8
|
||||
3z"/>
|
||||
<path d="M1379 928 c0 -13 -2 -33 -3 -46 -2 -13 2 -21 8 -19 13 4 17 87 4 87
|
||||
-4 0 -8 -10 -9 -22z"/>
|
||||
<path d="M1605 940 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0 -7
|
||||
-4 -4 -10z"/>
|
||||
<path d="M668 933 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M1147 927 c-3 -8 1 -14 9 -14 16 0 19 13 5 21 -5 3 -11 0 -14 -7z"/>
|
||||
<path d="M1269 901 c-14 -15 -33 -32 -42 -37 -11 -7 -13 -14 -7 -24 8 -12 13
|
||||
-10 32 14 13 16 31 36 41 45 18 16 23 32 10 30 -5 0 -20 -13 -34 -28z"/>
|
||||
<path d="M1660 894 c0 -19 4 -33 8 -30 8 5 4 66 -4 66 -2 0 -4 -16 -4 -36z"/>
|
||||
<path d="M395 912 c-18 -13 -14 -28 8 -29 16 -2 18 0 8 6 -7 5 -10 14 -7 20 8
|
||||
13 5 14 -9 3z"/>
|
||||
<path d="M574 906 c-10 -8 -17 -17 -14 -19 3 -3 16 3 29 14 27 22 15 26 -15 5z"/>
|
||||
<path d="M1500 901 c-12 -24 -13 -34 -1 -27 9 6 22 46 15 46 -2 0 -8 -9 -14
|
||||
-19z"/>
|
||||
<path d="M26 877 c-10 -22 -15 -44 -13 -50 3 -7 10 2 17 18 l12 30 9 -24 c5
|
||||
-13 12 -21 16 -17 3 3 1 16 -5 29 -6 12 -13 29 -15 37 -3 10 -11 1 -21 -23z"/>
|
||||
<path d="M482 891 c-11 -7 -11 -9 1 -14 9 -3 18 1 21 9 6 16 -2 18 -22 5z"/>
|
||||
<path d="M1173 892 c-6 -4 -14 -21 -17 -37 -6 -28 -6 -29 4 -6 6 14 16 31 22
|
||||
38 12 15 9 16 -9 5z"/>
|
||||
<path d="M1013 863 c-36 -34 -49 -63 -27 -63 8 0 13 4 10 9 -3 4 6 19 19 31
|
||||
14 13 25 18 25 11 0 -7 5 -9 10 -6 12 7 13 45 2 45 -5 0 -22 -12 -39 -27z"/>
|
||||
<path d="M104 865 c-10 -8 -14 -15 -8 -15 6 0 17 7 24 15 16 19 9 19 -16 0z"/>
|
||||
<path d="M1095 869 c-4 -6 -5 -12 -2 -15 2 -3 7 2 10 11 7 17 1 20 -8 4z"/>
|
||||
<path d="M761 854 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M365 850 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0 -7
|
||||
-4 -4 -10z"/>
|
||||
<path d="M900 849 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M952 848 c-15 -15 -16 -31 0 -26 6 2 12 12 14 21 3 20 2 21 -14 5z"/>
|
||||
<path d="M1411 853 c-1 -7 8 -17 19 -23 14 -7 20 -7 20 0 0 5 -6 10 -14 10 -8
|
||||
0 -17 6 -19 13 -4 9 -6 9 -6 0z"/>
|
||||
<path d="M1469 833 c-18 -47 -26 -58 -38 -59 -6 -1 -14 -2 -18 -3 -4 0 2 -8
|
||||
13 -17 18 -15 18 -15 0 -10 -17 6 -17 5 -5 -11 9 -11 10 -14 1 -9 -8 5 -15 -2
|
||||
-22 -18 -5 -14 -16 -26 -25 -26 -8 0 -15 -7 -15 -16 0 -8 -4 -12 -10 -9 -5 3
|
||||
-10 -1 -10 -9 0 -8 8 -19 17 -24 15 -9 14 -11 -5 -23 -13 -8 -18 -17 -12 -24
|
||||
12 -14 -12 -61 -29 -57 -7 1 -10 -2 -7 -7 4 -5 0 -12 -6 -14 -7 -3 -8 -6 -3
|
||||
-6 20 -1 45 27 65 73 24 58 25 64 3 68 -14 3 -9 10 19 28 21 14 36 31 33 38
|
||||
-2 6 1 12 8 12 13 0 50 74 63 124 8 34 -4 33 -17 -1z"/>
|
||||
<path d="M679 831 c-13 -11 -22 -22 -19 -24 3 -3 16 5 29 19 28 29 22 31 -10
|
||||
5z"/>
|
||||
<path d="M555 821 c-3 -5 -1 -12 4 -15 5 -3 11 1 15 9 6 16 -9 21 -19 6z"/>
|
||||
<path d="M1110 815 c0 -8 -5 -14 -12 -12 -7 1 -13 -5 -14 -13 0 -8 -2 -21 -2
|
||||
-28 -1 -7 -8 -12 -14 -11 -27 3 -38 -1 -38 -15 0 -8 4 -17 9 -20 5 -3 8 0 7 7
|
||||
0 6 4 12 9 12 6 0 9 -4 7 -10 -2 -5 8 4 22 20 29 35 50 85 35 85 -5 0 -9 -7
|
||||
-9 -15z"/>
|
||||
<path d="M1166 814 c-4 -9 -4 -19 -1 -22 2 -3 7 3 11 12 4 9 4 19 1 22 -2 3
|
||||
-7 -3 -11 -12z"/>
|
||||
<path d="M1200 809 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1 736 c-1 -64 0 -69 12 -46 7 14 10 27 5 31 -4 3 -3 21 2 39 13 45
|
||||
13 47 -4 47 -9 0 -14 -19 -15 -71z"/>
|
||||
<path d="M1310 795 c-7 -8 -9 -23 -5 -36 6 -18 4 -21 -10 -15 -15 5 -16 4 -6
|
||||
-8 9 -11 10 -24 2 -52 -5 -20 -7 -34 -4 -30 8 8 34 75 37 96 1 8 8 25 14 38
|
||||
11 18 10 22 -1 22 -8 0 -20 -7 -27 -15z"/>
|
||||
<path d="M624 778 c-11 -13 -30 -28 -44 -35 -20 -9 -21 -12 -6 -12 15 -1 16
|
||||
-4 6 -16 -9 -10 -9 -15 -1 -15 10 0 15 13 12 33 0 4 6 7 14 7 15 0 51 47 42
|
||||
56 -2 3 -13 -5 -23 -18z"/>
|
||||
<path d="M409 788 c-12 -40 23 -62 42 -27 9 18 7 19 -17 13 -19 -5 -25 -4 -20
|
||||
5 4 6 5 11 2 11 -3 0 -6 -1 -7 -2z"/>
|
||||
<path d="M935 780 c-3 -5 -2 -10 4 -10 5 0 13 5 16 10 3 6 2 10 -4 10 -5 0
|
||||
-13 -4 -16 -10z"/>
|
||||
<path d="M660 770 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0 -4
|
||||
-4 -4 -10z"/>
|
||||
<path d="M1222 760 c-8 -13 -8 -20 -2 -20 6 0 13 7 17 15 9 24 -1 27 -15 5z"/>
|
||||
<path d="M827 763 c-4 -3 -7 -11 -7 -17 0 -6 5 -5 12 2 6 6 9 14 7 17 -3 3 -9
|
||||
2 -12 -2z"/>
|
||||
<path d="M1002 765 c5 -5 -1 -14 -12 -22 -11 -8 -20 -22 -19 -31 0 -14 2 -14
|
||||
6 -2 4 8 15 22 26 31 17 13 18 17 6 24 -8 5 -11 5 -7 0z"/>
|
||||
<path d="M355 750 c3 -6 1 -10 -5 -10 -6 0 -9 -4 -5 -10 6 -10 35 -2 35 10 0
|
||||
4 -7 11 -16 14 -8 3 -12 2 -9 -4z"/>
|
||||
<path d="M1185 730 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M1469 733 c-1 -5 -1 -12 0 -17 1 -4 -6 -14 -16 -22 -16 -13 -16 -13
|
||||
6 -6 26 9 41 32 21 32 -6 0 -8 5 -5 10 3 6 4 10 1 10 -3 0 -7 -3 -7 -7z"/>
|
||||
<path d="M1147 701 c-4 -17 -2 -18 13 -8 10 6 16 15 14 19 -9 14 -22 9 -27
|
||||
-11z"/>
|
||||
<path d="M780 701 c0 -5 -12 -8 -27 -6 -26 3 -26 2 -8 -12 20 -15 20 -15 0
|
||||
-11 -15 4 -21 0 -21 -13 0 -11 4 -19 8 -19 4 0 8 5 8 10 0 6 6 10 14 10 8 0
|
||||
17 7 20 16 3 8 10 12 16 9 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
|
||||
<path d="M810 706 c0 -2 7 -7 16 -10 8 -3 12 -2 9 4 -6 10 -25 14 -25 6z"/>
|
||||
<path d="M1590 696 c7 -7 14 -6 21 1 9 9 7 12 -9 10 -14 -1 -18 -5 -12 -11z"/>
|
||||
<path d="M89 666 c-17 -19 -37 -32 -43 -30 -6 2 -20 -10 -30 -26 -19 -34 -17
|
||||
-50 4 -25 7 8 16 15 20 15 4 0 30 23 57 50 28 28 44 50 37 50 -7 0 -27 -15
|
||||
-45 -34z"/>
|
||||
<path d="M250 663 c-12 -21 -31 -43 -41 -51 -18 -13 -27 -42 -11 -42 4 0 18
|
||||
16 32 35 29 39 46 45 35 13 -3 -13 -6 -30 -6 -38 3 -56 0 -83 -8 -99 -14 -26
|
||||
-21 -71 -11 -71 7 0 20 38 25 70 0 3 4 10 8 16 10 17 17 204 7 204 -4 0 -18
|
||||
-17 -30 -37z"/>
|
||||
<path d="M375 690 c-3 -5 1 -10 9 -10 9 0 16 5 16 10 0 6 -4 10 -9 10 -6 0
|
||||
-13 -4 -16 -10z"/>
|
||||
<path d="M880 685 c-11 -13 -10 -14 4 -9 9 3 16 10 16 15 0 13 -6 11 -20 -6z"/>
|
||||
<path d="M923 687 c-3 -6 -1 -7 5 -3 7 4 12 2 12 -4 0 -6 5 -8 10 -5 6 3 10
|
||||
10 10 14 0 11 -30 9 -37 -2z"/>
|
||||
<path d="M1063 685 c-3 -9 -3 -19 1 -22 3 -4 6 1 6 10 0 10 4 17 8 17 14 0 32
|
||||
-23 32 -42 0 -16 3 -16 20 -6 18 12 19 13 2 19 -10 4 -24 14 -31 23 -17 20
|
||||
-30 20 -38 1z"/>
|
||||
<path d="M987 676 c-4 -10 0 -14 12 -13 11 1 17 7 14 14 -7 17 -20 17 -26 -1z"/>
|
||||
<path d="M1576 663 c-6 -14 -5 -15 5 -6 7 7 10 15 7 18 -3 3 -9 -2 -12 -12z"/>
|
||||
<path d="M1073 655 c-7 -8 -13 -19 -13 -25 0 -5 -4 -10 -10 -10 -5 0 -10 -6
|
||||
-10 -12 1 -15 50 38 50 53 0 12 -2 11 -17 -6z"/>
|
||||
<path d="M950 638 c0 -4 7 -8 15 -8 8 0 15 4 15 8 0 5 -7 9 -15 9 -8 0 -15 -4
|
||||
-15 -9z"/>
|
||||
<path d="M1215 640 c4 -6 11 -8 16 -5 14 9 11 15 -7 15 -8 0 -12 -5 -9 -10z"/>
|
||||
<path d="M480 620 c-13 -8 -12 -10 3 -10 9 0 17 5 17 10 0 12 -1 12 -20 0z"/>
|
||||
<path d="M894 622 c-6 -4 -14 -16 -17 -27 -7 -20 -7 -20 8 -1 8 11 21 23 27
|
||||
28 7 4 9 8 3 8 -5 0 -15 -4 -21 -8z"/>
|
||||
<path d="M728 608 c5 -5 16 -8 23 -6 8 3 3 7 -10 11 -17 4 -21 3 -13 -5z"/>
|
||||
<path d="M1405 610 c-3 -6 1 -7 9 -4 18 7 21 14 7 14 -6 0 -13 -4 -16 -10z"/>
|
||||
<path d="M1440 599 c0 -23 10 -28 35 -18 18 7 18 8 1 8 -11 1 -16 6 -13 14 3
|
||||
8 -1 14 -9 14 -8 0 -14 -8 -14 -18z"/>
|
||||
<path d="M813 595 c0 -8 4 -12 9 -9 5 3 6 10 3 15 -9 13 -12 11 -12 -6z"/>
|
||||
<path d="M1271 573 c2 -24 2 -25 6 -5 2 12 9 20 14 17 5 -4 9 -1 9 4 0 6 -7
|
||||
11 -15 11 -10 0 -15 -9 -14 -27z"/>
|
||||
<path d="M1125 580 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M1163 565 c0 -8 4 -12 9 -9 5 3 6 10 3 15 -9 13 -12 11 -12 -6z"/>
|
||||
<path d="M1880 573 c0 -5 7 -19 16 -31 8 -12 12 -22 9 -22 -3 0 1 -10 9 -22
|
||||
20 -28 20 -42 2 -35 -11 4 -11 1 -2 -18 6 -13 14 -21 18 -19 4 3 10 -8 13 -23
|
||||
4 -15 11 -38 16 -51 7 -17 6 -21 -3 -16 -8 5 -9 2 -4 -12 5 -10 9 -26 10 -34
|
||||
0 -8 5 -18 9 -21 5 -4 7 -16 5 -29 -3 -22 -3 -22 -25 -2 -13 10 -19 23 -15 27
|
||||
4 5 1 5 -5 1 -10 -5 -9 -13 3 -32 9 -13 20 -24 25 -24 5 0 9 -12 9 -27 0 -23
|
||||
-2 -25 -11 -13 -9 12 -10 11 -4 -5 4 -11 9 -53 12 -92 4 -55 10 -73 20 -73 13
|
||||
0 14 25 10 162 -4 147 -8 172 -35 254 -16 50 -37 104 -46 122 -16 31 -36 50
|
||||
-36 35z"/>
|
||||
<path d="M30 548 c-12 -22 -12 -22 6 -6 10 10 15 20 12 24 -4 3 -12 -5 -18
|
||||
-18z"/>
|
||||
<path d="M430 559 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1212 550 c-7 -11 -8 -20 -3 -20 9 0 24 30 18 36 -1 2 -8 -6 -15 -16z"/>
|
||||
<path d="M165 544 c21 -16 19 -37 -6 -52 -12 -8 -18 -19 -15 -28 3 -8 1 -14
|
||||
-5 -14 -6 0 -8 -9 -4 -19 4 -13 -5 -37 -24 -67 -16 -27 -27 -52 -24 -57 7 -12
|
||||
47 59 67 121 19 56 38 78 58 66 10 -6 9 -3 -1 9 -8 11 -9 17 -3 17 6 0 16 10
|
||||
22 23 9 18 9 20 -2 7 -18 -20 -42 -25 -35 -7 4 11 -2 14 -19 13 -20 -1 -22 -3
|
||||
-9 -12z"/>
|
||||
<path d="M998 553 c6 -2 9 -10 6 -15 -4 -7 -2 -8 5 -4 13 9 5 26 -12 25 -9 0
|
||||
-8 -2 1 -6z"/>
|
||||
<path d="M1463 540 c1 -21 12 -26 22 -10 3 6 1 10 -5 10 -6 0 -8 5 -5 10 3 6
|
||||
2 10 -4 10 -5 0 -9 -9 -8 -20z"/>
|
||||
<path d="M1045 518 c-4 -18 -17 -42 -29 -53 -12 -11 -17 -17 -11 -13 7 4 15 5
|
||||
18 1 4 -3 9 1 13 10 3 9 11 15 17 13 7 -1 9 -1 6 1 -3 2 -4 19 -2 38 4 44 -3
|
||||
45 -12 3z"/>
|
||||
<path d="M130 530 c-13 -8 -12 -10 3 -10 9 0 17 5 17 10 0 12 -1 12 -20 0z"/>
|
||||
<path d="M570 525 c-8 -9 -8 -15 -2 -15 12 0 26 19 19 26 -2 2 -10 -2 -17 -11z"/>
|
||||
<path d="M712 501 c-16 -17 -33 -27 -36 -23 -4 3 -4 -1 -1 -10 6 -14 12 -11
|
||||
41 19 19 20 33 37 31 40 -3 2 -18 -10 -35 -26z"/>
|
||||
<path d="M850 516 c0 -8 4 -17 9 -20 5 -4 7 3 4 14 -6 23 -13 26 -13 6z"/>
|
||||
<path d="M1436 516 c3 -9 1 -23 -6 -31 -7 -8 -8 -15 -4 -15 5 0 15 9 21 19 10
|
||||
16 9 22 -3 32 -12 10 -13 9 -8 -5z"/>
|
||||
<path d="M1260 510 c-8 -5 -10 -10 -5 -10 6 0 17 5 25 10 8 5 11 10 5 10 -5 0
|
||||
-17 -5 -25 -10z"/>
|
||||
<path d="M106 499 c10 -17 -56 -72 -71 -59 -8 7 -16 3 -25 -15 -7 -14 -10 -28
|
||||
-6 -32 4 -4 9 3 13 16 3 14 11 20 20 17 8 -3 32 11 55 32 34 32 38 40 24 45
|
||||
-11 5 -15 3 -10 -4z"/>
|
||||
<path d="M1225 500 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M635 474 c-9 -15 -12 -23 -6 -20 6 4 11 2 11 -3 0 -6 5 -11 11 -11 8
|
||||
0 8 5 -1 15 -7 8 -8 15 -3 15 5 0 10 7 10 15 0 20 -2 19 -22 -11z"/>
|
||||
<path d="M100 421 c0 -5 -6 -16 -12 -23 -51 -53 -40 -69 11 -17 34 34 39 49
|
||||
16 49 -8 0 -15 -4 -15 -9z"/>
|
||||
<path d="M176 388 c0 -23 6 -44 12 -46 14 -4 15 -55 2 -100 -8 -29 -7 -32 5
|
||||
-22 17 14 30 93 20 117 -15 33 -15 56 -3 71 11 13 10 15 -3 10 -9 -4 -21 -2
|
||||
-25 2 -6 6 -9 -8 -8 -32z"/>
|
||||
<path d="M735 420 c-3 -6 1 -7 9 -4 18 7 21 14 7 14 -6 0 -13 -4 -16 -10z"/>
|
||||
<path d="M1305 380 c-3 -5 1 -10 10 -10 9 0 13 5 10 10 -3 6 -8 10 -10 10 -2
|
||||
0 -7 -4 -10 -10z"/>
|
||||
<path d="M825 370 c-3 -5 -21 -10 -38 -10 -21 0 -28 -3 -19 -9 8 -4 13 -11 13
|
||||
-15 -4 -29 13 -37 22 -12 4 11 1 13 -11 9 -14 -5 -15 -3 -5 7 9 10 15 10 26 1
|
||||
15 -11 22 -7 41 27 9 14 -20 17 -29 2z"/>
|
||||
<path d="M11 323 c-10 -26 -10 -27 4 -9 8 11 15 23 15 28 0 15 -7 8 -19 -19z"/>
|
||||
<path d="M483 335 c-3 -9 -3 -18 -1 -21 3 -3 8 4 11 16 6 23 -1 27 -10 5z"/>
|
||||
<path d="M1840 340 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M570 320 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0 -4
|
||||
-4 -4 -10z"/>
|
||||
<path d="M873 317 c0 -8 6 -14 14 -14 9 0 10 4 2 14 -6 7 -12 13 -14 13 -1 0
|
||||
-2 -6 -2 -13z"/>
|
||||
<path d="M1356 317 c3 -10 9 -15 12 -12 3 3 0 11 -7 18 -10 9 -11 8 -5 -6z"/>
|
||||
<path d="M166 297 c3 -10 9 -15 12 -12 3 3 0 11 -7 18 -10 9 -11 8 -5 -6z"/>
|
||||
<path d="M94 285 c-10 -8 -15 -15 -10 -15 5 0 4 -6 -1 -12 -5 -7 -10 -29 -11
|
||||
-48 0 -33 0 -32 13 13 7 26 19 54 25 62 16 19 9 19 -16 0z"/>
|
||||
<path d="M492 284 c-12 -8 -28 -12 -35 -8 -6 4 -5 -1 4 -11 13 -13 21 -15 37
|
||||
-6 20 11 38 41 24 41 -4 0 -18 -7 -30 -16z"/>
|
||||
<path d="M590 291 c0 -6 5 -11 11 -11 5 0 7 -4 4 -10 -3 -5 -1 -10 4 -10 16 0
|
||||
13 16 -4 30 -10 9 -15 9 -15 1z"/>
|
||||
<path d="M747 293 c-4 -3 -7 -13 -7 -22 1 -13 3 -13 11 2 11 19 8 33 -4 20z"/>
|
||||
<path d="M127 283 c-11 -18 -4 -63 9 -63 16 0 19 16 4 25 -6 4 -8 15 -5 26 6
|
||||
19 1 26 -8 12z"/>
|
||||
<path d="M627 256 c-3 -8 5 -22 19 -33 13 -10 22 -24 19 -30 -9 -26 11 -12 28
|
||||
19 13 23 21 28 26 19 7 -10 9 -9 14 2 3 9 -1 18 -9 21 -8 3 -17 0 -20 -7 -7
|
||||
-19 -44 -14 -59 7 -11 14 -14 14 -18 2z"/>
|
||||
<path d="M1075 250 c-10 -11 -14 -20 -9 -20 5 0 17 9 27 20 9 11 13 20 8 20
|
||||
-4 0 -16 -9 -26 -20z"/>
|
||||
<path d="M1155 261 c-3 -5 -2 -12 3 -15 5 -3 9 1 9 9 0 17 -3 19 -12 6z"/>
|
||||
<path d="M1450 245 c-7 -8 -16 -12 -21 -9 -5 3 -9 -2 -9 -10 0 -9 7 -16 15
|
||||
-16 8 0 15 7 15 15 0 7 8 19 18 24 9 6 12 11 6 11 -6 0 -17 -7 -24 -15z"/>
|
||||
<path d="M1516 233 c10 -40 15 -42 12 -5 -1 18 -6 32 -10 32 -5 0 -5 -12 -2
|
||||
-27z"/>
|
||||
<path d="M40 219 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10 -5
|
||||
-10 -11z"/>
|
||||
<path d="M1010 189 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1136 192 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
|
||||
-9 -8z"/>
|
||||
<path d="M583 175 c-7 -8 -13 -18 -13 -22 0 -4 -11 -21 -25 -37 -30 -35 -31
|
||||
-40 -5 -24 10 7 27 27 37 45 9 17 20 30 25 27 4 -3 5 2 2 10 -7 19 -6 19 -21
|
||||
1z"/>
|
||||
<path d="M920 181 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
|
||||
<path d="M1531 170 c0 -8 4 -24 9 -35 9 -20 9 -20 9 0 0 11 -4 27 -9 35 -9 13
|
||||
-10 13 -9 0z"/>
|
||||
<path d="M1418 156 c-10 -7 -18 -19 -18 -26 0 -7 9 -3 20 10 28 33 27 39 -2
|
||||
16z"/>
|
||||
<path d="M520 145 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M1602 140 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
|
||||
<path d="M730 129 c0 -10 5 -21 12 -25 7 -4 8 -3 4 5 -4 6 -3 18 3 25 8 9 7
|
||||
13 -4 13 -8 0 -15 -8 -15 -18z"/>
|
||||
<path d="M666 131 c-4 -7 -5 -15 -2 -18 9 -9 19 4 14 18 -4 11 -6 11 -12 0z"/>
|
||||
<path d="M496 121 c-5 -7 -18 -16 -30 -21 -20 -8 -20 -9 -1 -9 27 -1 48 14 43
|
||||
30 -3 10 -6 10 -12 0z"/>
|
||||
<path d="M923 114 c-15 -16 -16 -24 -4 -24 8 0 24 30 19 35 -2 2 -9 -3 -15
|
||||
-11z"/>
|
||||
<path d="M1497 103 c-3 -16 -3 -30 -1 -33 7 -7 24 23 24 43 0 27 -17 20 -23
|
||||
-10z"/>
|
||||
<path d="M832 105 c3 -3 -5 -18 -17 -31 -13 -14 -21 -32 -18 -40 6 -16 26 -8
|
||||
20 9 -2 6 7 21 20 33 21 20 22 22 6 28 -10 4 -15 4 -11 1z"/>
|
||||
<path d="M380 75 c-7 -9 -10 -18 -6 -22 3 -3 6 -1 6 6 0 7 3 10 8 8 4 -3 13 1
|
||||
20 9 10 11 10 14 -1 14 -8 0 -20 -7 -27 -15z"/>
|
||||
<path d="M1026 73 c-6 -14 -5 -15 5 -6 7 7 10 15 7 18 -3 3 -9 -2 -12 -12z"/>
|
||||
<path d="M450 65 c-7 -8 -8 -15 -2 -15 5 0 15 7 22 15 7 8 8 15 2 15 -5 0 -15
|
||||
-7 -22 -15z"/>
|
||||
<path d="M1920 71 c0 -6 5 -13 11 -16 6 -4 8 -14 4 -22 -4 -13 -3 -14 9 -4 13
|
||||
11 13 15 -2 32 -19 21 -22 23 -22 10z"/>
|
||||
<path d="M66 61 c-6 -9 9 -61 18 -61 2 0 6 8 8 18 6 21 -17 58 -26 43z"/>
|
||||
<path d="M1391 63 c-1 -17 16 -25 25 -12 4 7 3 9 -4 5 -5 -3 -13 0 -15 6 -4 9
|
||||
-6 10 -6 1z"/>
|
||||
<path d="M280 50 c-8 -5 -12 -11 -9 -14 2 -3 11 -1 19 4 8 5 12 11 9 14 -2 3
|
||||
-11 1 -19 -4z"/>
|
||||
<path d="M1252 40 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
|
||||
<path d="M1465 50 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M1626 48 c-7 -21 -3 -48 5 -43 4 3 6 13 5 23 -2 9 4 20 13 24 14 6
|
||||
14 7 -2 7 -10 1 -19 -5 -21 -11z"/>
|
||||
<path d="M7 25 c-4 -26 -4 -26 14 -6 23 24 24 31 5 31 -7 0 -16 -11 -19 -25z"/>
|
||||
<path d="M1520 38 c0 -9 -8 -22 -17 -27 -16 -9 -16 -10 -2 -11 24 0 40 23 29
|
||||
40 -8 13 -10 12 -10 -2z"/>
|
||||
<path d="M930 31 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
|
||||
<path d="M735 20 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0 -8
|
||||
-4 -11 -10z"/>
|
||||
</g>
|
||||
<path d="M0 0 h 300 v 15 h -300 z"/>
|
||||
<path d="M0 285 h 300 v 15 h -300 z"/>
|
||||
<path d="M0 0 v 300 h 15 v -300 z"/>
|
||||
<path d="M285 0 v 300 h 15 v -300 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 54 KiB |
@@ -1,9 +1,9 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::fixtures::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::targets::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::targets::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
@@ -1,18 +1,18 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::fixtures::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::iterators::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use crate::prolog::ordered_float::*;
|
||||
use crate::prolog::rug::ops::PowAssign;
|
||||
use crate::prolog::rug::{Assign, Integer, Rational};
|
||||
use crate::ordered_float::*;
|
||||
use crate::rug::ops::PowAssign;
|
||||
use crate::rug::{Assign, Integer, Rational};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp::{max, min, Ordering};
|
||||
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::forms::Number;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::rug::rand::RandState;
|
||||
use crate::forms::Number;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::rug::rand::RandState;
|
||||
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@@ -171,6 +171,16 @@ pub enum SystemClauseType {
|
||||
CurrentHostname,
|
||||
CurrentInput,
|
||||
CurrentOutput,
|
||||
DirectoryFiles,
|
||||
FileSize,
|
||||
FileExists,
|
||||
DirectoryExists,
|
||||
DirectorySeparator,
|
||||
MakeDirectory,
|
||||
DeleteFile,
|
||||
WorkingDirectory,
|
||||
PathCanonical,
|
||||
FileTime,
|
||||
DeleteAttribute,
|
||||
DeleteHeadAttribute,
|
||||
DynamicModuleResolution(usize),
|
||||
@@ -180,11 +190,11 @@ pub enum SystemClauseType {
|
||||
ExpandTerm,
|
||||
FetchGlobalVar,
|
||||
FetchGlobalVarWithOffset,
|
||||
FileToChars,
|
||||
FirstStream,
|
||||
FlushOutput,
|
||||
GetByte,
|
||||
GetChar,
|
||||
GetNChars,
|
||||
GetCode,
|
||||
GetSingleChar,
|
||||
ResetAttrVarState,
|
||||
@@ -229,8 +239,8 @@ pub enum SystemClauseType {
|
||||
PeekCode,
|
||||
PointsToContinuationResetMarker,
|
||||
PutByte,
|
||||
PutBytes,
|
||||
PutChar,
|
||||
PutChars,
|
||||
PutCode,
|
||||
REPL(REPLCodePtr),
|
||||
ReadQueryTerm,
|
||||
@@ -261,6 +271,7 @@ pub enum SystemClauseType {
|
||||
InstallNewBlock,
|
||||
Maybe,
|
||||
CpuNow,
|
||||
CurrentTime,
|
||||
QuotedToken,
|
||||
ReadTermFromChars,
|
||||
ResetBlock,
|
||||
@@ -293,10 +304,18 @@ pub enum SystemClauseType {
|
||||
CryptoPasswordHash,
|
||||
CryptoDataEncrypt,
|
||||
CryptoDataDecrypt,
|
||||
CryptoCurveScalarMult,
|
||||
Ed25519Sign,
|
||||
Ed25519Verify,
|
||||
Ed25519NewKeyPair,
|
||||
Ed25519KeyPairPublicKey
|
||||
Ed25519KeyPairPublicKey,
|
||||
Curve25519ScalarMult,
|
||||
LoadHTML,
|
||||
LoadXML,
|
||||
GetEnv,
|
||||
SetEnv,
|
||||
UnsetEnv,
|
||||
CharsBase64,
|
||||
}
|
||||
|
||||
impl SystemClauseType {
|
||||
@@ -324,6 +343,16 @@ impl SystemClauseType {
|
||||
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
||||
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
||||
&SystemClauseType::CurrentOutput => clause_name!("$current_output"),
|
||||
&SystemClauseType::DirectoryFiles => clause_name!("$directory_files"),
|
||||
&SystemClauseType::FileSize => clause_name!("$file_size"),
|
||||
&SystemClauseType::FileExists => clause_name!("$file_exists"),
|
||||
&SystemClauseType::DirectoryExists => clause_name!("$directory_exists"),
|
||||
&SystemClauseType::DirectorySeparator => clause_name!("$directory_separator"),
|
||||
&SystemClauseType::MakeDirectory => clause_name!("$make_directory"),
|
||||
&SystemClauseType::DeleteFile => clause_name!("$delete_file"),
|
||||
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
||||
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
||||
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
|
||||
@@ -348,11 +377,11 @@ impl SystemClauseType {
|
||||
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||
clause_name!("$fetch_global_var_with_offset")
|
||||
}
|
||||
&SystemClauseType::FileToChars => clause_name!("$file_to_chars"),
|
||||
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
||||
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
||||
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
||||
&SystemClauseType::GetChar => clause_name!("$get_char"),
|
||||
&SystemClauseType::GetNChars => clause_name!("$get_n_chars"),
|
||||
&SystemClauseType::GetCode => clause_name!("$get_code"),
|
||||
&SystemClauseType::GetSingleChar => clause_name!("$get_single_char"),
|
||||
&SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"),
|
||||
@@ -397,6 +426,7 @@ impl SystemClauseType {
|
||||
&SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
|
||||
&SystemClauseType::Maybe => clause_name!("maybe"),
|
||||
&SystemClauseType::CpuNow => clause_name!("$cpu_now"),
|
||||
&SystemClauseType::CurrentTime => clause_name!("$current_time"),
|
||||
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
|
||||
clause_name!("$module_asserta")
|
||||
}
|
||||
@@ -416,12 +446,12 @@ impl SystemClauseType {
|
||||
&SystemClauseType::PutByte => {
|
||||
clause_name!("$put_byte")
|
||||
}
|
||||
&SystemClauseType::PutBytes => {
|
||||
clause_name!("$put_bytes")
|
||||
}
|
||||
&SystemClauseType::PutChar => {
|
||||
clause_name!("$put_char")
|
||||
}
|
||||
&SystemClauseType::PutChars => {
|
||||
clause_name!("$put_chars")
|
||||
}
|
||||
&SystemClauseType::PutCode => {
|
||||
clause_name!("$put_code")
|
||||
}
|
||||
@@ -488,10 +518,18 @@ impl SystemClauseType {
|
||||
&SystemClauseType::CryptoPasswordHash => clause_name!("$crypto_password_hash"),
|
||||
&SystemClauseType::CryptoDataEncrypt => clause_name!("$crypto_data_encrypt"),
|
||||
&SystemClauseType::CryptoDataDecrypt => clause_name!("$crypto_data_decrypt"),
|
||||
&SystemClauseType::CryptoCurveScalarMult => clause_name!("$crypto_curve_scalar_mult"),
|
||||
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
||||
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
||||
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
|
||||
&SystemClauseType::Ed25519KeyPairPublicKey => clause_name!("$ed25519_keypair_public_key")
|
||||
&SystemClauseType::Ed25519KeyPairPublicKey => clause_name!("$ed25519_keypair_public_key"),
|
||||
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
|
||||
&SystemClauseType::LoadHTML => clause_name!("$load_html"),
|
||||
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
||||
&SystemClauseType::GetEnv => clause_name!("$getenv"),
|
||||
&SystemClauseType::SetEnv => clause_name!("$setenv"),
|
||||
&SystemClauseType::UnsetEnv => clause_name!("$unsetenv"),
|
||||
&SystemClauseType::CharsBase64 => clause_name!("$chars_base64"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,9 +583,9 @@ impl SystemClauseType {
|
||||
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
|
||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
||||
("$file_to_chars", 3) => Some(SystemClauseType::FileToChars),
|
||||
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
||||
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
||||
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
||||
("$get_code", 2) => Some(SystemClauseType::GetCode),
|
||||
("$get_single_char", 1) => Some(SystemClauseType::GetSingleChar),
|
||||
("$points_to_cont_reset_marker", 1) => {
|
||||
@@ -556,12 +594,12 @@ impl SystemClauseType {
|
||||
("$put_byte", 2) => {
|
||||
Some(SystemClauseType::PutByte)
|
||||
}
|
||||
("$put_bytes", 2) => {
|
||||
Some(SystemClauseType::PutBytes)
|
||||
}
|
||||
("$put_char", 2) => {
|
||||
Some(SystemClauseType::PutChar)
|
||||
}
|
||||
("$put_chars", 2) => {
|
||||
Some(SystemClauseType::PutChars)
|
||||
}
|
||||
("$put_code", 2) => {
|
||||
Some(SystemClauseType::PutCode)
|
||||
}
|
||||
@@ -580,13 +618,14 @@ impl SystemClauseType {
|
||||
("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
||||
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||
("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
|
||||
("$halt", 0) => Some(SystemClauseType::Halt),
|
||||
("$halt", 1) => Some(SystemClauseType::Halt),
|
||||
("$head_is_dynamic", 1) => Some(SystemClauseType::HeadIsDynamic),
|
||||
("$install_scc_cleaner", 2) => Some(SystemClauseType::InstallSCCCleaner),
|
||||
("$install_inference_counter", 3) => Some(SystemClauseType::InstallInferenceCounter),
|
||||
("$lh_length", 1) => Some(SystemClauseType::LiftedHeapLength),
|
||||
("$maybe", 0) => Some(SystemClauseType::Maybe),
|
||||
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
|
||||
("$current_time", 1) => Some(SystemClauseType::CurrentTime),
|
||||
("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
|
||||
("$module_of", 2) => Some(SystemClauseType::ModuleOf),
|
||||
("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
|
||||
@@ -633,7 +672,7 @@ impl SystemClauseType {
|
||||
("$set_seed", 1) => Some(SystemClauseType::SetSeed),
|
||||
("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
|
||||
("$sleep", 1) => Some(SystemClauseType::Sleep),
|
||||
("$socket_client_open", 7) => Some(SystemClauseType::SocketClientOpen),
|
||||
("$socket_client_open", 8) => Some(SystemClauseType::SocketClientOpen),
|
||||
("$socket_server_open", 3) => Some(SystemClauseType::SocketServerOpen),
|
||||
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
||||
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
||||
@@ -645,6 +684,16 @@ impl SystemClauseType {
|
||||
("$unwind_environments", 0) => Some(SystemClauseType::UnwindEnvironments),
|
||||
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
||||
("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck),
|
||||
("$directory_files", 2) => Some(SystemClauseType::DirectoryFiles),
|
||||
("$file_size", 2) => Some(SystemClauseType::FileSize),
|
||||
("$file_exists", 1) => Some(SystemClauseType::FileExists),
|
||||
("$directory_exists", 1) => Some(SystemClauseType::DirectoryExists),
|
||||
("$directory_separator", 1) => Some(SystemClauseType::DirectorySeparator),
|
||||
("$make_directory", 1) => Some(SystemClauseType::MakeDirectory),
|
||||
("$delete_file", 1) => Some(SystemClauseType::DeleteFile),
|
||||
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
||||
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
||||
("$file_time", 3) => Some(SystemClauseType::FileTime),
|
||||
("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||
("$use_module_from_file", 1) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)),
|
||||
@@ -658,15 +707,23 @@ impl SystemClauseType {
|
||||
("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
|
||||
("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion),
|
||||
("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte),
|
||||
("$crypto_data_hash", 3) => Some(SystemClauseType::CryptoDataHash),
|
||||
("$crypto_data_hkdf", 6) => Some(SystemClauseType::CryptoDataHKDF),
|
||||
("$crypto_data_hash", 4) => Some(SystemClauseType::CryptoDataHash),
|
||||
("$crypto_data_hkdf", 7) => Some(SystemClauseType::CryptoDataHKDF),
|
||||
("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash),
|
||||
("$crypto_data_encrypt", 5) => Some(SystemClauseType::CryptoDataEncrypt),
|
||||
("$crypto_data_decrypt", 5) => Some(SystemClauseType::CryptoDataDecrypt),
|
||||
("$ed25519_sign", 3) => Some(SystemClauseType::Ed25519Sign),
|
||||
("$ed25519_verify", 3) => Some(SystemClauseType::Ed25519Verify),
|
||||
("$crypto_data_encrypt", 6) => Some(SystemClauseType::CryptoDataEncrypt),
|
||||
("$crypto_data_decrypt", 6) => Some(SystemClauseType::CryptoDataDecrypt),
|
||||
("$crypto_curve_scalar_mult", 5) => Some(SystemClauseType::CryptoCurveScalarMult),
|
||||
("$ed25519_sign", 5) => Some(SystemClauseType::Ed25519Sign),
|
||||
("$ed25519_verify", 5) => Some(SystemClauseType::Ed25519Verify),
|
||||
("$ed25519_new_keypair", 1) => Some(SystemClauseType::Ed25519NewKeyPair),
|
||||
("$ed25519_keypair_public_key", 2) => Some(SystemClauseType::Ed25519KeyPairPublicKey),
|
||||
("$ed25519_keypair_public_key", 3) => Some(SystemClauseType::Ed25519KeyPairPublicKey),
|
||||
("$curve25519_scalar_mult", 3) => Some(SystemClauseType::Curve25519ScalarMult),
|
||||
("$load_html", 3) => Some(SystemClauseType::LoadHTML),
|
||||
("$load_xml", 3) => Some(SystemClauseType::LoadXML),
|
||||
("$getenv", 2) => Some(SystemClauseType::GetEnv),
|
||||
("$setenv", 2) => Some(SystemClauseType::SetEnv),
|
||||
("$unsetenv", 1) => Some(SystemClauseType::UnsetEnv),
|
||||
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::allocator::*;
|
||||
use crate::prolog::arithmetic::*;
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::fixtures::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::indexing::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::iterators::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::targets::*;
|
||||
use crate::allocator::*;
|
||||
use crate::arithmetic::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::indexing::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::targets::*;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
@@ -1,12 +1,12 @@
|
||||
use indexmap::IndexMap;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::allocator::*;
|
||||
use crate::prolog::fixtures::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::targets::*;
|
||||
use crate::allocator::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::targets::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::BTreeSet;
|
||||
219
src/examples/bimetatrans/README.md
Normal file
219
src/examples/bimetatrans/README.md
Normal file
@@ -0,0 +1,219 @@
|
||||
### BiMetaTrans 1.0
|
||||
|
||||
BiMetaTrans(Prolog, RuleML) is a bidirectional translator capable of
|
||||
parsing and generating a well-formed sublanguage of RuleML/XML to/from
|
||||
a metalogical encoding of our own design called Prolog/'$V'. For later
|
||||
ease of reference:
|
||||
|
||||
* Prolog/'$V' stands for "Metalogic Prolog with variable-as-'$V'-term encoding"
|
||||
* RuleML/XML stands for "RuleML in XML with any kind of rendering"
|
||||
* RuleML/xmL stands for "RuleML in minified XML"
|
||||
* RuleML/Xml stands for "RuleML in indented XML"
|
||||
|
||||
"Minified XML" refers to XML with only necessary whitespace, between
|
||||
element names and attributes, and pairs of attributes, with all
|
||||
indentation stripped out. "Indented XML" contains indentation and
|
||||
newlines, and is usually formatted for human readers.
|
||||
|
||||
The specification of Prolog/'$V', and of the NafHornlogEq sublanguage
|
||||
of RuleML/XML targeted by BiMetaTrans, is contained in the preprint
|
||||
[Invertible Bidirectional Metalogical Translation Between Prolog and
|
||||
RuleML/XML for Knowledge Representation and
|
||||
Querying](http://ruleml.org/papers/RuleMLXMLBiDirTransScryer.pdf) and
|
||||
its accompanying talk
|
||||
[slides](http://ruleml.org/talks/RuleMLXMLBiDirTransScryer-talk.pdf). The
|
||||
preprint and talk also describe the implementation of BiMetaTrans
|
||||
found here, and outlines a strategy for proving the invertibility of
|
||||
BiMetaTrans.
|
||||
|
||||
BiMetaTrans exports a single public predicate subsuming its user
|
||||
API, `parse_ruleml/3`. It has two modes, each corresponding to a single
|
||||
direction of translation:
|
||||
|
||||
```
|
||||
parse_ruleml(+AssertItems, +QueryItems, ?XML) (Prolog->RuleML)
|
||||
parse_ruleml(?AssertItems, ?QueryItems, +XML) (RuleML->Prolog)
|
||||
```
|
||||
|
||||
The modes constrain the inputs to fit one of two patterns, the
|
||||
first where AssertItems and QueryItems are instantiated and XML is
|
||||
possibly a variable, and conversely for the second. Instantiated
|
||||
inputs are expected to be ground, meaning they should not contain
|
||||
free variables.
|
||||
|
||||
We explore several examples of its use in Scryer Prolog.
|
||||
|
||||
Loading BiMetaTrans from the Scryer REPL:
|
||||
|
||||
```
|
||||
?- use_module('src/examples/bimetatrans/bimetatrans').
|
||||
```
|
||||
|
||||
Using `write/1` to print the string to standard output, capturing the
|
||||
`Prolog->RuleML` direction (`write/1` is used because it does not
|
||||
print strings with escape characters, ie., `\"` for double quote):
|
||||
|
||||
```
|
||||
?- parse_ruleml([people('Alex',male),people('Alex',female),people('Siri',female)], [], XML),
|
||||
write(XML).
|
||||
"<Assert mapClosure="universal"><Atom><Rel>people</Rel><Ind>Alex</Ind><Data iso:type="symbol">male</Data></Atom><Atom><Rel>people</Rel><Ind>Alex</Ind><Data iso:type="symbol">female</Data></Atom><Atom><Rel>people</Rel><Ind>Siri</Ind><Data iso:type="symbol">female</Data></Atom></Assert>" XML = "<Assert mapClosure= ...".
|
||||
```
|
||||
|
||||
Note that the XML input can contain extraneous whitespace and
|
||||
indentation while generated XML never does (ie., the XML generated by
|
||||
BiMetaTrans is always Ruleml/xmL). `\` is used to continue ISO Prolog
|
||||
strings to the next line but is never stored to the string by the
|
||||
Prolog reader.
|
||||
|
||||
Performing the inverse translation of the previous example
|
||||
(`RuleML->Prolog`), in RuleML/Xml:
|
||||
|
||||
```
|
||||
?- parse_ruleml(AssertItems, QueryItems,
|
||||
"<Assert mapClosure=\"universal\">\
|
||||
<Atom>\
|
||||
<Rel>people</Rel>\
|
||||
<Ind>Alex</Ind>\
|
||||
<Data iso:type=\"symbol\">male</Data>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>people</Rel>\
|
||||
<Ind>Alex</Ind>\
|
||||
<Data iso:type=\"symbol\">female</Data>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>people</Rel>\
|
||||
<Ind>Siri</Ind>\
|
||||
<Data iso:type=\"symbol\">female</Data>\
|
||||
</Atom>\
|
||||
</Assert>").
|
||||
AssertItems = [people('Alex',male),people('Alex',female),people('Siri',female)], QueryItems = [].
|
||||
```
|
||||
|
||||
Double quote characters within strings must be escaped as in
|
||||
`\"`. Non-empty AssertItems and QueryItems lists generated to
|
||||
RuleML/xmL simultaneously:
|
||||
|
||||
```
|
||||
?- parse_ruleml([a(item), b(item), c(item)], [(?- p, q, r(1), s(-2.222342432), t("attached")), (?- u, v('$V'(q)))], XML),
|
||||
write(XML).
|
||||
"<Assert mapClosure="universal"><Atom><Rel>a</Rel><Data iso:type="symbol">item</Data></Atom><Atom><Rel>b</Rel><Data iso:type="symbol">item</Data></Atom><Atom><Rel>c</Rel><Data iso:type="symbol">item</Data></Atom></Assert><Query closure="existential"><And><Atom><Rel>p</Rel></Atom><Atom><Rel>q</Rel></Atom><Atom><Rel>r</Rel><Data iso:type="number">1</Data></Atom><Atom><Rel>s</Rel><Data iso:type="number">-2.222342432</Data></Atom><Atom><Rel>t</Rel><Data iso:type="string">"attached"</Data></Atom></And></Query><Query closure="existential"><And><Atom><Rel>u</Rel></Atom><Atom><Rel>v</Rel><Var>q</Var></Atom></And></Query>" XML = "<Assert mapClosure= ...".
|
||||
```
|
||||
|
||||
To insert escape characters into the printed RuleML/xmL, we use
|
||||
`writeq/1` in place of `write/1`:
|
||||
|
||||
```
|
||||
?- parse_ruleml([a(item), b(item), c(item)], [(?- p, q, r(1), s(-2.222342432), t("attached")), (?- u, v('$V'(q)))], XML),
|
||||
writeq(XML).
|
||||
"<Assert mapClosure=\"universal\"><Atom><Rel>a</Rel><Data iso:type=\"symbol\">item</Data></Atom><Atom><Rel>b</Rel><Data iso:type=\"symbol\">item</Data></Atom><Atom><Rel>c</Rel><Data iso:type=\"symbol\">item</Data></Atom></Assert><Query closure=\"existential\"><And><Atom><Rel>p</Rel></Atom><Atom><Rel>q</Rel></Atom><Atom><Rel>r</Rel><Data iso:type=\"number\">1</Data></Atom><Atom><Rel>s</Rel><Data iso:type=\"number\">-2.222342432</Data></Atom><Atom><Rel>t</Rel><Data iso:type=\"string\">\"attached\"</Data></Atom></And></Query><Query closure=\"existential\"><And><Atom><Rel>u</Rel></Atom><Atom><Rel>v</Rel><Var>q</Var></Atom></And></Query>" XML = "<Assert mapClosure= ...".
|
||||
```
|
||||
|
||||
XML can be pretty printed using a [free online XML pretty
|
||||
printer](https://codebeautify.org/xmlviewer), as here:
|
||||
|
||||
```
|
||||
<Assert mapClosure=\"universal\">
|
||||
<Atom>
|
||||
<Rel>a</Rel>
|
||||
<Data iso:type=\"symbol\">item</Data>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>b</Rel>
|
||||
<Data iso:type=\"symbol\">item</Data>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>c</Rel>
|
||||
<Data iso:type=\"symbol\">item</Data>
|
||||
</Atom>
|
||||
</Assert>
|
||||
<Query closure=\"existential\">
|
||||
<And>
|
||||
<Atom>
|
||||
<Rel>p</Rel>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>q</Rel>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>r</Rel>
|
||||
<Data iso:type=\"number\">1</Data>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>s</Rel>
|
||||
<Data iso:type=\"number\">-2.222342432</Data>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>t</Rel>
|
||||
<Data iso:type=\"string\">\"attached\"</Data>
|
||||
</Atom>
|
||||
</And>
|
||||
</Query>
|
||||
<Query closure=\"existential\">
|
||||
<And>
|
||||
<Atom>
|
||||
<Rel>u</Rel>
|
||||
</Atom>
|
||||
<Atom>
|
||||
<Rel>v</Rel>
|
||||
<Var>q</Var>
|
||||
</Atom>
|
||||
</And>
|
||||
</Query>
|
||||
```
|
||||
|
||||
The AssertItems and QueryItems lists can then be recovered using this
|
||||
RuleML/Xml string, with the `\` character added to the end of each
|
||||
line:
|
||||
|
||||
```
|
||||
?- parse_ruleml(AssertItems, QueryItems,
|
||||
"<Assert mapClosure=\"universal\">\
|
||||
<Atom>\
|
||||
<Rel>a</Rel>\
|
||||
<Data iso:type=\"symbol\">item</Data>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>b</Rel>\
|
||||
<Data iso:type=\"symbol\">item</Data>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>c</Rel>\
|
||||
<Data iso:type=\"symbol\">item</Data>\
|
||||
</Atom>\
|
||||
</Assert>\
|
||||
<Query closure=\"existential\">\
|
||||
<And>\
|
||||
<Atom>\
|
||||
<Rel>p</Rel>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>q</Rel>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>r</Rel>\
|
||||
<Data iso:type=\"number\">1</Data>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>s</Rel>\
|
||||
<Data iso:type=\"number\">-2.222342432</Data>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>t</Rel>\
|
||||
<Data iso:type=\"string\">\"attached\"</Data>\
|
||||
</Atom>\
|
||||
</And>\
|
||||
</Query>\
|
||||
<Query closure=\"existential\">\
|
||||
<And>\
|
||||
<Atom>\
|
||||
<Rel>u</Rel>\
|
||||
</Atom>\
|
||||
<Atom>\
|
||||
<Rel>v</Rel>\
|
||||
<Var>q</Var>\
|
||||
</Atom>\
|
||||
</And>\
|
||||
</Query>").
|
||||
AssertItems = [a(item),b(item),c(item)], QueryItems = [(?-p,q,r(1),s(-2.222342432),t("attached")),(?-u,v('$V'(q)))].
|
||||
```
|
||||
@@ -1,4 +1,4 @@
|
||||
:- module(bimetatrans_ruleml, [parse_ruleml/3]).
|
||||
:- module(bimetatrans, [parse_ruleml/3]).
|
||||
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(iso_ext)).
|
||||
@@ -19,28 +19,34 @@
|
||||
* all indentation stripped out. "Indented XML" contains indentation
|
||||
* and newlines, and is usually formatted for human readers.
|
||||
*
|
||||
* parse_ruleml/3 is the sole public predicate of BiMetaTrans(RuleML,
|
||||
* Prolog), a bidirectional translator capable of parsing well-formed
|
||||
* parse_ruleml/3 is the sole public predicate of BiMetaTrans(Prolog,
|
||||
* RuleML), a bidirectional translator capable of parsing well-formed
|
||||
* RuleML/XML (valid w.r.t. a proposed anchor schema nafhornlogeq
|
||||
* defining a sublanguage of the existing anchor schema naffologeq) to
|
||||
* an equivalent Prolog/'$V' term and back to RuleML/xmL. It has the
|
||||
* modes
|
||||
*
|
||||
* +AssertItem, +QueryItems, ?XML (Prolog->RuleML)
|
||||
* ?AssertItem, ?QueryItems, +XML (RuleML->Prolog)
|
||||
* +AssertItems, +QueryItems, ?XML (Prolog->RuleML)
|
||||
* ?AssertItems, ?QueryItems, +XML (RuleML->Prolog)
|
||||
*
|
||||
* The modes constrain the inputs to fit one of two patterns, the
|
||||
* first where AssertItem and QueryItem are instantiated and XML is
|
||||
* first where AssertItems and QueryItems are instantiated and XML is
|
||||
* possibly a variable, and conversely for the second. Instantiated
|
||||
* inputs are expected to be ground, meaning they should not contain
|
||||
* free variables.
|
||||
*
|
||||
* A RuleML/XML document is assumed to contain an optional Assert
|
||||
* element (with zero or more children) and zero or more Query
|
||||
* elements. The children of the Assert element are the Items of
|
||||
* AssertItems, while the Items of QueryItems each correspond to a
|
||||
* single Query element.
|
||||
*
|
||||
* parse_ruleml/3 is meant to subsume an invertible function in the
|
||||
* sense that the top-level query
|
||||
*
|
||||
* ?- parse_ruleml(AssertItem, QueryItems, XML0), % Prolog->RuleML
|
||||
* parse_ruleml(AssertItem0, QueryItems0, XML), % RuleML->Prolog
|
||||
* AssertItem0 == AssertItem, % Test for expected round-trip results.
|
||||
* ?- parse_ruleml(AssertItems, QueryItems, XML0), % Prolog->RuleML
|
||||
* parse_ruleml(AssertItems0, QueryItems0, XML), % RuleML->Prolog
|
||||
* AssertItems0 == AssertItems, % Test for expected round-trip results.
|
||||
* QueryItems0 == QueryItems,
|
||||
* XML0 == XML.
|
||||
*
|
||||
@@ -48,10 +54,11 @@
|
||||
* not 0-appended are instantiated and therefore ground.
|
||||
*/
|
||||
|
||||
parse_ruleml(AssertItem, QueryItem, XML) :-
|
||||
( ( var(AssertItem) ; var(QueryItem) ), var(XML) ->
|
||||
parse_ruleml(AssertItems, QueryItems, XML) :-
|
||||
( ( var(AssertItems) ; var(QueryItems) ), var(XML) ->
|
||||
throw(error(instantiation_error, parse_ruleml/2))
|
||||
; phrase(ruleml_top_level_items(AssertItem, QueryItem), XML)
|
||||
; phrase(ruleml_top_level_items(AssertItems, QueryItems), XML),
|
||||
!
|
||||
).
|
||||
|
||||
|
||||
@@ -82,24 +89,15 @@ parse_header -->
|
||||
*
|
||||
* The two arguments are (un)instantiated depending on the direction
|
||||
* in which parse_ruleml/2 operates. In either direction, once
|
||||
* ruleml_query_item(QueryItems) or ruleml_assert(AssertItem)
|
||||
* succeeds:
|
||||
*
|
||||
* 1) AssertItem/QueryItems is a fully ground list of terms,
|
||||
* corresponding to an Assert/Query performative of the RuleML/XML KB.
|
||||
*
|
||||
* 2) It would not be meaningful to backtrack after the last success,
|
||||
* thus undoing its effects; that is because we have already refuted
|
||||
* the possibility of there being further items for the grammar to
|
||||
* consume. Hence we see that the cut (!) does not restrict the
|
||||
* generality of the grammar.
|
||||
* ruleml_query_item(QueryItems) or ruleml_assert(AssertItems)
|
||||
* succeeds, AssertItems and QueryItems are ground lists of terms,
|
||||
* corresponding to Assert/Query performative(s) of the RuleML/XML KB.
|
||||
*/
|
||||
|
||||
ruleml_top_level_items(AssertItem, QueryItems) -->
|
||||
( ruleml_assert(AssertItem),
|
||||
ruleml_query_items(QueryItems),
|
||||
!
|
||||
; { AssertItem = [] },
|
||||
ruleml_top_level_items(AssertItems, QueryItems) -->
|
||||
( ruleml_assert(AssertItems),
|
||||
ruleml_query_items(QueryItems)
|
||||
; { AssertItems = [] },
|
||||
ruleml_query_items(QueryItems)
|
||||
).
|
||||
|
||||
@@ -169,22 +167,16 @@ ruleml_top_level_items(AssertItem, QueryItems) -->
|
||||
* outset of ruleml_assert//1 will cause it to fail, meaning that
|
||||
* an empty <Assert></Assert> element is never emitted to the output
|
||||
* RuleML/xmL.
|
||||
*
|
||||
* The two cuts are green cuts, meaning they do not change the meaning
|
||||
* or output of the program, they simply prevent needless
|
||||
* backtracking.
|
||||
*/
|
||||
|
||||
ruleml_assert(Items) -->
|
||||
( { var(Items) } ->
|
||||
list_ws("<Assert mapClosure=\"universal\">"),
|
||||
ruleml_assert_items(Items),
|
||||
!,
|
||||
list_ws("</Assert>")
|
||||
; "<Assert mapClosure=\"universal\">",
|
||||
{ Items \== [] },
|
||||
ruleml_assert_items(Items),
|
||||
!,
|
||||
"</Assert>"
|
||||
).
|
||||
|
||||
@@ -206,7 +198,6 @@ ruleml_assert(Items) -->
|
||||
|
||||
ruleml_assert_items([Item | Items]) -->
|
||||
ruleml_assert_item(Item),
|
||||
!,
|
||||
ruleml_assert_items(Items).
|
||||
ruleml_assert_items([]) --> [].
|
||||
|
||||
@@ -214,7 +205,6 @@ ruleml_assert_items([]) --> [].
|
||||
ruleml_query_items(Items) -->
|
||||
( { var(Items) } ->
|
||||
ruleml_query_item(Item),
|
||||
!,
|
||||
( { var(Item) } ->
|
||||
ruleml_query_items(Items)
|
||||
; { Items = [Item | Items0] },
|
||||
@@ -222,7 +212,6 @@ ruleml_query_items(Items) -->
|
||||
)
|
||||
; { Items = [Item | Items0] },
|
||||
ruleml_query_item(Item),
|
||||
!,
|
||||
ruleml_query_items(Items0)
|
||||
).
|
||||
ruleml_query_items([]) --> [].
|
||||
@@ -279,7 +268,7 @@ space(' ') --> " ".
|
||||
|
||||
decimal_point('.') --> ".".
|
||||
|
||||
sign('-') --> "-", !.
|
||||
sign('-') --> "-".
|
||||
sign('+') --> "+".
|
||||
|
||||
double_quote('"') --> "\"".
|
||||
@@ -332,7 +321,6 @@ ruleml_condition(Item) -->
|
||||
|
||||
ruleml_item_conjunction([Item | Items]) -->
|
||||
ruleml_condition(Item),
|
||||
!,
|
||||
ruleml_item_conjunction(Items).
|
||||
ruleml_item_conjunction([]) --> [].
|
||||
|
||||
@@ -404,7 +392,6 @@ ruleml_conjunction_of_items(Items) -->
|
||||
|
||||
ruleml_item_disjunction([Item | Items]) -->
|
||||
ruleml_condition(Item),
|
||||
!,
|
||||
ruleml_item_disjunction(Items).
|
||||
ruleml_item_disjunction([]) --> [].
|
||||
|
||||
@@ -549,7 +536,6 @@ ruleml_naf(Item) -->
|
||||
|
||||
ruleml_atoms([Item|Items]) -->
|
||||
ruleml_atom(Item),
|
||||
!,
|
||||
ruleml_atoms(Items).
|
||||
ruleml_atoms([]) --> [].
|
||||
|
||||
@@ -652,7 +638,6 @@ ruleml_expr(Item) -->
|
||||
( list_ws("<repo>"),
|
||||
ruleml_item(RepoItem),
|
||||
list_ws("</repo>"),
|
||||
!,
|
||||
{ fold_commas(Args, ArgsCommas) },
|
||||
{ Item =.. [Name, (ArgsCommas | RepoItem)] }
|
||||
; { Item =.. [Name | Args] }
|
||||
@@ -823,15 +808,12 @@ ruleml_data(Name) -->
|
||||
* converting from lists of characters (here denoted as Cs) to the
|
||||
* named data type in ISO Prolog. The type information is given
|
||||
* in the first argument.
|
||||
*
|
||||
* Grammatically, ruleml_data_contents//3 is a disjoint union of its
|
||||
* subgrammars, justifying the cut at the end of the first two rules.
|
||||
*/
|
||||
|
||||
ruleml_data_contents(number, Cs) -->
|
||||
ruleml_number(Cs), !.
|
||||
ruleml_number(Cs).
|
||||
ruleml_data_contents(symbol, Cs) -->
|
||||
ruleml_symbol(Cs), !.
|
||||
ruleml_symbol(Cs).
|
||||
ruleml_data_contents(string, Cs) -->
|
||||
ruleml_string(Cs).
|
||||
|
||||
@@ -1195,8 +1177,7 @@ fold_semicolons(List, Output) :-
|
||||
* complicated by Scryer's current lack of multi-argument indexing.
|
||||
*/
|
||||
|
||||
fold_list([Item], _, Item) :-
|
||||
!.
|
||||
fold_list([Item], _, Item).
|
||||
fold_list([Item|Items], F, Form) :-
|
||||
Form =.. [F, Item, Fs],
|
||||
fold_list(Items, F, Fs).
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,11 +11,12 @@
|
||||
*/
|
||||
|
||||
:- module(least_time, [find_min_time/2,
|
||||
write_time_nl/1]).
|
||||
write_time_nl/1]).
|
||||
|
||||
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(format)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(reif)).
|
||||
|
||||
|
||||
@@ -32,10 +33,10 @@ valid_time([H1,H2,M1,M2], T) :-
|
||||
memberd_t(M2, [0,1,2,3,4,5,6,7,8,9], TM2),
|
||||
( maplist(=(true), [TH1, TH2, TM1, TM2]) ->
|
||||
( H1 =:= 2 ->
|
||||
( H2 =< 3 ->
|
||||
T = true
|
||||
; T = false
|
||||
)
|
||||
( H2 =< 3 ->
|
||||
T = true
|
||||
; T = false
|
||||
)
|
||||
; T = true
|
||||
)
|
||||
; T = false
|
||||
@@ -49,15 +50,7 @@ permuted_times(Time, PermutedTimes) :-
|
||||
|
||||
find_min_time(Time, Min) :-
|
||||
valid_time(Time, true),
|
||||
permuted_times(Time, PermutedTimes),
|
||||
find_min_time_(PermutedTimes, Time, Min).
|
||||
|
||||
find_min_time_([], Min, Min).
|
||||
find_min_time_([Time|Times], MinSoFar, Min) :-
|
||||
( Time @< MinSoFar ->
|
||||
find_min_time_(Times, Time, Min)
|
||||
; find_min_time_(Times, MinSoFar, Min)
|
||||
).
|
||||
permuted_times(Time, [Min|_]).
|
||||
|
||||
|
||||
write_time_nl(Time) :-
|
||||
31
src/examples/utf8.pl
Normal file
31
src/examples/utf8.pl
Normal file
@@ -0,0 +1,31 @@
|
||||
:- use_module(library(charsio)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
:- initialization(unit_test).
|
||||
|
||||
unit_test :-
|
||||
chars_utf8bytes("a£\x2124\", Bs),
|
||||
Bs = [97, 194, 163, 226, 132, 164],
|
||||
chars_utf8bytes(Cs, Bs),
|
||||
Cs = "a£\x2124\".
|
||||
|
||||
write_f :-
|
||||
open('x.txt', write, Stream, [type(binary)]),
|
||||
F = put_byte(Stream),
|
||||
chars_utf8bytes("£\x2124\\x2764\\x1F496\\n", Bs),
|
||||
maplist(F, Bs),
|
||||
close(Stream).
|
||||
|
||||
get_bytes(Stream, Res) :- get_bytes(Stream, [], Res).
|
||||
get_bytes(Stream, Acc, Res) :-
|
||||
get_byte(Stream, B),
|
||||
(B =:= -1 ->
|
||||
reverse(Acc, Res)
|
||||
; get_bytes(Stream, [B|Acc], Res)).
|
||||
|
||||
read_f :-
|
||||
open('x.txt', read, Stream, [type(binary)]),
|
||||
get_bytes(Stream, Bs),
|
||||
chars_utf8bytes(Cs, Bs),
|
||||
write(Cs),
|
||||
close(Stream).
|
||||
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::iterators::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::BTreeSet;
|
||||
@@ -1,14 +1,14 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::parser::OpDesc;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::parser::OpDesc;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::ordered_float::OrderedFloat;
|
||||
use crate::prolog::rug::{Integer, Rational};
|
||||
use crate::clause_types::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::rug::{Integer, Rational};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -505,11 +505,11 @@ pub fn fetch_atom_op_spec(
|
||||
spec: Option<SharedOpDesc>,
|
||||
op_dir: &OpDir,
|
||||
) -> Option<SharedOpDesc> {
|
||||
fetch_op_spec(name.clone(), 1, spec.clone(), op_dir)
|
||||
.or_else(|| fetch_op_spec(name, 2, spec, op_dir))
|
||||
fetch_op_spec_from_existing(name.clone(), 1, spec.clone(), op_dir)
|
||||
.or_else(|| fetch_op_spec_from_existing(name, 2, spec, op_dir))
|
||||
}
|
||||
|
||||
pub fn fetch_op_spec(
|
||||
pub fn fetch_op_spec_from_existing(
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
spec: Option<SharedOpDesc>,
|
||||
@@ -524,7 +524,15 @@ pub fn fetch_op_spec(
|
||||
}
|
||||
}
|
||||
|
||||
spec.or_else(|| match arity {
|
||||
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
||||
}
|
||||
|
||||
pub fn fetch_op_spec(
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
op_dir: &OpDir,
|
||||
) -> Option<SharedOpDesc> {
|
||||
match arity {
|
||||
2 => op_dir
|
||||
.get(&(name, Fixity::In))
|
||||
.and_then(|OpDirValue(spec, _)| {
|
||||
@@ -542,7 +550,7 @@ pub fn fetch_op_spec(
|
||||
}
|
||||
|
||||
op_dir
|
||||
.get(&(name.clone(), Fixity::Post))
|
||||
.get(&(name, Fixity::Post))
|
||||
.and_then(|OpDirValue(spec, _)| {
|
||||
if spec.prec() > 0 {
|
||||
Some(spec.clone())
|
||||
@@ -551,8 +559,10 @@ pub fn fetch_op_spec(
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type ModuleDir = IndexMap<ClauseName, Module>;
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use crate::indexmap::IndexSet;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::Deref;
|
||||
@@ -93,21 +93,19 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
}
|
||||
Addr::Con(h) => {
|
||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
||||
if !self.machine_st.flags.double_quotes.is_atom() {
|
||||
return if let Some(c) = pstr.range_from(0 ..).next() {
|
||||
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
|
||||
self.state_stack.push(Addr::Char(c));
|
||||
if let Some(c) = pstr.range_from(0 ..).next() {
|
||||
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
|
||||
self.state_stack.push(Addr::Char(c));
|
||||
|
||||
Addr::PStrLocation(h, 0)
|
||||
} else if has_tail {
|
||||
self.follow(Addr::HeapCell(h + 1))
|
||||
} else {
|
||||
Addr::EmptyList
|
||||
};
|
||||
Addr::PStrLocation(h, 0)
|
||||
} else if has_tail {
|
||||
self.follow(Addr::HeapCell(h + 1))
|
||||
} else {
|
||||
Addr::EmptyList
|
||||
}
|
||||
} else {
|
||||
Addr::Con(h)
|
||||
}
|
||||
|
||||
Addr::Con(h)
|
||||
}
|
||||
da => {
|
||||
da
|
||||
@@ -1,16 +1,16 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::heap_iter::*;
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::prolog::ordered_float::OrderedFloat;
|
||||
use crate::prolog::rug::{Integer, Rational};
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::rug::{Integer, Rational};
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryFrom;
|
||||
@@ -449,8 +449,6 @@ fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||
if let Some(c) = iter.next() {
|
||||
if small_letter_char!(c) {
|
||||
iter.all(|c| alpha_numeric_char!(c))
|
||||
} else if c == '.' {
|
||||
iter.next().is_some()
|
||||
} else if graphic_token_char!(c) {
|
||||
non_quoted_graphic_token(iter, c)
|
||||
} else if semicolon_char!(c) {
|
||||
@@ -1173,7 +1171,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let at_cdr = self.at_cdr(",");
|
||||
|
||||
if !at_cdr && Addr::EmptyList == end_addr {
|
||||
if self.machine_st.flags.double_quotes.is_chars() && !self.ignore_ops {
|
||||
if !self.ignore_ops {
|
||||
self.print_proper_string(buf, max_depth);
|
||||
return;
|
||||
}
|
||||
@@ -1190,18 +1188,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let mut byte_len = 0;
|
||||
|
||||
let char_printer = |printer: &mut Self, c| {
|
||||
if printer.machine_st.flags.double_quotes.is_codes() {
|
||||
let s = (c as u32).to_string();
|
||||
|
||||
push_space_if_amb!(printer, &s, {
|
||||
printer.append_str(&s);
|
||||
});
|
||||
} else {
|
||||
printer.print_char(printer.quoted, c);
|
||||
}
|
||||
};
|
||||
|
||||
if self.ignore_ops {
|
||||
let mut char_count = 0;
|
||||
|
||||
@@ -1209,7 +1195,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
self.append_str("'.'");
|
||||
self.push_char('(');
|
||||
|
||||
char_printer(self, c);
|
||||
self.print_char(self.quoted, c);
|
||||
self.push_char(',');
|
||||
|
||||
char_count += 1;
|
||||
@@ -1235,7 +1221,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
};
|
||||
|
||||
for c in buf_iter {
|
||||
char_printer(self, c);
|
||||
self.print_char(self.quoted, c);
|
||||
self.push_char(',');
|
||||
|
||||
byte_len += c.len_utf8();
|
||||
@@ -1312,6 +1298,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||
match heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||
_ => false
|
||||
@@ -1422,7 +1409,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
||||
let spec = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir);
|
||||
let spec = fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir);
|
||||
|
||||
if let Some(spec) = spec {
|
||||
self.handle_op_as_struct(
|
||||
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::rug::Integer;
|
||||
use crate::instructions::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
@@ -123,10 +123,6 @@ impl CodeOffsets {
|
||||
code.push(Self::add_index(code.is_empty(), index));
|
||||
}
|
||||
}
|
||||
&Constant::String(_) => {
|
||||
let is_initial_index = self.lists.is_empty();
|
||||
self.lists.push(Self::add_index(is_initial_index, index));
|
||||
}
|
||||
&Constant::Usize(n) => {
|
||||
let code = self.constants
|
||||
.entry(Constant::Integer(Rc::new(Integer::from(n))))
|
||||
@@ -158,7 +154,7 @@ impl CodeOffsets {
|
||||
let is_initial_index = code.is_empty();
|
||||
code.push(Self::add_index(is_initial_index, index));
|
||||
}
|
||||
&Term::Cons(..) => {
|
||||
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
||||
let is_initial_index = self.lists.is_empty();
|
||||
self.lists.push(Self::add_index(is_initial_index, index));
|
||||
}
|
||||
@@ -172,7 +168,8 @@ impl CodeOffsets {
|
||||
let is_initial_index = code.is_empty();
|
||||
code.push(Self::add_index(is_initial_index, index));
|
||||
}
|
||||
_ => {}
|
||||
_ => {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_errors::MachineStub;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::rug::Integer;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_errors::MachineStub;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
@@ -1,8 +1,8 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -24,6 +24,8 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
|
||||
:- op(400, yfx, [div, //, rdiv, <<, >>, mod, rem]).
|
||||
:- op(200, fy, [+, -, \]).
|
||||
|
||||
:- op(1200, xfx, -->).
|
||||
|
||||
% arithmetic comparison operators.
|
||||
:- op(700, xfx, [>, <, =\=, =:=, >=, =<]).
|
||||
|
||||
@@ -52,7 +54,7 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
|
||||
findall/3, findall/4, flush_output/0,
|
||||
flush_output/1, get_byte/1, get_byte/2,
|
||||
get_char/1, get_char/2, get_code/1, get_code/2,
|
||||
halt/0, max_arity/1, number_chars/2,
|
||||
halt/0, halt/1, max_arity/1, number_chars/2,
|
||||
number_codes/2, once/1, op/3, open/3, open/4,
|
||||
peek_byte/1, peek_byte/2, peek_char/1,
|
||||
peek_char/2, peek_code/1, peek_code/2,
|
||||
@@ -912,7 +914,14 @@ op(Priority, OpSpec, Op) :-
|
||||
; throw(error(type_error(list, Op), op/3)) % 8.14.3.3 f)
|
||||
).
|
||||
|
||||
halt :- '$halt'.
|
||||
|
||||
halt :- halt(0).
|
||||
|
||||
halt(N) :-
|
||||
( -2^31 =< N, N =< 2^31 - 1 ->
|
||||
'$halt'(N)
|
||||
; throw(error(domain_error(exit_code, N), halt/1))
|
||||
).
|
||||
|
||||
atom_length(Atom, Length) :-
|
||||
( var(Atom) -> throw(error(instantiation_error, atom_length/2)) % 8.16.1.3 a)
|
||||
@@ -1,8 +1,10 @@
|
||||
:- module(charsio, [char_type/2,
|
||||
chars_utf8bytes/2,
|
||||
get_single_char/1,
|
||||
read_line_to_chars/3,
|
||||
read_term_from_chars/2,
|
||||
write_term_to_chars/3]).
|
||||
write_term_to_chars/3,
|
||||
chars_base64/3]).
|
||||
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(iso_ext)).
|
||||
@@ -140,7 +142,6 @@ write_term_to_chars(Term, Options, Chars) :-
|
||||
'$write_term_to_chars'(Chars, Term, IgnoreOps, NumberVars, Quoted, NewVarNames, MaxDepth).
|
||||
|
||||
% Encodes Ch character to list of Bytes.
|
||||
% TODO: if Ch is variable, decode Bytes to Char.
|
||||
char_utf8bytes(Ch, Bytes) :-
|
||||
char_code(Ch, Code),
|
||||
phrase(code_to_utf8(Code), Bytes).
|
||||
@@ -155,10 +156,87 @@ encode(Code, Prefix, Nb) -->
|
||||
{ Nb1 is Nb - 1, Byte is Prefix \/ ((Code >> (6 * Nb1)) /\ 0x3F) },
|
||||
[Byte], encode(Code, 0x80, Nb1).
|
||||
|
||||
% Encodes a list of characters Cs to a list of UTF-8 bytes Bs.
|
||||
% TODO: if Cs is variable, decode bytes to chars instead.
|
||||
% Maps characters and UTF-8 bytes.
|
||||
% If Cs is a variable, parses Bs as a list of UTF-8 bytes.
|
||||
% Otherwise, transform the list of characters Cs to UTF-8 bytes.
|
||||
chars_utf8bytes(Cs, Bs) :-
|
||||
must_be(list, Cs),
|
||||
maplist(must_be(atom), Cs),
|
||||
maplist(char_utf8bytes, Cs, Bss),
|
||||
append(Bss, Bs).
|
||||
var(Cs), must_be(list, Bs) ->
|
||||
once(phrase(decode_utf8(Cs), Bs))
|
||||
; (must_be(list, Cs),
|
||||
maplist(must_be(atom), Cs),
|
||||
maplist(char_utf8bytes, Cs, Bss),
|
||||
append(Bss, Bs)).
|
||||
|
||||
decode_utf8([]) --> [].
|
||||
decode_utf8(Chars) --> leading(Nb, Code), continuation(Code, Chars, Nb).
|
||||
|
||||
leading(1, Byte) --> [Byte], {Byte /\ 0x80 =:= 0}.
|
||||
leading(2, Code) --> [Byte], {Byte /\ 0xE0 =:= 0xC0, Code is Byte - 0xC0}.
|
||||
leading(3, Code) --> [Byte], {Byte /\ 0xF0 =:= 0xE0, Code is Byte - 0xE0}.
|
||||
leading(4, Code) --> [Byte], {Byte /\ 0xF8 =:= 0xF0, Code is Byte - 0xF0}.
|
||||
leading(1, 0xFFFD) --> [_]. % invalid first byte
|
||||
|
||||
continuation(Code, [H|T], 1) --> {char_code(H, Code)}, decode_utf8(T).
|
||||
continuation(Code, Chars, Nb) --> [Byte],
|
||||
{Nb1 is Nb - 1, Byte /\ 0xC0 =:= 0x80, NextCode is (Code << 6) \/ (Byte - 0x80)},
|
||||
continuation(NextCode, Chars, Nb1).
|
||||
|
||||
% invalid continuation byte
|
||||
% each remaining continuation byte (if any) will raise 0xFFFD too
|
||||
continuation(_, ['\xFFFD\'|T], _) --> [_], decode_utf8(T).
|
||||
|
||||
|
||||
read_line_to_chars(Stream, Cs0, Cs) :-
|
||||
'$get_n_chars'(Stream, 1, Char), % this also works for binary streams
|
||||
( Char == [] -> Cs0 = Cs
|
||||
; Char = [C],
|
||||
Cs0 = [C|Rest],
|
||||
( C == '\n' -> Rest = Cs
|
||||
; read_line_to_chars(Stream, Rest, Cs)
|
||||
)
|
||||
).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Relation between a list of characters Cs and its Base64 encoding Bs,
|
||||
also a list of characters.
|
||||
|
||||
At least one of the arguments must be instantiated.
|
||||
|
||||
Options are:
|
||||
|
||||
- padding(Boolean)
|
||||
Whether to use padding: true (the default) or false.
|
||||
- charset(C)
|
||||
Either 'standard' (RFC 4648 §4, the default) or 'url' (RFC 4648 §5).
|
||||
|
||||
Example:
|
||||
|
||||
?- chars_base64("hello", Bs, []).
|
||||
Bs = "aGVsbG8="
|
||||
; false.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
chars_base64(Cs, Bs, Options) :-
|
||||
must_be(list, Options),
|
||||
( member(O, Options), var(O) ->
|
||||
instantiation_error(chars_base64/3)
|
||||
; ( member(padding(Padding), Options) -> true
|
||||
; Padding = true
|
||||
),
|
||||
( member(charset(Charset), Options) -> true
|
||||
; Charset = standard
|
||||
)
|
||||
),
|
||||
must_be(boolean, Padding),
|
||||
must_be(atom, Charset),
|
||||
( member(Charset, [standard,url]) -> true
|
||||
; domain_error(charset, Charset, chars_base64/3)
|
||||
),
|
||||
( var(Cs) ->
|
||||
must_be(list, Bs),
|
||||
maplist(must_be(character), Bs),
|
||||
'$chars_base64'(Cs, Bs, Padding, Charset)
|
||||
; must_be(list, Cs),
|
||||
maplist(must_be(character), Cs),
|
||||
'$chars_base64'(Cs, Bs, Padding, Charset)
|
||||
).
|
||||
@@ -29,6 +29,8 @@
|
||||
ed25519_keypair_public_key/2, % +KeyPair, +PublicKey
|
||||
ed25519_sign/4, % +KeyPair, +Data, -Signature, +Options
|
||||
ed25519_verify/4, % +PublicKey, +Data, +Signature, +Options
|
||||
curve25519_generator/1, % -Generator
|
||||
curve25519_scalar_mult/3, % +Scalar, +Point, -Result
|
||||
crypto_name_curve/2, % +Name, -Curve
|
||||
crypto_curve_order/2, % +Curve, -Order
|
||||
crypto_curve_generator/2, % +Curve, -Generator
|
||||
@@ -43,6 +45,7 @@
|
||||
:- use_module(library(arithmetic)).
|
||||
:- use_module(library(format)).
|
||||
:- use_module(library(charsio)).
|
||||
:- use_module(library(si)).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
hex_bytes(?Hex, ?Bytes) is det.
|
||||
@@ -76,13 +79,13 @@ hex_bytes([]) --> [].
|
||||
hex_bytes([H1,H2|Hs]) --> [Byte],
|
||||
{ char_hexval(H1, High),
|
||||
char_hexval(H2, Low),
|
||||
Byte is High*16 + Low },
|
||||
Byte #= High*16 + Low },
|
||||
hex_bytes(Hs).
|
||||
|
||||
bytes_hex([]) --> [].
|
||||
bytes_hex([B|Bs]) --> [C0,C1],
|
||||
{ High is B>>4,
|
||||
Low is B /\ 0xf,
|
||||
{ High #= B>>4,
|
||||
Low #= B /\ 0xf,
|
||||
char_hexval(C0, High),
|
||||
char_hexval(C1, Low)
|
||||
},
|
||||
@@ -101,6 +104,16 @@ must_be_bytes(Bytes, Context) :-
|
||||
).
|
||||
|
||||
|
||||
must_be_byte_chars(Chars, Context) :-
|
||||
must_be(list, Chars),
|
||||
( member(Char, Chars),
|
||||
char_code(Char, Code),
|
||||
\+ between(0, 255, Code) ->
|
||||
domain_error(byte_char, Char, Context)
|
||||
; true
|
||||
).
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cryptographically secure random numbers
|
||||
=======================================
|
||||
@@ -191,18 +204,18 @@ crypto_random_byte(B) :- '$crypto_random_byte'(B).
|
||||
|
||||
crypto_data_hash(Data0, Hash, Options0) :-
|
||||
must_be(list, Options0),
|
||||
options_data_bytes(Options0, Data0, Data),
|
||||
options_data_chars(Options0, Data0, Data, Encoding),
|
||||
functor_hash_options(algorithm, A, Options0, _),
|
||||
( hash_algorithm(A) -> true
|
||||
; domain_error(hash_algorithm, A, crypto_data_hash/3)
|
||||
),
|
||||
'$crypto_data_hash'(Data, HashBytes, A),
|
||||
'$crypto_data_hash'(Data, Encoding, HashBytes, A),
|
||||
hex_bytes(Hash, HashBytes).
|
||||
|
||||
options_data_bytes(Options, Data, Bytes) :-
|
||||
options_data_chars(Options, Data, Chars, Encoding) :-
|
||||
option(encoding(Encoding), Options, utf8),
|
||||
must_be(atom, Encoding),
|
||||
encoding_bytes(Encoding, Data, Bytes).
|
||||
encoding_chars(Encoding, Data, Chars).
|
||||
|
||||
default_hash(sha256).
|
||||
|
||||
@@ -270,12 +283,12 @@ crypto_data_hkdf(Data0, L, Bytes, Options0) :-
|
||||
),
|
||||
must_be(integer, L),
|
||||
L >= 0,
|
||||
options_data_bytes(Options, Data0, Data),
|
||||
options_data_chars(Options, Data0, Data, Encoding),
|
||||
option(salt(SaltBytes), Options, []),
|
||||
must_be_bytes(SaltBytes, crypto_data_hkdf/4),
|
||||
option(info(Info0), Options, []),
|
||||
chars_bytes_(Info0, Info, crypto_data_hkdf/4),
|
||||
'$crypto_data_hkdf'(Data, SaltBytes, Info, Algorithm, L, Bytes).
|
||||
'$crypto_data_hkdf'(Data, Encoding, SaltBytes, Info, Algorithm, L, Bytes).
|
||||
|
||||
hkdf_algorithm(sha256).
|
||||
hkdf_algorithm(sha384).
|
||||
@@ -416,61 +429,17 @@ crypto_password_hash(Password0, Hash, Options) :-
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Bidirectional Bytes <-> Base64 conversion
|
||||
=========================================
|
||||
|
||||
This implements Base64 conversion *without padding*.
|
||||
Bidirectional Bytes <-> Base64 conversion *without padding*.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
n_base64(0 , 'A'). n_base64(1 , 'B'). n_base64(2 , 'C'). n_base64(3 , 'D').
|
||||
n_base64(4 , 'E'). n_base64(5 , 'F'). n_base64(6 , 'G'). n_base64(7 , 'H').
|
||||
n_base64(8 , 'I'). n_base64(9 , 'J'). n_base64(10, 'K'). n_base64(11, 'L').
|
||||
n_base64(12, 'M'). n_base64(13, 'N'). n_base64(14, 'O'). n_base64(15, 'P').
|
||||
n_base64(16, 'Q'). n_base64(17, 'R'). n_base64(18, 'S'). n_base64(19, 'T').
|
||||
n_base64(20, 'U'). n_base64(21, 'V'). n_base64(22, 'W'). n_base64(23, 'X').
|
||||
n_base64(24, 'Y'). n_base64(25, 'Z'). n_base64(26, 'a'). n_base64(27, 'b').
|
||||
n_base64(28, 'c'). n_base64(29, 'd'). n_base64(30, 'e'). n_base64(31, 'f').
|
||||
n_base64(32, 'g'). n_base64(33, 'h'). n_base64(34, 'i'). n_base64(35, 'j').
|
||||
n_base64(36, 'k'). n_base64(37, 'l'). n_base64(38, 'm'). n_base64(39, 'n').
|
||||
n_base64(40, 'o'). n_base64(41, 'p'). n_base64(42, 'q'). n_base64(43, 'r').
|
||||
n_base64(44, 's'). n_base64(45, 't'). n_base64(46, 'u'). n_base64(47, 'v').
|
||||
n_base64(48, 'w'). n_base64(49, 'x'). n_base64(50, 'y'). n_base64(51, 'z').
|
||||
n_base64(52, '0'). n_base64(53, '1'). n_base64(54, '2'). n_base64(55, '3').
|
||||
n_base64(56, '4'). n_base64(57, '5'). n_base64(58, '6'). n_base64(59, '7').
|
||||
n_base64(60, '8'). n_base64(61, '9'). n_base64(62, '+'). n_base64(63, '/').
|
||||
|
||||
bytes_base64(Ls, Bs) :-
|
||||
( list(Bs), maplist(atom, Bs) ->
|
||||
maplist(n_base64, Is, Bs),
|
||||
phrase(bytes_base64_(Ls), Is),
|
||||
Ls ins 0..255
|
||||
; phrase(bytes_base64_(Ls), Is),
|
||||
Is ins 0..63,
|
||||
maplist(n_base64, Is, Bs)
|
||||
bytes_base64(Bytes, Base64) :-
|
||||
( var(Bytes) ->
|
||||
chars_base64(Chars, Base64, [padding(false)]),
|
||||
maplist(char_code, Chars, Bytes)
|
||||
; maplist(char_code, Chars, Bytes),
|
||||
chars_base64(Chars, Base64, [padding(false)])
|
||||
).
|
||||
|
||||
list(Ls) :-
|
||||
nonvar(Ls),
|
||||
( Ls = [] -> true
|
||||
; Ls = [_|Rest],
|
||||
list(Rest)
|
||||
).
|
||||
|
||||
bytes_base64_([]) --> [].
|
||||
bytes_base64_([A]) --> [W,X],
|
||||
{ A #= W*4 + X//16,
|
||||
X #= 16*_ }.
|
||||
bytes_base64_([A,B]) --> [W,X,Y],
|
||||
{ A #= W*4 + X//16,
|
||||
B #= (X mod 16)*16 + Y//4,
|
||||
Y #= 4*_ }.
|
||||
bytes_base64_([A,B,C|Ls]) --> [W,X,Y,Z],
|
||||
{ A #= W*4 + X//16,
|
||||
B #= (X mod 16)*16 + Y//4,
|
||||
C #= (Y mod 4)*64 + Z },
|
||||
bytes_base64_(Ls).
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
crypto_data_encrypt(+PlainText,
|
||||
+Algorithm,
|
||||
@@ -558,7 +527,7 @@ bytes_base64_([A,B,C|Ls]) --> [W,X,Y,Z],
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
|
||||
options_data_bytes(Options, PlainText0, PlainText),
|
||||
options_data_chars(Options, PlainText0, PlainText, Encoding),
|
||||
option(tag(Tag), Options, _),
|
||||
( nonvar(Tag) ->
|
||||
must_be_bytes(Tag, crypto_data_encrypt/6)
|
||||
@@ -570,7 +539,7 @@ crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
|
||||
( Algorithm = 'chacha20-poly1305' -> true
|
||||
; domain_error('chacha20-poly1305', Algorithm, crypto_data_encrypt/6)
|
||||
),
|
||||
'$crypto_data_encrypt'(PlainText, Key, IV, Tag, CipherText).
|
||||
'$crypto_data_encrypt'(PlainText, Encoding, Key, IV, Tag, CipherText).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
crypto_data_decrypt(+CipherText,
|
||||
@@ -610,26 +579,25 @@ crypto_data_decrypt(CipherText0, Algorithm, Key, IV, PlainText, Options) :-
|
||||
must_be(atom, Encoding),
|
||||
member(Encoding, [utf8,octet]),
|
||||
must_be(list, CipherText0),
|
||||
encoding_bytes(octet, CipherText0, CipherText1),
|
||||
append(CipherText1, Tag, CipherText),
|
||||
encoding_chars(octet, CipherText0, CipherText1),
|
||||
maplist(char_code, TagChars, Tag),
|
||||
append(CipherText1, TagChars, CipherText),
|
||||
( Algorithm = 'chacha20-poly1305' -> true
|
||||
; domain_error('chacha20-poly1305', Algorithm, crypto_data_decrypt/6)
|
||||
),
|
||||
'$crypto_data_decrypt'(CipherText, Key, IV, Encoding, PlainText).
|
||||
'$crypto_data_decrypt'(CipherText, octet, Key, IV, Encoding, PlainText).
|
||||
|
||||
encoding_bytes(octet, Bs0, Bs) :-
|
||||
must_be(list, Bs0),
|
||||
( maplist(integer, Bs0) ->
|
||||
Bs0 = Bs
|
||||
; maplist(char_code, Bs0, Bs)
|
||||
|
||||
encoding_chars(octet, Bs, Cs) :-
|
||||
must_be(list, Bs),
|
||||
( maplist(integer, Bs) ->
|
||||
maplist(char_code, Cs, Bs)
|
||||
; Bs = Cs
|
||||
),
|
||||
must_be_bytes(Bs, crypto_encoding).
|
||||
encoding_bytes(utf8, Cs, Bs) :-
|
||||
must_be_byte_chars(Cs, crypto_encoding).
|
||||
encoding_chars(utf8, Cs, Cs) :-
|
||||
must_be(list, Cs),
|
||||
( maplist(atom, Cs) ->
|
||||
chars_bytes_(Cs, Bs, crypto_encoding)
|
||||
; domain_error(encryption_encoding, Cs, crypto)
|
||||
).
|
||||
maplist(must_be(character), Cs).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Digital signatures with Ed25519
|
||||
@@ -667,60 +635,77 @@ encoding_bytes(utf8, Cs, Bs) :-
|
||||
ed25519_new_keypair(Pair) :-
|
||||
'$ed25519_new_keypair'(Pair).
|
||||
|
||||
ed25519_keypair_public_key(Pair0, PublicKey) :-
|
||||
encoding_bytes(octet, Pair0, Pair),
|
||||
'$ed25519_keypair_public_key'(Pair, PublicKey).
|
||||
ed25519_keypair_public_key(Pair, PublicKey) :-
|
||||
must_be_byte_chars(Pair, ed25519_keypair_public_key),
|
||||
'$ed25519_keypair_public_key'(Pair, octet, PublicKey).
|
||||
|
||||
ed25519_sign(Key0, Data0, Signature, Options) :-
|
||||
options_data_bytes(Options, Data0, Data),
|
||||
encoding_bytes(octet, Key0, Key),
|
||||
'$ed25519_sign'(Key, Data, Signature0),
|
||||
ed25519_sign(Key, Data0, Signature, Options) :-
|
||||
must_be_byte_chars(Key, ed25519_sign),
|
||||
options_data_chars(Options, Data0, Data, Encoding),
|
||||
'$ed25519_sign'(Key, octet, Data, Encoding, Signature0),
|
||||
hex_bytes(Signature, Signature0).
|
||||
|
||||
ed25519_verify(Key0, Data0, Signature0, Options) :-
|
||||
options_data_bytes(Options, Data0, Data),
|
||||
encoding_bytes(octet, Key0, Key),
|
||||
ed25519_verify(Key, Data0, Signature0, Options) :-
|
||||
must_be_byte_chars(Key, ed25519_verify),
|
||||
options_data_chars(Options, Data0, Data, Encoding),
|
||||
hex_bytes(Signature0, Signature),
|
||||
'$ed25519_verify'(Key, Data, Signature).
|
||||
'$ed25519_verify'(Key, octet, Data, Encoding, Signature).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Modular multiplicative inverse.
|
||||
X25519: ECDH key exchange over Curve25519
|
||||
=========================================
|
||||
|
||||
Compute Y = X^(-1) mod p, using the extended Euclidean algorithm.
|
||||
Points on Curve25519 are represented as lists of characters that denote
|
||||
the u-coordinate of the Montgomery curve.
|
||||
|
||||
- curve25519_generator(-Gs)
|
||||
Gs is the generator point of Curve25519.
|
||||
|
||||
- curve25519_scalar_mult(+Scalar, +Ps, -Rs)
|
||||
Scalar must be an integer between 0 and 2^256-1,
|
||||
or a list of 32 bytes, and Ps must be a point on the curve.
|
||||
Computes the point Rs = Scalar*Ps as mandated by X25519.
|
||||
|
||||
Alice and Bob can use this to establish a shared secret as follows,
|
||||
where Gs is the generator point of Curve25519:
|
||||
|
||||
1. Alice creates a random integer a and sends As = a*Gs to Bob.
|
||||
2. Bob creates a random integer b and sends Bs = b*Gs to Alice.
|
||||
3. Alice computes Rs = a*Bs.
|
||||
4. Bob computes Rs = b*As.
|
||||
5. Alice and Bob use crypto_data_hkdf/4 on Rs with suitable
|
||||
(same) parameters to obtain lists of bytes that can be used as
|
||||
keys and initialization vectors for symmetric encryption.
|
||||
|
||||
If a and b are kept secret, this method is considered very secure.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
multiplicative_inverse_modulo_p(X, P, Y) :-
|
||||
eea(X, P, _, _, Y),
|
||||
R #= X*Y mod P,
|
||||
zcompare(C, 1, R),
|
||||
must_be_one(C, X, P, Y).
|
||||
curve25519_generator(Gs) :-
|
||||
length(Gs0, 32),
|
||||
Gs0 = [9|Zs],
|
||||
maplist(=(0), Zs),
|
||||
maplist(char_code, Gs, Gs0).
|
||||
|
||||
must_be_one(=, _, _, _).
|
||||
must_be_one(>, X, P, Y) :- throw(multiplicative_inverse_modulo_p(X,P,Y)).
|
||||
must_be_one(<, X, P, Y) :- throw(multiplicative_inverse_modulo_p(X,P,Y)).
|
||||
curve25519_scalar_mult(Scalar, Point, Result) :-
|
||||
( integer_si(Scalar) ->
|
||||
Scalar #>= 0,
|
||||
Scalar #< 2^256,
|
||||
length(ScalarBytes, 32),
|
||||
bytes_integer(ScalarBytes, Scalar)
|
||||
; ScalarBytes = Scalar,
|
||||
must_be_bytes(ScalarBytes, curve25519_scalar_mult/3),
|
||||
length(ScalarBytes, 32)
|
||||
),
|
||||
maplist(char_code, Point, PointBytes),
|
||||
'$curve25519_scalar_mult'(ScalarBytes, PointBytes, Result).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Extended Euclidean algorithm.
|
||||
|
||||
Computes the GCD and the Bézout coefficients S and T.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
eea(I, J, G, S, T) :-
|
||||
State0 = state(1,0,0,1),
|
||||
eea_loop(I, J, State0, G, S, T).
|
||||
|
||||
eea_loop(I, J, State0, G, S, T) :-
|
||||
zcompare(C, 0, J),
|
||||
eea_(C, I, J, State0, G, S, T).
|
||||
|
||||
eea_(=, I, _, state(_,_,U,V), I, U, V).
|
||||
eea_(<, I0, J0, state(S0,T0,U0,V0), I, U, V) :-
|
||||
Q #= I0 // J0,
|
||||
R #= I0 mod J0,
|
||||
S1 #= U0 - (Q*S0),
|
||||
T1 #= V0 - (Q*T0),
|
||||
eea_loop(J0, R, state(S1,T1,S0,T0), I, U, V).
|
||||
bytes_integer(Bs, N) :-
|
||||
foldl(pow, Bs, 0-0, N-_).
|
||||
|
||||
pow(B, N0-I0, N-I) :-
|
||||
B in 0..255,
|
||||
N #= N0 + B*256^I0,
|
||||
I #= I0 + 1.
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Operations on Elliptic Curves
|
||||
@@ -728,7 +713,7 @@ eea_(<, I0, J0, state(S0,T0,U0,V0), I, U, V) :-
|
||||
|
||||
Sample use: Establishing a shared secret S, using ECDH key exchange.
|
||||
|
||||
?- crypto_name_curve(Name, C),
|
||||
?- crypto_name_curve(secp256k1, C),
|
||||
crypto_curve_generator(C, Generator),
|
||||
PrivateKey = 10,
|
||||
crypto_curve_scalar_mult(C, PrivateKey, Generator, PublicKey),
|
||||
@@ -737,95 +722,44 @@ eea_(<, I0, J0, state(S0,T0,U0,V0), I, U, V) :-
|
||||
crypto_curve_scalar_mult(C, Random, PublicKey, S),
|
||||
crypto_curve_scalar_mult(C, PrivateKey, R, S).
|
||||
|
||||
For better security, new code should use Curve25519 instead.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
An elliptic curve over a prime field F_p is represented as:
|
||||
|
||||
curve(P,A,B,point(X,Y),Order,Cofactor).
|
||||
curve(Name,P,A,B,point(X,Y),Order,FieldLength,Cofactor).
|
||||
|
||||
First, we define suitable accessors.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
curve_p(curve(P,_,_,_,_,_), P).
|
||||
curve_a(curve(_,A,_,_,_,_), A).
|
||||
curve_b(curve(_,_,B,_,_,_), B).
|
||||
curve_name(curve(Name,_,_,_,_,_,_,_), Name).
|
||||
curve_p(curve(_,P,_,_,_,_,_,_), P).
|
||||
curve_a(curve(_,_,A,_,_,_,_,_), A).
|
||||
curve_b(curve(_,_,_,B,_,_,_,_), B).
|
||||
curve_field_length(curve(_,_,_,_,_,_,FieldLength,_), FieldLength).
|
||||
|
||||
crypto_curve_order(curve(_,_,_,_,Order,_), Order).
|
||||
crypto_curve_generator(curve(_,_,_,G,_,_), G).
|
||||
crypto_curve_generator(curve(_,_,_,_,G,_,_,_), G).
|
||||
crypto_curve_order(curve(_,_,_,_,_,Order,_,_), Order).
|
||||
|
||||
crypto_curve_scalar_mult(Curve, Scalar, point(X,Y), point(RX, RY)) :-
|
||||
must_be(integer, Scalar),
|
||||
must_be_on_curve(Curve, point(X,Y)),
|
||||
curve_name(Curve, Name),
|
||||
curve_field_length(Curve, L0),
|
||||
L #= 2*L0, % for hex encoding
|
||||
phrase(format_("04~|~`0t~16r~*+~`0t~16r~*+", [X,L,Y,L]), Hex),
|
||||
hex_bytes(Hex, Bytes),
|
||||
'$crypto_curve_scalar_mult'(Name, Scalar, Bytes, SX, SY),
|
||||
number_chars(RX, SX),
|
||||
number_chars(RY, SY).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Scalar point multiplication.
|
||||
|
||||
R = k*Q.
|
||||
|
||||
The Montgomery ladder method is used to mitigate side-channel
|
||||
attacks such as timing attacks, since the number of multiplications
|
||||
and additions is independent of the private key K. This method does
|
||||
not even reveal the key's Hamming weight (number of 1s).
|
||||
?- crypto_name_curve(secp256k1, Curve),
|
||||
crypto_curve_generator(Curve, G),
|
||||
crypto_curve_scalar_mult(Curve, 2, G, R).
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
crypto_curve_scalar_mult(Curve, K, Q, R) :-
|
||||
msb(K, Upper),
|
||||
scalar_multiplication(Curve, K, Upper, ml(null,Q)-R),
|
||||
must_be_on_curve(Curve, R).
|
||||
|
||||
scalar_multiplication(Curve, K, I, R0-R) :-
|
||||
zcompare(C, -1, I),
|
||||
scalar_mult_(C, Curve, K, I, R0-R).
|
||||
|
||||
scalar_mult_(=, _, _, _, ml(R,_)-R).
|
||||
scalar_mult_(<, Curve, K, I0, ML0-R) :-
|
||||
BitSet #= K /\ (1 << I0),
|
||||
zcompare(C, 0, BitSet),
|
||||
montgomery_step(C, Curve, ML0, ML1),
|
||||
I1 #= I0 - 1,
|
||||
scalar_multiplication(Curve, K, I1, ML1-R).
|
||||
|
||||
montgomery_step(=, Curve, ml(R0,S0), ml(R,S)) :-
|
||||
curve_points_addition(Curve, R0, S0, S),
|
||||
curve_point_double(Curve, R0, R).
|
||||
montgomery_step(<, Curve, ml(R0,S0), ml(R,S)) :-
|
||||
curve_points_addition(Curve, R0, S0, R),
|
||||
curve_point_double(Curve, S0, S).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Doubling a point: R = A + A.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
curve_point_double(_, null, null).
|
||||
curve_point_double(Curve, point(AX,AY), R) :-
|
||||
curve_p(Curve, P),
|
||||
curve_a(Curve, A),
|
||||
Numerator #= (3*AX^2 + A) mod P,
|
||||
Denom0 #= 2*AY mod P,
|
||||
multiplicative_inverse_modulo_p(Denom0, P, Denom),
|
||||
S #= (Numerator*Denom) mod P,
|
||||
R = point(RX,RY),
|
||||
RX #= (S^2 - 2*AX) mod P,
|
||||
RY #= (S*(AX - RX) - AY) mod P,
|
||||
must_be_on_curve(Curve, R).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Adding two points.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
curve_points_addition(Curve, P, Q, R) :-
|
||||
curve_points_addition_(P, Curve, Q, R).
|
||||
|
||||
curve_points_addition_(null, _, P, P).
|
||||
curve_points_addition_(P, _, null, P).
|
||||
curve_points_addition_(point(AX,AY), Curve, point(BX,BY), R) :-
|
||||
curve_p(Curve, P),
|
||||
Numerator #= (AY - BY) mod P,
|
||||
Denom0 #= (AX - BX) mod P,
|
||||
multiplicative_inverse_modulo_p(Denom0, P, Denom),
|
||||
S #= (Numerator * Denom) mod P,
|
||||
R = point(RX,RY),
|
||||
RX #= (S^2 - AX - BX) mod P,
|
||||
RY #= (S*(AX - RX) - AY) mod P,
|
||||
must_be_on_curve(Curve, R).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Validation.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
@@ -838,7 +772,7 @@ curve_contains_point(Curve, point(QX,QY)) :-
|
||||
|
||||
must_be_on_curve(Curve, P) :-
|
||||
\+ curve_contains_point(Curve, P),
|
||||
throw(not_on_curve(P)).
|
||||
domain_error(point_on_curve, P, crypto_elliptic_curves).
|
||||
must_be_on_curve(Curve, P) :- curve_contains_point(Curve, P).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@@ -855,21 +789,38 @@ must_be_on_curve(Curve, P) :- curve_contains_point(Curve, P).
|
||||
-text -no_seed -name secp256k1
|
||||
|
||||
You must remove the leading "04:" from the generator.
|
||||
|
||||
The field length depends on the order of the curve and can be computed
|
||||
with order_field_length/2.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
order_field_length(Order, L) :-
|
||||
fitting_exponent(Order, 0, E),
|
||||
L #= (E + 7) // 8.
|
||||
|
||||
fitting_exponent(N, E0, E) :-
|
||||
( 2^E0 #>= N -> E #= E0
|
||||
; E1 #= E0 + 1,
|
||||
fitting_exponent(N, E1, E)
|
||||
).
|
||||
|
||||
crypto_name_curve(secp112r1,
|
||||
curve(0x00db7c2abf62e35e668076bead208b,
|
||||
curve(secp112r1,
|
||||
0x00db7c2abf62e35e668076bead208b,
|
||||
0x00db7c2abf62e35e668076bead2088,
|
||||
0x659ef8ba043916eede8911702b22,
|
||||
point(0x09487239995a5ee76b55f9c2f098,
|
||||
0xa89ce5af8724c0a23e0e0ff77500),
|
||||
0x00db7c2abf62e35e7628dfac6561c5,
|
||||
14,
|
||||
1)).
|
||||
crypto_name_curve(secp256k1,
|
||||
curve(0x00fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
|
||||
curve(secp256k1,
|
||||
0x00fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
|
||||
0x0,
|
||||
0x7,
|
||||
point(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
|
||||
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
|
||||
0x00fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
|
||||
32,
|
||||
1)).
|
||||
238
src/lib/csv.pl
Normal file
238
src/lib/csv.pl
Normal file
@@ -0,0 +1,238 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Predicates for parsing CSV data
|
||||
|
||||
|
||||
Read csv files
|
||||
|
||||
Only two options with default values :
|
||||
- token_separator(',')
|
||||
- with_header(true)
|
||||
|
||||
Examples
|
||||
|
||||
* parsing a csv string:
|
||||
|
||||
?- use_module(library(csv)).
|
||||
?- use_module(library(dcgs)).
|
||||
?- phrase(parse_csv(Data), "col1,col2,col3,col4\none,2,,three").
|
||||
Data = frame(["col1","col2","col3","col4"],[["one",2,[],"three"]]).
|
||||
|
||||
* with some options:
|
||||
|
||||
?- phrase(parse_csv(Data, [with_header(false), token_separator(';')]), "one;2;;three").
|
||||
Data = frame([],[["one",2,[],"three"]]).
|
||||
|
||||
* parsing a csv file:
|
||||
|
||||
?- use_module(library(csv)).
|
||||
?- use_module(library(pio)).
|
||||
?- phrase_from_file(parse_csv(frame(Header, Rows)), './test.csv').
|
||||
|
||||
|
||||
Write csv files
|
||||
|
||||
Four options with default values :
|
||||
- line_separator('\n')
|
||||
- token_separator(',')
|
||||
- with_header(true)
|
||||
- null_value(empty)
|
||||
|
||||
Examples
|
||||
|
||||
* writing a csv file:
|
||||
|
||||
?- use_module(library(csv)).
|
||||
?- write_csv('./test.csv', frame(["col1","col2","col3","col4"], [["one",2,[],"three"]])).
|
||||
|
||||
* with some options
|
||||
|
||||
?- use_module(library(csv)).
|
||||
?- write_csv('./test.csv', frame(["col1","col2","col3","col4"], [["one",2,[],"three"]]), [with_header(false), line_separator('\r\n'), token_separator(';'), null_value('\\N')]).
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(csv, [
|
||||
parse_csv//1,
|
||||
parse_csv//2,
|
||||
write_csv/2,
|
||||
write_csv/3
|
||||
]).
|
||||
|
||||
:- use_module(library(format)).
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(iso_ext)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
|
||||
option(W, O) :-
|
||||
( member(W, O) -> true
|
||||
; throw(error(domain_error(csv_option, W), option/2))).
|
||||
|
||||
|
||||
option_extends([], Opt, Opt).
|
||||
option_extends([X | Y], Opt0, Opt) :-
|
||||
functor(X, Name, 1),
|
||||
F0 =.. [Name, _],
|
||||
( select(F0, Opt0, R) ->
|
||||
option_extends(Y, [X | R], Opt)
|
||||
; option_extends(Y, [X | Opt0], Opt) ).
|
||||
|
||||
|
||||
%% -- write --
|
||||
|
||||
|
||||
escaped_field([], []).
|
||||
escaped_field(['"' | Y], ['"', '"' | R]) :-
|
||||
escaped_field(Y, R).
|
||||
escaped_field([X | Y], [X | R]) :-
|
||||
X \== '"',
|
||||
escaped_field(Y, R).
|
||||
|
||||
|
||||
ensure_escaped(Field, Field) :-
|
||||
(atom(Field); integer(Field); float(Field)).
|
||||
ensure_escaped([X | Y], Field) :-
|
||||
escaped_field([X | Y], Field).
|
||||
|
||||
|
||||
write_field(Out, Field, Opt) :-
|
||||
( Field \== [] ->
|
||||
ensure_escaped(Field, Field0),
|
||||
format(Out, "~w", [Field0])
|
||||
; option(null_value(Null_Value), Opt),
|
||||
( Null_Value == empty -> true
|
||||
; format(Out, "~w", [Null_Value]))).
|
||||
|
||||
|
||||
write_row(Out, [Field], Opt) :-
|
||||
write_field(Out, Field, Opt).
|
||||
write_row(Out, [Field, X | Y], Opt) :-
|
||||
write_field(Out, Field, Opt),
|
||||
option(token_separator(Tk_Sep), Opt),
|
||||
format(Out, "~w", [Tk_Sep]),
|
||||
write_row(Out, [X | Y], Opt).
|
||||
|
||||
|
||||
write_rows(Out, [Row], Opt) :-
|
||||
write_row(Out, Row, Opt).
|
||||
write_rows(Out, [Row, X | Y], Opt) :-
|
||||
option(line_separator(Line_Sep), Opt),
|
||||
write_row(Out, Row, Opt),
|
||||
format(Out, "~w", [Line_Sep]),
|
||||
write_rows(Out, [X | Y], Opt).
|
||||
|
||||
|
||||
write_csv_(Out, frame(Header, Rows), Opt) :-
|
||||
option(with_header(With_Header), Opt),
|
||||
( With_Header == true ->
|
||||
write_row(Out, Header, Opt),
|
||||
option(line_separator(Line_Sep), Opt),
|
||||
format(Out, "~w", [Line_Sep])
|
||||
; true),
|
||||
write_rows(Out, Rows, Opt).
|
||||
|
||||
|
||||
write_csv(File_Name, Frm, Opt) :-
|
||||
option_extends(Opt, [
|
||||
null_value(empty),
|
||||
token_separator(','),
|
||||
with_header(true),
|
||||
line_separator('\n')
|
||||
], Opt0),
|
||||
setup_call_cleanup(
|
||||
open(File_Name, write, Out),
|
||||
write_csv_(Out, Frm, Opt0),
|
||||
close(Out)).
|
||||
write_csv(File_Name, Frm) :-
|
||||
write_csv(File_Name, Frm, []).
|
||||
|
||||
|
||||
%% -- read --
|
||||
|
||||
|
||||
tokens([], Opt), [Tk_Sep] -->
|
||||
{ option(token_separator(Tk_Sep), Opt) },
|
||||
[Tk_Sep],
|
||||
!.
|
||||
tokens([], _), "\r\n" -->
|
||||
"\r\n",
|
||||
!.
|
||||
tokens([], _), "\n" -->
|
||||
"\n",
|
||||
!.
|
||||
tokens([], _), "\r" -->
|
||||
"\r",
|
||||
!.
|
||||
tokens([X | Y], Opt) -->
|
||||
[X],
|
||||
!,
|
||||
tokens(Y, Opt).
|
||||
tokens([], _) --> [].
|
||||
|
||||
|
||||
field(R, Opt) -->
|
||||
"\"",
|
||||
!,
|
||||
string_tokens(R, Opt).
|
||||
field(R, Opt) -->
|
||||
tokens(R0, Opt),
|
||||
{ R0 \== [],
|
||||
catch(number_chars(R, R0), _, R = R0)
|
||||
}.
|
||||
field([], _) --> [].
|
||||
|
||||
|
||||
string_tokens(R, Opt) -->
|
||||
[X],
|
||||
( { X == '"' } ->
|
||||
( "\"" ->
|
||||
{ R = [X | Y] },
|
||||
string_tokens(Y, Opt)
|
||||
; { R = [] })
|
||||
; { R = [X | Y] },
|
||||
string_tokens(Y, Opt)).
|
||||
|
||||
|
||||
end_token --> "\r\n".
|
||||
end_token --> "\n".
|
||||
end_token --> "\r".
|
||||
end_token --> [].
|
||||
|
||||
|
||||
separator(Opt) -->
|
||||
{ option(token_separator(Tk_Sep), Opt) },
|
||||
[Tk_Sep].
|
||||
|
||||
|
||||
row([X | Y], Opt) -->
|
||||
field(X, Opt),
|
||||
!,
|
||||
( separator(Opt) ->
|
||||
row(Y, Opt)
|
||||
; end_token ->
|
||||
{ Y = [] }).
|
||||
|
||||
|
||||
rows(R, Opt) -->
|
||||
row(X, Opt),
|
||||
!,
|
||||
( { X \== [[]] } ->
|
||||
rows(Y, Opt),
|
||||
{ R = [X | Y] }
|
||||
; { R = [] }).
|
||||
|
||||
|
||||
parse_csv(frame(Header, Rows), Opt) -->
|
||||
{ option_extends(Opt, [
|
||||
with_header(true),
|
||||
token_separator(',')
|
||||
], Opt0)
|
||||
},
|
||||
( { option(with_header(With_Header), Opt0),
|
||||
With_Header == true } ->
|
||||
row(Header, Opt0),
|
||||
{ Header \== [[]] },
|
||||
end_token
|
||||
; { Header = [] }),
|
||||
rows(Rows, Opt0).
|
||||
parse_csv(R) -->
|
||||
parse_csv(R, []).
|
||||
@@ -1,7 +1,7 @@
|
||||
:- module(dcgs, [op(1200, xfx, -->),
|
||||
op(1105, xfy, '|'),
|
||||
phrase/2,
|
||||
phrase/3]).
|
||||
:- module(dcgs,
|
||||
[op(1105, xfy, '|'),
|
||||
phrase/2,
|
||||
phrase/3]).
|
||||
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(lists), [append/3]).
|
||||
22
src/lib/debug.pl
Normal file
22
src/lib/debug.pl
Normal file
@@ -0,0 +1,22 @@
|
||||
% Source: https://stackoverflow.com/a/30791637
|
||||
|
||||
:- module(debug, [
|
||||
op(900, fx, $),
|
||||
op(900, fx, $-),
|
||||
op(950, fy, *),
|
||||
(*)/1,
|
||||
($)/1,
|
||||
($-)/1
|
||||
]).
|
||||
|
||||
:- use_module(library(format), [portray_clause/1]).
|
||||
|
||||
$-(G_0) :-
|
||||
catch(G_0, Ex, ( portray_clause(exception:Ex:G_0), throw(Ex) ) ).
|
||||
|
||||
$(G_0) :-
|
||||
portray_clause(call:G_0),
|
||||
$-G_0,
|
||||
portray_clause(exit:G_0).
|
||||
|
||||
*(_).
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
- integer
|
||||
- atom
|
||||
- list.
|
||||
- list
|
||||
- boolean
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
must_be(Type, Term) :-
|
||||
@@ -43,8 +44,10 @@ 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_(character, character, T).
|
||||
must_be_(list, Term) :- check_(ilist, list, Term).
|
||||
must_be_(type, Term) :- check_(type, type, Term).
|
||||
must_be_(boolean, Term) :- check_(boolean, boolean, Term).
|
||||
|
||||
check_(Pred, Type, Term) :-
|
||||
( var(Term) -> instantiation_error(must_be/2)
|
||||
@@ -52,6 +55,12 @@ check_(Pred, Type, Term) :-
|
||||
; type_error(Type, Term, must_be/2)
|
||||
).
|
||||
|
||||
boolean(B) :- ( B == true ; B == false ).
|
||||
|
||||
character(C) :-
|
||||
atom(C),
|
||||
atom_length(C, 1).
|
||||
|
||||
ilist(V) :- var(V), instantiation_error(must_be/2).
|
||||
ilist([]).
|
||||
ilist([_|Ls]) :- ilist(Ls).
|
||||
@@ -59,8 +68,10 @@ ilist([_|Ls]) :- ilist(Ls).
|
||||
type(type).
|
||||
type(integer).
|
||||
type(atom).
|
||||
type(character).
|
||||
type(list).
|
||||
type(var).
|
||||
type(boolean).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
can_be(Type, Term)
|
||||
@@ -85,7 +96,9 @@ can_be(Type, Term) :-
|
||||
|
||||
can_(integer, Term) :- integer(Term).
|
||||
can_(atom, Term) :- atom(Term).
|
||||
can_(character, T) :- character(T).
|
||||
can_(list, Term) :- list_or_partial_list(Term).
|
||||
can_(boolean, Term) :- boolean(Term).
|
||||
|
||||
list_or_partial_list(Var) :- var(Var).
|
||||
list_or_partial_list([]).
|
||||
200
src/lib/files.pl
Normal file
200
src/lib/files.pl
Normal file
@@ -0,0 +1,200 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Written June 2020 by Markus Triska (triska@metalevel.at)
|
||||
Part of Scryer Prolog.
|
||||
|
||||
Predicates for reasoning about files and directories.
|
||||
|
||||
In this library, directories and files are represented as
|
||||
*lists of characters*. This is an ideal representation:
|
||||
|
||||
-) Lists of characters can be conveniently reasoned about with DCGs
|
||||
and built-in Prolog predicates from library(lists). This alone
|
||||
is already a very compelling argument to use them.
|
||||
-) Other Scryer libraries such as library(http/http_open) also already
|
||||
use lists of characters to represent paths.
|
||||
-) File names are mostly ephemeral, so it is good for efficiency
|
||||
that they can quickly allocated transiently on the heap, leaving the
|
||||
atom table mostly unaffected. Indexing is almost never needed
|
||||
for file names. If needed, it should be added to the engine.
|
||||
-) The previous point is also good for security, since the system
|
||||
leaves little trace of which files were even accessed.
|
||||
-) Scryer Prolog represents lists of characters extremely compactly.
|
||||
|
||||
Some Prolog programmers will likely find this representation quite
|
||||
unusual, because files are represented as *atoms* in many systems.
|
||||
|
||||
However, the ISO standard only demands that sources and sinks be
|
||||
*ground* terms, so lists of characters are completely admissible:
|
||||
|
||||
A source/sink is specified as an implementation defined
|
||||
ground term in a call of open/4 (8.11.5). All subsequent
|
||||
references to the source/sink are made by referring to a
|
||||
stream-term (7.10.2) or alias (7.10.2.2).
|
||||
|
||||
I believe that with the advent of Scryer Prolog and its efficient
|
||||
representation of strings as lists of characters, we should take
|
||||
this opportunity for improvement, and in fact extend the use of
|
||||
lists of characters also to other predicates like open/3.
|
||||
|
||||
Please note that we *cannot* simply accept *both* representations,
|
||||
because that would invalidate the type errors raised by this library,
|
||||
and make future extensions for type checking impossible.
|
||||
|
||||
So I ask you: Please try out this representation for a few months.
|
||||
It simplifies working with files considerably. Once we have collected
|
||||
more experience with this representations, please let us consider
|
||||
how to proceed in such a way that we can call it an improvement.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(files, [directory_files/2,
|
||||
file_size/2,
|
||||
file_exists/1,
|
||||
directory_exists/1,
|
||||
delete_file/1,
|
||||
make_directory/1,
|
||||
working_directory/2,
|
||||
path_canonical/2,
|
||||
path_segments/2,
|
||||
file_modification_time/2,
|
||||
file_creation_time/2,
|
||||
file_access_time/2]).
|
||||
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(charsio)).
|
||||
|
||||
list_of_chars(Cs) :-
|
||||
must_be(list, Cs),
|
||||
maplist(must_be(character), Cs).
|
||||
|
||||
directory_files(Directory, Files) :-
|
||||
list_of_chars(Directory),
|
||||
can_be(list, Files),
|
||||
'$directory_files'(Directory, Files).
|
||||
|
||||
file_size(File, Size) :-
|
||||
list_of_chars(File),
|
||||
can_be(integer, Size),
|
||||
'$file_size'(File, Size).
|
||||
|
||||
file_exists(File) :-
|
||||
list_of_chars(File),
|
||||
'$file_exists'(File).
|
||||
|
||||
directory_exists(Directory) :-
|
||||
list_of_chars(Directory),
|
||||
'$directory_exists'(Directory).
|
||||
|
||||
make_directory(Directory) :-
|
||||
list_of_chars(Directory),
|
||||
'$make_directory'(Directory).
|
||||
|
||||
delete_file(File) :-
|
||||
list_of_chars(File),
|
||||
'$delete_file'(File).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dir0 is the current working directory, and the working directory
|
||||
is changed to Dir.
|
||||
|
||||
Use working_directory(Ds, Ds) to determine the current working directory,
|
||||
and leave it as is.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
working_directory(Dir0, Dir) :-
|
||||
can_be(list, Dir0),
|
||||
can_be(list, Dir),
|
||||
'$working_directory'(Dir0, Dir).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
True iff Cs is the canonical, absolute path of Ps.
|
||||
|
||||
All intermediate components are normalized, and all symbolic links
|
||||
are resolved.
|
||||
|
||||
The predicate fails in the following situations, though not
|
||||
necessarily *only* in these cases:
|
||||
|
||||
1. Ps is a path that does not exist.
|
||||
2. A non-final component in Ps is not a directory.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
path_canonical(Ps, Cs) :-
|
||||
must_be(list, Ps),
|
||||
maplist(must_be(character), Ps),
|
||||
can_be(list, Cs),
|
||||
'$path_canonical'(Ps, Cs).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
T is, respectively, the modification, access or creation time of File.
|
||||
T is a time stamp, suitable for use in format_time//2 in library(time).
|
||||
|
||||
For two time stamps A and B, if A precedes B, then A @< B holds.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
file_modification_time(File, T) :-
|
||||
file_time_(File, modification, T).
|
||||
|
||||
file_access_time(File, T) :-
|
||||
file_time_(File, access, T).
|
||||
|
||||
file_creation_time(File, T) :-
|
||||
file_time_(File, creation, T).
|
||||
|
||||
file_time_(File, Which, T) :-
|
||||
'$file_time'(File, Which, T0),
|
||||
read_term_from_chars(T0, T).
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
path_segments(Ps, Segments): True iff Segments are the segments of Ps.
|
||||
|
||||
Segments is the list of components of the path Ps that are
|
||||
separated by the platform-specific directory separator. Each
|
||||
segment is a list of characters.
|
||||
|
||||
At least one of the arguments must be instantiated.
|
||||
|
||||
Examples:
|
||||
|
||||
?- path_segments("/hello/there", Segments).
|
||||
Segments = [[],"hello","there"]
|
||||
; false.
|
||||
|
||||
?- path_segments(Path, ["hello","there"]).
|
||||
Path = "hello/there"
|
||||
; false.
|
||||
|
||||
|
||||
To obtain the platform-specific directory separator, you can use:
|
||||
|
||||
?- path_segments(Separator, ["",""]).
|
||||
Separator = "/"
|
||||
; false.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
path_segments(Path, Segments) :-
|
||||
'$directory_separator'(Sep),
|
||||
( var(Path) ->
|
||||
must_be(list, Segments),
|
||||
maplist(list_of_chars, Segments),
|
||||
append_with_separator(Segments, Sep, Path)
|
||||
; list_of_chars(Path),
|
||||
path_to_segments(Path, Sep, Segments)
|
||||
).
|
||||
|
||||
append_with_separator([], _, []).
|
||||
append_with_separator([Segment|Segments], Sep, Path) :-
|
||||
append_with_separator_(Segments, Segment, Sep, Path).
|
||||
|
||||
append_with_separator_([], Segment, _, Segment).
|
||||
append_with_separator_([Segment|Segments], Prev, Sep, Path) :-
|
||||
append(Prev, [Sep|Rest], Path),
|
||||
append_with_separator_(Segments, Segment, Sep, Rest).
|
||||
|
||||
path_to_segments(Path, Sep, Segments) :-
|
||||
( append(Front, [Sep|Ps], Path) ->
|
||||
Segments = [Front|Rest],
|
||||
path_to_segments(Ps, Sep, Rest)
|
||||
; Segments = [Path]
|
||||
).
|
||||
@@ -3,7 +3,7 @@
|
||||
Part of Scryer Prolog.
|
||||
|
||||
This library provides the nonterminal format_//2 to describe
|
||||
formatted strings. format/2 is provided for impure output.
|
||||
formatted strings. format/[2,3] are provided for impure output.
|
||||
|
||||
Usage:
|
||||
======
|
||||
@@ -74,6 +74,7 @@
|
||||
format/2,
|
||||
format/3,
|
||||
portray_clause/1,
|
||||
portray_clause/2,
|
||||
listing/1
|
||||
]).
|
||||
|
||||
@@ -158,7 +159,7 @@ element_gluevar(glue(_,V), N, N) --> [V].
|
||||
|
||||
cells([], Args, Tab, Es) -->
|
||||
( { Args == [] } -> cell(Tab, Tab, Es)
|
||||
; { domain_error(no_remaining_arguments, Args, format_//2) }
|
||||
; { domain_error(empty_list, Args, format_//2) }
|
||||
).
|
||||
cells([~,~|Fs], Args, Tab, Es) --> !,
|
||||
cells(Fs, Args, Tab, [chars("~")|Es]).
|
||||
@@ -172,9 +173,11 @@ cells([~,a|Fs], [Arg|Args], Tab, Es) --> !,
|
||||
{ atom_chars(Arg, Chars) },
|
||||
cells(Fs, Args, Tab, [chars(Chars)|Es]).
|
||||
cells([~|Fs0], Args0, Tab, Es) -->
|
||||
{ numeric_argument(Fs0, Num, [d|Fs], Args0, [Arg|Args]) },
|
||||
{ numeric_argument(Fs0, Num, [d|Fs], Args0, [Arg0|Args]) },
|
||||
!,
|
||||
{ number_chars(Arg, Cs0) },
|
||||
{ Arg is Arg0, % evaluate compound expression
|
||||
must_be(integer, Arg),
|
||||
number_chars(Arg, Cs0) },
|
||||
( { Num =:= 0 } -> { Cs = Cs0 }
|
||||
; { length(Cs0, L),
|
||||
( L =< Num ->
|
||||
@@ -216,12 +219,12 @@ cells([~|Fs0], Args0, Tab, Es) -->
|
||||
cells([~,s|Fs], [Arg|Args], Tab, Es) --> !,
|
||||
cells(Fs, Args, Tab, [chars(Arg)|Es]).
|
||||
cells([~,f|Fs], [Arg|Args], Tab, Es) --> !,
|
||||
{ number_chars(Arg, Chars) },
|
||||
{ format_number_chars(Arg, Chars) },
|
||||
cells(Fs, Args, Tab, [chars(Chars)|Es]).
|
||||
cells([~|Fs0], Args0, Tab, Es) -->
|
||||
{ numeric_argument(Fs0, Num, [f|Fs], Args0, [Arg|Args]) },
|
||||
!,
|
||||
{ number_chars(Arg, Cs0),
|
||||
{ format_number_chars(Arg, Cs0),
|
||||
phrase(upto_what(Bs, .), Cs0, Cs),
|
||||
( Num =:= 0 -> Chars = Bs
|
||||
; ( Cs = ['.'|Rest] ->
|
||||
@@ -279,6 +282,10 @@ cells(Fs0, Args, Tab, Es) -->
|
||||
Fs1 = [_|_] },
|
||||
cells(Fs, Args, Tab, [chars(Fs1)|Es]).
|
||||
|
||||
format_number_chars(N0, Chars) :-
|
||||
N is N0, % evaluate compound expression
|
||||
number_chars(N, Chars).
|
||||
|
||||
n_newlines(0) --> !.
|
||||
n_newlines(N0) --> { N0 > 0, N is N0 - 1 }, [newline], n_newlines(N).
|
||||
|
||||
@@ -327,7 +334,8 @@ pow10(D, N0-Pow0, N-Pow) :-
|
||||
N is N0 + D*10^Pow0,
|
||||
Pow is Pow0 + 1.
|
||||
|
||||
integer_to_radix(I, R, Which, Cs) :-
|
||||
integer_to_radix(I0, R, Which, Cs) :-
|
||||
I is I0, % evaluate compound expression
|
||||
must_be(integer, I),
|
||||
must_be(integer, R),
|
||||
( \+ between(2, 36, R) ->
|
||||
@@ -361,28 +369,16 @@ digits(uppercase, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
format(Fs, Args) :-
|
||||
phrase(format_(Fs, Args), Cs),
|
||||
maplist(write, Cs).
|
||||
current_output(Stream),
|
||||
format(Stream, Fs, Args).
|
||||
|
||||
format(Stream, Fs, Args) :-
|
||||
phrase(format_(Fs, Args), Cs),
|
||||
( stream_property(Stream, type(binary)) ->
|
||||
% maplist(char_code, Cs, Bytes) is currently a lot slower
|
||||
% than first converting Cs to an atom, and then to codes.
|
||||
% In the future, we can ideally avoid creating an atom here,
|
||||
% since an atom leaves traces in the system.
|
||||
atom_chars(A, Cs),
|
||||
atom_codes(A, Bytes),
|
||||
( member(NonByte, Bytes), NonByte > 255 ->
|
||||
char_code(Char, NonByte),
|
||||
throw(error(representation_error(Char), format/3))
|
||||
; true
|
||||
),
|
||||
% For binary streams, we use a specialised internal predicate
|
||||
% that uses only a single "write" operation for efficiency.
|
||||
'$put_bytes'(Stream, Bytes)
|
||||
; maplist(put_char(Stream), Cs)
|
||||
).
|
||||
% we use a specialised internal predicate that uses only a
|
||||
% single "write" operation for efficiency. It is equivalent to
|
||||
% maplist(put_char(Stream), Cs). It also works for binary streams.
|
||||
'$put_chars'(Stream, Cs),
|
||||
flush_output(Stream).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
?- phrase(cells("hello", [], 0, []), Cs).
|
||||
@@ -458,8 +454,12 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
portray_clause(Term) :-
|
||||
current_output(Out),
|
||||
portray_clause(Out, Term).
|
||||
|
||||
portray_clause(Stream, Term) :-
|
||||
phrase(portray_clause_(Term), Ls),
|
||||
maplist(write, Ls).
|
||||
format(Stream, "~s", [Ls]).
|
||||
|
||||
portray_clause_(Term) -->
|
||||
{ term_variables(Term, Vs),
|
||||
84
src/lib/http/http_open.pl
Normal file
84
src/lib/http/http_open.pl
Normal file
@@ -0,0 +1,84 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Written June 2020 by Markus Triska (triska@metalevel.at)
|
||||
Part of Scryer Prolog.
|
||||
|
||||
http_open(+Address, -Stream, +Options)
|
||||
======================================
|
||||
|
||||
Yields Stream to read the body of an HTTP reply from Address.
|
||||
Address is a list of characters, and includes the method. Both HTTP
|
||||
and HTTPS are supported. Redirects are followed.
|
||||
|
||||
Currently, Options must be the empty list. Options may be
|
||||
added in the future to give more control over the connection.
|
||||
|
||||
We use HTTP/1.0 until we can read chunked transfer-encoding.
|
||||
|
||||
Example:
|
||||
|
||||
?- http_open("https://github.com/mthom/scryer-prolog", S, []).
|
||||
%@ S = '$stream'(0x7f86f94a6cd0)
|
||||
%@ ; false.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(http_open, [http_open/3]).
|
||||
|
||||
:- use_module(library(sockets)).
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(format)).
|
||||
:- use_module(library(charsio)).
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(lists), [member/2]).
|
||||
|
||||
http_open(Address, Stream, Options) :-
|
||||
must_be(list, Options),
|
||||
must_be(list, Address),
|
||||
once(phrase((list(SchemeCs), "://", list(Rest)), Address)),
|
||||
atom_chars(Scheme, SchemeCs),
|
||||
chars_host_url(Rest, Host, URL),
|
||||
connect(Scheme, Host, Stream0),
|
||||
format(Stream0, "\
|
||||
GET ~s HTTP/1.0\r\n\
|
||||
Host: ~w\r\n\
|
||||
User-Agent: Scryer Prolog\r\n\
|
||||
Connection: close\r\n\r\n\
|
||||
", [URL,Host]),
|
||||
read_line_to_chars(Stream0, StatusLine, []),
|
||||
once(phrase(("HTTP/1.",(['0']|['1'])," ",[D1]), StatusLine, _)),
|
||||
read_header_lines(Stream0, HeaderLines),
|
||||
handle_response(D1, HeaderLines, Stream0, Stream).
|
||||
|
||||
list([]) --> [].
|
||||
list([L|Ls]) --> [L], list(Ls).
|
||||
|
||||
handle_response('2', _, Stream, Stream). % ok
|
||||
handle_response('3', HeaderLines, Stream0, Stream) :- % redirect
|
||||
close(Stream0),
|
||||
once((member(Line, HeaderLines),
|
||||
phrase(("Location: ",list(Location),"\r\n"), Line))),
|
||||
http_open(Location, Stream, []).
|
||||
|
||||
% Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
|
||||
|
||||
read_header_lines(Stream, Hs) :-
|
||||
read_line_to_chars(Stream, Cs, []),
|
||||
( Cs == "" -> Hs = []
|
||||
; Cs == "\r\n" -> Hs = []
|
||||
; Hs = [Cs|Rest],
|
||||
read_header_lines(Stream, Rest)
|
||||
).
|
||||
|
||||
chars_host_url(Cs, Host, [/|Us]) :-
|
||||
( phrase((list(Hs),"/",list(Us)), Cs) ->
|
||||
true
|
||||
; Hs = Cs,
|
||||
Us = []
|
||||
),
|
||||
atom_chars(Host, Hs).
|
||||
|
||||
connect(https, Host, Stream) :-
|
||||
socket_client_open(Host:443, Stream, [tls(true)]).
|
||||
connect(http, Host, Stream) :-
|
||||
socket_client_open(Host:80, Stream, []).
|
||||
|
||||
58
src/lib/os.pl
Normal file
58
src/lib/os.pl
Normal file
@@ -0,0 +1,58 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Predicates for reasoning about the operating system (OS) environment.
|
||||
Written July 2020 by Markus Triska (triska@metalevel.at).
|
||||
|
||||
Lists of characters are used throughout to represent keys and values.
|
||||
|
||||
Example:
|
||||
|
||||
?- getenv("LANG", Ls).
|
||||
Ls = "en_US.UTF-8"
|
||||
; false.
|
||||
|
||||
Public domain code.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(os, [getenv/2,
|
||||
setenv/2,
|
||||
unsetenv/1]).
|
||||
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(charsio)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
getenv(Key, Value) :-
|
||||
must_be_env_var(Key),
|
||||
'$getenv'(Key, Value).
|
||||
|
||||
setenv(Key, Value) :-
|
||||
must_be_env_var(Key),
|
||||
must_be_chars(Value),
|
||||
'$setenv'(Key, Value).
|
||||
|
||||
unsetenv(Key) :-
|
||||
must_be_env_var(Key),
|
||||
'$unsetenv'(Key).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
For now, we only support a restricted subset of variable names.
|
||||
|
||||
The reason is that Rust may panic if a key is empty, contains an
|
||||
ASCII equals sign '=' or the NUL character '\0', or when the value
|
||||
contains the NUL character.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
must_be_env_var(Cs) :-
|
||||
must_be_chars(Cs),
|
||||
Cs = [_|_],
|
||||
( maplist(permitted, Cs) -> true
|
||||
; domain_error(env_var, Cs, os)
|
||||
).
|
||||
|
||||
permitted(C) :- char_type(C, alnum).
|
||||
permitted(C) :- char_type(C, ascii_punctuation).
|
||||
permitted('_').
|
||||
|
||||
must_be_chars(Cs) :-
|
||||
must_be(list, Cs),
|
||||
maplist(must_be(character), Cs).
|
||||
42
src/lib/pio.pl
Normal file
42
src/lib/pio.pl
Normal file
@@ -0,0 +1,42 @@
|
||||
:- module(pio, [phrase_from_file/2,
|
||||
phrase_from_file/3]).
|
||||
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(freeze)).
|
||||
:- use_module(library(iso_ext), [setup_call_cleanup/3, partial_string/3]).
|
||||
:- use_module(library(lists), [member/2]).
|
||||
|
||||
phrase_from_file(NT, File) :-
|
||||
phrase_from_file(NT, File, []).
|
||||
|
||||
phrase_from_file(NT, File, Options) :-
|
||||
( var(File) -> instantiation_error(phrase_from_file/3)
|
||||
; (\+ atom(File) ; File = []) ->
|
||||
domain_error(source_sink, File, phrase_from_file/3)
|
||||
; must_be(list, Options),
|
||||
( member(Var, Options), var(Var) -> instantiation_error(phrase_from_file/3)
|
||||
; member(type(Type), Options) ->
|
||||
must_be(atom, Type),
|
||||
member(Type, [text,binary])
|
||||
; Type = text
|
||||
),
|
||||
setup_call_cleanup(open(File, read, Stream, [reposition(true)|Options]),
|
||||
( stream_to_lazy_list(Stream, Xs),
|
||||
phrase(NT, Xs) ),
|
||||
close(Stream))
|
||||
).
|
||||
|
||||
|
||||
stream_to_lazy_list(Stream, Xs) :-
|
||||
stream_property(Stream, position(Pos)),
|
||||
freeze(Xs, reader_step(Stream, Pos, Xs)).
|
||||
|
||||
reader_step(Stream, Pos, Xs0) :-
|
||||
set_stream_position(Stream, Pos),
|
||||
( at_end_of_stream(Stream)
|
||||
-> Xs0 = []
|
||||
; '$get_n_chars'(Stream, 4096, Cs),
|
||||
partial_string(Cs, Xs0, Xs),
|
||||
stream_to_lazy_list(Stream, Xs)
|
||||
).
|
||||
92
src/lib/sgml.pl
Normal file
92
src/lib/sgml.pl
Normal file
@@ -0,0 +1,92 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Predicates for parsing HTML and XML documents.
|
||||
Written June 2020 by Markus Triska (triska@metalevel.at)
|
||||
Part of Scryer Prolog.
|
||||
|
||||
Currently, two predicates are provided:
|
||||
|
||||
- load_html(+Source, -Es, +Options)
|
||||
- load_xml(+Source, -Es, +Options)
|
||||
|
||||
These predicates parse HTML and XML documents, respectively.
|
||||
|
||||
Source must be a stream, specified as stream(S), or a file,
|
||||
specified as file(Name), where Name is a list of characters, or a
|
||||
list of characters with the document contents.
|
||||
|
||||
Es is unified with the abstract syntax tree of the parsed document,
|
||||
represented as a list of elements where each is of the form:
|
||||
|
||||
* a list of characters, representing text
|
||||
* element(Name, Attrs, Children)
|
||||
- Name is the name of the tag
|
||||
- Attrs is a list of Key=Value pairs:
|
||||
Key is an atom, and Value is a list of characters
|
||||
- Children is a list of elements as specified here.
|
||||
|
||||
Currently, Options are ignored. In the future, more options may be
|
||||
provided to control parsing.
|
||||
|
||||
Example:
|
||||
|
||||
?- load_html("<html><head><title>Hello!</title></head></html>", Es, []).
|
||||
|
||||
Yielding:
|
||||
|
||||
Es = [element(html,[],
|
||||
[element(head,[],
|
||||
[element(title,[],
|
||||
["Hello!"])]),
|
||||
element(body,[],[])])].
|
||||
|
||||
library(xpath) provides convenient reasoning about parsed documents.
|
||||
For example, to fetch the title of the document above, we can use:
|
||||
|
||||
?- load_html("<html><head><title>Hello!</title></head></html>", Es, []),
|
||||
xpath(Es, //title(text), T).
|
||||
|
||||
Yielding T = "Hello!".
|
||||
|
||||
Use http_open/3 from library(http/http_open) to read answers from
|
||||
web servers via streams.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(sgml, [load_html/3,
|
||||
load_xml/3]).
|
||||
|
||||
:- use_module(library(iso_ext)).
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(pio)).
|
||||
|
||||
load_html(Source, Es, Options) :-
|
||||
load_structure_(Source, Es, Options, html).
|
||||
load_xml(Source, Es, Options) :-
|
||||
load_structure_(Source, Es, Options, xml).
|
||||
|
||||
list([]) --> [].
|
||||
list([L|Ls]) --> [L], list(Ls).
|
||||
|
||||
load_structure_([], [], _, _).
|
||||
load_structure_([C|Cs], [E], Options, What) :-
|
||||
load_(What, [C|Cs], E, Options).
|
||||
load_structure_(file(Fs), [E], Options, What) :-
|
||||
must_be(list, Options),
|
||||
must_be(list, Fs),
|
||||
atom_chars(File, Fs),
|
||||
once(phrase_from_file(list(Cs), File)),
|
||||
load_(What, Cs, E, Options).
|
||||
load_structure_(stream(Stream), [E], Options, What) :-
|
||||
must_be(list, Options),
|
||||
read_to_end(Stream, Cs),
|
||||
load_(What, Cs, E, Options).
|
||||
|
||||
load_(html, Cs, E, Options) :- '$load_html'(Cs, E, Options).
|
||||
load_(xml, Cs, E, Options) :- '$load_xml'(Cs, E, Options).
|
||||
|
||||
read_to_end(Stream, Cs) :-
|
||||
'$get_n_chars'(Stream, 4096, Cs0),
|
||||
( Cs0 = [] -> Cs = []
|
||||
; partial_string(Cs0, Cs, Rest),
|
||||
read_to_end(Stream, Rest)
|
||||
).
|
||||
@@ -6,7 +6,16 @@
|
||||
current_hostname/1]).
|
||||
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
parse_socket_options_(tls(TLS), tls-TLS) :-
|
||||
must_be(boolean, TLS), !.
|
||||
parse_socket_options_(Option, OptionPair) :-
|
||||
builtins:parse_stream_options_(Option, OptionPair).
|
||||
|
||||
parse_socket_options(Options, OptionValues, Stub) :-
|
||||
DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, tls-false, type-text],
|
||||
builtins:parse_options_list(Options, parse_socket_options_, DefaultOptions, OptionValues, Stub).
|
||||
|
||||
socket_client_open(Addr, Stream, Options) :-
|
||||
( var(Addr) ->
|
||||
@@ -23,10 +32,10 @@ socket_client_open(Addr, Stream, Options) :-
|
||||
;
|
||||
throw(error(type_error(socket_address, Addr), socket_client_open/3))
|
||||
),
|
||||
builtins:parse_stream_options(Options,
|
||||
[Alias, EOFAction, Reposition, Type],
|
||||
socket_client_open/3),
|
||||
'$socket_client_open'(Address, Port, Stream, Alias, EOFAction, Reposition, Type).
|
||||
parse_socket_options(Options,
|
||||
[Alias, EOFAction, Reposition, TLS, Type],
|
||||
socket_client_open/3),
|
||||
'$socket_client_open'(Address, Port, Stream, Alias, EOFAction, Reposition, Type, TLS).
|
||||
|
||||
|
||||
socket_server_open(Addr, ServerSocket) :-
|
||||
@@ -8,12 +8,12 @@
|
||||
op(1150, fx, table)
|
||||
]).
|
||||
|
||||
:- use_module('tabling/double_linked_list').
|
||||
:- use_module('tabling/table_data_structure').
|
||||
:- use_module('tabling/batched_worklist').
|
||||
:- use_module('tabling/wrapper').
|
||||
:- use_module('tabling/global_worklist').
|
||||
:- use_module('tabling/table_link_manager').
|
||||
:- use_module(library(tabling/double_linked_list)).
|
||||
:- use_module(library(tabling/table_data_structure)).
|
||||
:- use_module(library(tabling/batched_worklist)).
|
||||
:- use_module(library(tabling/wrapper)).
|
||||
:- use_module(library(tabling/global_worklist)).
|
||||
:- use_module(library(tabling/table_link_manager)).
|
||||
|
||||
:- use_module(library(cont)).
|
||||
:- use_module(library(lists)).
|
||||
@@ -45,8 +45,8 @@
|
||||
wkl_worklist_work_done/1 % +WorkList
|
||||
]).
|
||||
|
||||
:- use_module(global_worklist).
|
||||
:- use_module(double_linked_list).
|
||||
:- use_module(library(tabling/global_worklist)).
|
||||
:- use_module(library(tabling/double_linked_list)).
|
||||
|
||||
:- use_module(library(atts)).
|
||||
:- use_module(library(lists)).
|
||||
@@ -15,8 +15,8 @@
|
||||
get_nb_identifiers/3 % +Table, -NbWorklistID, -NbAnswerTreeID
|
||||
]).
|
||||
|
||||
:- use_module(table_link_manager).
|
||||
:- use_module(trie).
|
||||
:- use_module(library(tabling/table_link_manager)).
|
||||
:- use_module(library(tabling/trie)).
|
||||
|
||||
/* Part of SWI-Prolog
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
:- use_module(batched_worklist).
|
||||
:- use_module(library(tabling/batched_worklist)).
|
||||
|
||||
:- use_module(library(atts)).
|
||||
:- use_module(library(gensym)).
|
||||
@@ -47,7 +47,7 @@
|
||||
:- use_module(library(iso_ext)).
|
||||
:- use_module(library(terms)).
|
||||
|
||||
:- use_module(trie).
|
||||
:- use_module(library(tabling/trie)).
|
||||
|
||||
:- attribute trie_table_link/1.
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
% p_trie_arity_univ(+Term,-FunctorData,-ArgumentsList).
|
||||
p_trie_arity_univ(Term,functor_data(Name,Arity),Arguments) :-
|
||||
( var(Term) ->
|
||||
Name = var,
|
||||
Name = Term,
|
||||
Arity = 0,
|
||||
Arguments = []
|
||||
; Term =.. [Name|Arguments],
|
||||
129
src/lib/time.pl
Normal file
129
src/lib/time.pl
Normal file
@@ -0,0 +1,129 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Written 2020 by Markus Triska (triska@metalevel.at)
|
||||
Part of Scryer Prolog.
|
||||
|
||||
This library provides predicates for reasoning about time.
|
||||
|
||||
current_time(T) yields the current system time in an opaque form,
|
||||
called a time stamp. Use format_time//2 to describe strings that
|
||||
contain attributes of the time stamp.
|
||||
|
||||
The nonterminal format_time//2 describes a list of characters that
|
||||
are formatted according to a format string. Usage:
|
||||
|
||||
phrase(format_time(FormatString, TimeStamp), Cs)
|
||||
|
||||
TimeStamp represents a moment in time in an opaque form, as for
|
||||
example obtained by current_time/1.
|
||||
|
||||
FormatString is a list of characters that are interpreted literally,
|
||||
except for the following specifiers (and possibly more in the future):
|
||||
|
||||
%Y year of the time stamp. Example: 2020.
|
||||
%m month number (01-12), zero-padded to 2 digits
|
||||
%d day number (01-31), zero-padded to 2 digits
|
||||
%H hour number (00-24), zero-padded to 2 digits
|
||||
%M minute number (00-59), zero-padded to 2 digits
|
||||
%S second number (00-60), zero-padded to 2 digits
|
||||
%b abbreviated month name, always 3 letters
|
||||
%a abbreviated weekday name, always 3 letters
|
||||
%A full weekday name
|
||||
%j day of the year (001-366), zero-padded to 3 digits
|
||||
%% the literal %
|
||||
|
||||
Example:
|
||||
|
||||
?- current_time(T), phrase(format_time("%d.%m.%Y (%H:%M:%S)", T), Cs).
|
||||
T = [...], Cs = "11.06.2020 (00:24:32)"
|
||||
; false.
|
||||
|
||||
sleep(S) sleeps for S seconds (a floating point number).
|
||||
|
||||
time(Goal) reports the execution time of Goal.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(time, [max_sleep_time/1, sleep/1, time/1, current_time/1, format_time//2]).
|
||||
|
||||
:- use_module(library(format)).
|
||||
:- use_module(library(iso_ext)).
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(charsio), [read_term_from_chars/2]).
|
||||
|
||||
current_time(T) :-
|
||||
'$current_time'(T0),
|
||||
read_term_from_chars(T0, T).
|
||||
|
||||
format_time([], _) --> [].
|
||||
format_time(['%','%'|Fs], T) --> !, "%", format_time(Fs, T).
|
||||
format_time(['%',Spec|Fs], T) --> !,
|
||||
( { member(Spec=Value, T) } ->
|
||||
list(Value)
|
||||
; { domain_error(time_specifier, Spec, format_time//2) }
|
||||
),
|
||||
format_time(Fs, T).
|
||||
format_time([F|Fs], T) --> [F], format_time(Fs, T).
|
||||
|
||||
list([]) --> [].
|
||||
list([L|Ls]) --> [L], list(Ls).
|
||||
|
||||
max_sleep_time(0xfffffffffffffbff).
|
||||
|
||||
sleep(T) :-
|
||||
builtins:must_be_number(T, sleep),
|
||||
( T < 0 ->
|
||||
domain_error(not_less_than_zero, T, sleep/1)
|
||||
; max_sleep_time(N), T > N ->
|
||||
throw(error(representation_error(max_sleep_time), sleep/1))
|
||||
; '$sleep'(T)
|
||||
).
|
||||
|
||||
|
||||
% '$cpu_now' can be replaced by statistics/2 once that is implemented.
|
||||
|
||||
time(Goal) :-
|
||||
'$cpu_now'(T0),
|
||||
setup_call_cleanup(true,
|
||||
( Goal,
|
||||
report_time(T0)
|
||||
),
|
||||
report_time(T0)).
|
||||
|
||||
report_time(T0) :-
|
||||
'$cpu_now'(T),
|
||||
Time is T - T0,
|
||||
( bb_get('$first_answer', true) ->
|
||||
format(" % CPU time: ~3f seconds~n", [Time])
|
||||
; format("% CPU time: ~3f seconds~n ", [Time])
|
||||
).
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
?- time((true;false)).
|
||||
% CPU time: 0.000 seconds
|
||||
true
|
||||
; % CPU time: 0.001 seconds
|
||||
false.
|
||||
|
||||
:- time(use_module(library(clpz))).
|
||||
% CPU time: 2.762 seconds
|
||||
true
|
||||
; false.
|
||||
|
||||
:- time(use_module(library(lists))).
|
||||
% CPU time: 0.000 seconds
|
||||
true
|
||||
; % CPU time: 0.001 seconds
|
||||
false.
|
||||
|
||||
?- time(member(X, [a,b,c])).
|
||||
% CPU time: 0.000 seconds
|
||||
X = a
|
||||
; % CPU time: 0.002 seconds
|
||||
X = b
|
||||
; % CPU time: 0.004 seconds
|
||||
X = c
|
||||
; % CPU time: 0.007 seconds
|
||||
false.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
642
src/lib/xpath.pl
Normal file
642
src/lib/xpath.pl
Normal file
@@ -0,0 +1,642 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
The original copyright and licence information is shown below.
|
||||
|
||||
Adapted in June 2020 by Markus Triska (triska@metalevel.at)
|
||||
Part of Scryer Prolog.
|
||||
|
||||
In order to improve portability and reliability of this library, I
|
||||
have changed various parts of the original code to make it
|
||||
conforming to the Prolog ISO standard. I have removed all
|
||||
occurrences of proprietary non-standard ad hoc data types.
|
||||
|
||||
In Scryer Prolog, we represent strings as lists of characters.
|
||||
This makes them amenable to processing with DCGs and other
|
||||
built-in mechanisms such as existing predicates on lists.
|
||||
Scryer Prolog represents lists of characters very compactly,
|
||||
making it an ideal representation for large amounts of text. It
|
||||
fully conforms to the ISO standard and is very portable.
|
||||
|
||||
This library is intended to be used in tandem with load_html/3
|
||||
from library(sgml), which creates DOM trees from markup documents.
|
||||
It can be combined with http_open/3 from library(http/http_open)
|
||||
to read such documents directly from network connections.
|
||||
|
||||
For instance, to inspect all links to Prolog files (*.pl) on
|
||||
Scryer Prolog's project page, we can use:
|
||||
|
||||
:- use_module(library(http/http_open)).
|
||||
:- use_module(library(sgml)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(xpath)).
|
||||
|
||||
link_to_pl_file(File) :-
|
||||
http_open("https://github.com/mthom/scryer-prolog", S, []),
|
||||
load_html(stream(S), DOM, []),
|
||||
xpath(DOM, //a(@href), File),
|
||||
append(_, ".pl", File).
|
||||
|
||||
Yielding:
|
||||
|
||||
?- link_to_pl_file(File).
|
||||
%@ File = "/mthom/scryer-prolog/blob/master/src/lib/tabling.pl"
|
||||
%@ ; File = "/mthom/scryer-prolog/blob/master/src/lib/dif.pl"
|
||||
%@ ; File = "/mthom/scryer-prolog/blob/master/src/lib/freeze.pl"
|
||||
%@ ; ...
|
||||
|
||||
Parts of the original functionality may not yet work. Please
|
||||
consider such parts opportunities for improvements, and file
|
||||
issues in case you need additional features.
|
||||
|
||||
The original copyright information follows.
|
||||
|
||||
======================================================================
|
||||
|
||||
|
||||
Author: Jan Wielemaker
|
||||
E-mail: J.Wielemaker@vu.nl
|
||||
WWW: http://www.swi-prolog.org
|
||||
Copyright (c) 2009-2019, University of Amsterdam
|
||||
VU University Amsterdam
|
||||
CWI, Amsterdam
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
:- module(xpath,
|
||||
[ xpath/3, % +DOM, +Spec, -Value
|
||||
xpath_chk/3, % +DOM, +Spec, -Value
|
||||
|
||||
op(400, fx, //),
|
||||
op(400, fx, /),
|
||||
op(200, fy, @)
|
||||
]).
|
||||
|
||||
:- use_module(library(lists),[member/2,memberchk/2]).
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(si)).
|
||||
|
||||
/** <module> Select nodes in an XML DOM
|
||||
|
||||
The library xpath.pl provides predicates to select nodes from an XML DOM
|
||||
tree as produced by library(sgml) based on descriptions inspired by the
|
||||
XPath language.
|
||||
|
||||
The predicate xpath/3 selects a sub-structure of the DOM
|
||||
non-deterministically based on an XPath-like specification. Not all
|
||||
selectors of XPath are implemented, but the ability to mix xpath/3 calls
|
||||
with arbitrary Prolog code provides a powerful tool for extracting
|
||||
information from XML parse-trees.
|
||||
|
||||
@see http://www.w3.org/TR/xpath
|
||||
*/
|
||||
|
||||
element_name(element(Name,_,_), Name).
|
||||
element_attributes(element(_,Attributes,_), Attributes).
|
||||
element_content(element(_,_,Content), Content).
|
||||
|
||||
%! xpath_chk(+DOM, +Spec, ?Content) is semidet.
|
||||
%
|
||||
% Semi-deterministic version of xpath/3.
|
||||
|
||||
xpath_chk(DOM, Spec, Content) :-
|
||||
xpath(DOM, Spec, Content),
|
||||
!.
|
||||
|
||||
%! xpath(+DOM, +Spec, ?Content) is nondet.
|
||||
%
|
||||
% Match an element in a DOM structure. The syntax is inspired by
|
||||
% XPath, using () rather than [] to select inside an element.
|
||||
% First we can construct paths using / and //:
|
||||
%
|
||||
% $ =|//|=Term :
|
||||
% Select any node in the DOM matching term.
|
||||
% $ =|/|=Term :
|
||||
% Match the root against Term.
|
||||
% $ Term :
|
||||
% Select the immediate children of the root matching Term.
|
||||
%
|
||||
% The Terms above are of type _callable_. The functor specifies
|
||||
% the element name. The element name '*' refers to any element.
|
||||
% The name =self= refers to the top-element itself and is often
|
||||
% used for processing matches of an earlier xpath/3 query. A term
|
||||
% NS:Term refers to an XML name in the namespace NS. Optional
|
||||
% arguments specify additional constraints and functions. The
|
||||
% arguments are processed from left to right. Defined conditional
|
||||
% argument values are:
|
||||
%
|
||||
% $ index(?Index) :
|
||||
% True if the element is the Index-th child of its parent,
|
||||
% where 1 denotes the first child. Index can be one of:
|
||||
% $ `Var` :
|
||||
% `Var` is unified with the index of the matched element.
|
||||
% $ =last= :
|
||||
% True for the last element.
|
||||
% $ =last= - `IntExpr` :
|
||||
% True for the last-minus-nth element. For example,
|
||||
% `last-1` is the element directly preceding the last one.
|
||||
% $ `IntExpr` :
|
||||
% True for the element whose index equals `IntExpr`.
|
||||
% $ Integer :
|
||||
% The N-th element with the given name, with 1 denoting the
|
||||
% first element. Same as index(Integer).
|
||||
% $ =last= :
|
||||
% The last element with the given name. Same as
|
||||
% index(last).
|
||||
% $ =last= - IntExpr :
|
||||
% The IntExpr-th element before the last.
|
||||
% Same as index(last-IntExpr).
|
||||
%
|
||||
% Defined function argument values are:
|
||||
%
|
||||
% $ =self= :
|
||||
% Evaluate to the entire element
|
||||
% $ =content= :
|
||||
% Evaluate to the content of the element (a list)
|
||||
% $ =text= :
|
||||
% Evaluates to all text from the sub-tree, represented
|
||||
% as a list of characters.
|
||||
% $ `text(atom)` :
|
||||
% Evaluates to all text from the sub-tree as an atom.
|
||||
% $ =normalize_space= :
|
||||
% As =text=, but uses normalize_space/2 to normalise
|
||||
% white-space in the output
|
||||
% $ =number= :
|
||||
% Extract an integer or float from the value. Ignores
|
||||
% leading and trailing white-space
|
||||
% $ =|@|=Attribute :
|
||||
% Evaluates to the value of the given attribute. Attribute
|
||||
% can be a compound term. In this case the functor name
|
||||
% denotes the element and arguments perform transformations
|
||||
% on the attribute value. Defined transformations are:
|
||||
%
|
||||
% - number
|
||||
% Translate the value into a number using
|
||||
% xsd_number_chars/2.
|
||||
% - integer
|
||||
% As `number`, but subsequently transform the value
|
||||
% into an integer using the round/1 function.
|
||||
% - float
|
||||
% As `number`, but subsequently transform the value
|
||||
% into a float using the float/1 function.
|
||||
% - lower
|
||||
% Translate the value to lower case, preserving
|
||||
% the type.
|
||||
% - upper
|
||||
% Translate the value to upper case, preserving
|
||||
% the type.
|
||||
%
|
||||
% In addition, the argument-list can be _conditions_:
|
||||
%
|
||||
% $ Left = Right :
|
||||
% Succeeds if the left-hand unifies with the right-hand.
|
||||
% If the left-hand side is a function, this is evaluated.
|
||||
% The right-hand side is _never_ evaluated, and thus the
|
||||
% condition `content = content` defines that the content
|
||||
% of the element is the atom `content`.
|
||||
% The functions `lower_case` and `upper_case` can be applied
|
||||
% to Right (see example below).
|
||||
% $ contains(Haystack, Needle) :
|
||||
% Succeeds if Needle is a sub-list of Haystack.
|
||||
% $ XPath :
|
||||
% Succeeds if XPath matches in the currently selected
|
||||
% sub-DOM. For example, the following expression finds
|
||||
% an =h3= element inside a =div= element, where the =div=
|
||||
% element itself contains an =h2= child with a =strong=
|
||||
% child.
|
||||
%
|
||||
% ==
|
||||
% //div(h2/strong)/h3
|
||||
% ==
|
||||
%
|
||||
% This is equivalent to the conjunction of XPath goals below.
|
||||
%
|
||||
% ==
|
||||
% ...,
|
||||
% xpath(DOM, //(div), Div),
|
||||
% xpath(Div, h2/strong, _),
|
||||
% xpath(Div, h3, Result)
|
||||
% ==
|
||||
%
|
||||
% **Examples**:
|
||||
%
|
||||
% Match each table-row in DOM:
|
||||
%
|
||||
% ==
|
||||
% xpath(DOM, //tr, TR)
|
||||
% ==
|
||||
%
|
||||
% Match the last cell of each tablerow in DOM. This example
|
||||
% illustrates that a result can be the input of subsequent xpath/3
|
||||
% queries. Using multiple queries on the intermediate TR term
|
||||
% guarantee that all results come from the same table-row:
|
||||
%
|
||||
% ==
|
||||
% xpath(DOM, //tr, TR),
|
||||
% xpath(TR, /td(last), TD)
|
||||
% ==
|
||||
%
|
||||
% Match each =href= attribute in an <a> element
|
||||
%
|
||||
% ==
|
||||
% xpath(DOM, //a(@href), HREF)
|
||||
% ==
|
||||
%
|
||||
% Suppose we have a table containing rows where each first column
|
||||
% is the name of a product with a link to details and the second
|
||||
% is the price (a number). The following predicate matches the
|
||||
% name, URL and price:
|
||||
%
|
||||
% ==
|
||||
% product(DOM, Name, URL, Price) :-
|
||||
% xpath(DOM, //tr, TR),
|
||||
% xpath(TR, td(1), C1),
|
||||
% xpath(C1, /self(normalize_space), Name),
|
||||
% xpath(C1, a(@href), URL),
|
||||
% xpath(TR, td(2, number), Price).
|
||||
% ==
|
||||
%
|
||||
% Suppose we want to select books with genre="thriller" from a
|
||||
% tree containing elements =|<book genre=...>|=
|
||||
%
|
||||
% ==
|
||||
% thriller(DOM, Book) :-
|
||||
% xpath(DOM, //book(@genre=thiller), Book).
|
||||
% ==
|
||||
%
|
||||
% Match the elements =|<table align="center">|= _and_ =|<table
|
||||
% align="CENTER">|=:
|
||||
%
|
||||
% ```prolog
|
||||
% //table(@align(lower) = center)
|
||||
% ```
|
||||
%
|
||||
% Get the `width` and `height` of a `div` element as a number,
|
||||
% and the `div` node itself:
|
||||
%
|
||||
% ==
|
||||
% xpath(DOM, //div(@width(number)=W, @height(number)=H), Div)
|
||||
% ==
|
||||
%
|
||||
% Note that `div` is an infix operator, so parentheses must be
|
||||
% used in cases like the following:
|
||||
%
|
||||
% ==
|
||||
% xpath(DOM, //(div), Div)
|
||||
% ==
|
||||
|
||||
xpath(DOM, Spec, Content) :-
|
||||
in_dom(Spec, DOM, Content).
|
||||
|
||||
in_dom(//Spec, DOM, Value) :-
|
||||
!,
|
||||
element_spec(Spec, Name, Modifiers),
|
||||
sub_dom(I, Len, Name, E, DOM),
|
||||
modifiers(Modifiers, I, Len, E, Value).
|
||||
in_dom(/Spec, E, Value) :-
|
||||
!,
|
||||
element_spec(Spec, Name, Modifiers),
|
||||
( Name == self
|
||||
-> true
|
||||
; element_name(E, Name)
|
||||
),
|
||||
modifiers(Modifiers, 1, 1, E, Value).
|
||||
in_dom(A/B, DOM, Value) :-
|
||||
!,
|
||||
in_dom(A, DOM, Value0),
|
||||
in_dom(B, Value0, Value).
|
||||
in_dom(A//B, DOM, Value) :-
|
||||
!,
|
||||
in_dom(A, DOM, Value0),
|
||||
in_dom(//B, Value0, Value).
|
||||
in_dom(Spec, element(_, _, Content), Value) :-
|
||||
element_spec(Spec, Name, Modifiers),
|
||||
count_named_elements(Content, Name, CLen),
|
||||
CLen > 0,
|
||||
nth_element(N, Name, E, Content),
|
||||
modifiers(Modifiers, N, CLen, E, Value).
|
||||
|
||||
element_spec(Var, _, _) :-
|
||||
var(Var),
|
||||
!,
|
||||
instantiation_error(Var).
|
||||
element_spec(NS:Term, NS:Name, Modifiers) :-
|
||||
!,
|
||||
callable_name_arguments(Term, Name0, Modifiers),
|
||||
star(Name0, Name).
|
||||
element_spec(Term, Name, Modifiers) :-
|
||||
!,
|
||||
callable_name_arguments(Term, Name0, Modifiers),
|
||||
star(Name0, Name).
|
||||
|
||||
callable_name_arguments(Atom, Name, Arguments) :-
|
||||
atom(Atom),
|
||||
!,
|
||||
Name = Atom, Arguments = [].
|
||||
callable_name_arguments(Compound, Name, Arguments) :-
|
||||
Compound =.. [Name|Arguments].
|
||||
|
||||
|
||||
star(*, _) :- !.
|
||||
star(Name, Name).
|
||||
|
||||
|
||||
%! sub_dom(-Index, -Count, +Name, -Sub, +DOM) is nondet.
|
||||
%
|
||||
% Sub is a node in DOM with Name.
|
||||
%
|
||||
% @param Count is the total number of nodes in the content
|
||||
% list Sub appears that have the same name.
|
||||
% @param Index is the 1-based index of Sub of nodes with
|
||||
% Name.
|
||||
|
||||
sub_dom(1, 1, Name, DOM, DOM) :-
|
||||
element_name(DOM, Name0),
|
||||
\+ Name \= Name0.
|
||||
sub_dom(N, Len, Name, E, element(_,_,Content)) :-
|
||||
!,
|
||||
sub_dom_2(N, Len, Name, E, Content).
|
||||
sub_dom(N, Len, Name, E, Content) :-
|
||||
list_si(Content),
|
||||
sub_dom_2(N, Len, Name, E, Content).
|
||||
|
||||
sub_dom_2(N, Len, Name, Element, Content) :-
|
||||
( count_named_elements(Content, Name, Len),
|
||||
nth_element(N, Name, Element, Content)
|
||||
; member(element(_,_,C2), Content),
|
||||
sub_dom_2(N, Len, Name, Element, C2)
|
||||
).
|
||||
|
||||
|
||||
%! count_named_elements(+Content, +Name, -Count) is det.
|
||||
%
|
||||
% Count is the number of nodes with Name in Content.
|
||||
|
||||
count_named_elements(Content, Name, Count) :-
|
||||
count_named_elements(Content, Name, 0, Count).
|
||||
|
||||
count_named_elements([], _, Count, Count).
|
||||
count_named_elements([element(Name,_,_)|T], Name0, C0, C) :-
|
||||
\+ Name \= Name0,
|
||||
!,
|
||||
C1 is C0+1,
|
||||
count_named_elements(T, Name0, C1, C).
|
||||
count_named_elements([_|T], Name, C0, C) :-
|
||||
count_named_elements(T, Name, C0, C).
|
||||
|
||||
|
||||
%! nth_element(?N, +Name, -Element, +Content:list) is nondet.
|
||||
%
|
||||
% True if Element is the N-th element with name in Content.
|
||||
|
||||
nth_element(N, Name, Element, Content) :-
|
||||
nth_element_(1, N, Name, Element, Content).
|
||||
|
||||
nth_element_(I, N, Name, E, [H|T]) :-
|
||||
element_name(H, Name0),
|
||||
\+ Name \= Name0,
|
||||
!,
|
||||
( N = I,
|
||||
E = H
|
||||
; I2 is I + 1,
|
||||
( nonvar(N), I2 > N
|
||||
-> !, fail
|
||||
; true
|
||||
),
|
||||
nth_element_(I2, N, Name, E, T)
|
||||
).
|
||||
nth_element_(I, N, Name, E, [_|T]) :-
|
||||
nth_element_(I, N, Name, E, T).
|
||||
|
||||
|
||||
%! modifiers(+Modifiers, +I, +Clen, +DOM, -Value)
|
||||
%
|
||||
%
|
||||
|
||||
modifiers([], _, _, Value, Value).
|
||||
modifiers([H|T], I, L, Value0, Value) :-
|
||||
modifier(H, I, L, Value0, Value1),
|
||||
modifiers(T, I, L, Value1, Value).
|
||||
|
||||
modifier(M, _, _, _, _) :-
|
||||
var(M),
|
||||
!,
|
||||
instantiation_error(M).
|
||||
modifier(Index, I, L, Value0, Value) :-
|
||||
implicit_index_modifier(Index),
|
||||
!,
|
||||
Value = Value0,
|
||||
index_modifier(Index, I, L).
|
||||
modifier(index(Index), I, L, Value, Value) :-
|
||||
!,
|
||||
index_modifier(Index, I, L).
|
||||
modifier(Function, _, _, In, Out) :-
|
||||
xpath_function(Function),
|
||||
!,
|
||||
xpath_function(Function, In, Out).
|
||||
modifier(Function, _, _, In, Out) :-
|
||||
xpath_condition(Function, In),
|
||||
Out = In.
|
||||
|
||||
implicit_index_modifier(I) :-
|
||||
integer(I),
|
||||
!.
|
||||
implicit_index_modifier(last).
|
||||
implicit_index_modifier(last-_Expr).
|
||||
|
||||
index_modifier(Var, I, _L) :-
|
||||
var(Var),
|
||||
!,
|
||||
Var = I.
|
||||
index_modifier(last, I, L) :-
|
||||
!,
|
||||
I =:= L.
|
||||
index_modifier(last-Expr, I, L) :-
|
||||
!,
|
||||
I =:= L-Expr.
|
||||
index_modifier(N, I, _) :-
|
||||
N =:= I.
|
||||
|
||||
xpath_function(self, DOM, DOM). % self
|
||||
xpath_function(content, Element, Value) :- % content
|
||||
element_content(Element, Value).
|
||||
xpath_function(text, DOM, Text) :- % text
|
||||
text_of_dom(DOM, chars, Text).
|
||||
xpath_function(text(As), DOM, Text) :- % text(atom)
|
||||
text_of_dom(DOM, As, Text).
|
||||
xpath_function(normalize_space, DOM, Text) :- % normalize_space
|
||||
text_of_dom(DOM, chars, Text0),
|
||||
normalize_space(Text0, Text).
|
||||
xpath_function(number, DOM, Number) :- % number
|
||||
text_of_dom(DOM, chars, Text0),
|
||||
normalize_space(Text0, Text),
|
||||
catch(xsd_number_chars(Number, Text), _, fail).
|
||||
xpath_function(@Name, element(_, Attrs, _), Value) :- % @Name
|
||||
( atom(Name)
|
||||
-> memberchk(Name=Value, Attrs)
|
||||
; compound(Name)
|
||||
-> Name =.. [AName|AOps],
|
||||
memberchk(AName=Value0, Attrs),
|
||||
translate_attribute(AOps, Value0, Value)
|
||||
; member(Name=Value, Attrs)
|
||||
).
|
||||
xpath_function(quote(Value), _, Value). % quote(Value)
|
||||
|
||||
xpath_function(self).
|
||||
xpath_function(content).
|
||||
xpath_function(text).
|
||||
xpath_function(text(_)).
|
||||
xpath_function(normalize_space).
|
||||
xpath_function(number).
|
||||
xpath_function(@_).
|
||||
xpath_function(quote(_)).
|
||||
|
||||
translate_attribute([], Value, Value).
|
||||
translate_attribute([H|T], Value0, Value) :-
|
||||
translate_attr(H, Value0, Value1),
|
||||
translate_attribute(T, Value1, Value).
|
||||
|
||||
translate_attr(number, Value0, Value) :-
|
||||
xsd_number_chars(Value, Value0).
|
||||
translate_attr(integer, Value0, Value) :-
|
||||
xsd_number_chars(Value1, Value0),
|
||||
Value is round(Value1).
|
||||
translate_attr(float, Value0, Value) :-
|
||||
xsd_number_chars(Value1, Value0),
|
||||
Value is float(Value1).
|
||||
% The implementation of these translations is left for later.
|
||||
% translate_attr(lower, Value0, Value) :- ...
|
||||
% translate_attr(upper, Value0, Value) :- ...
|
||||
|
||||
xpath_condition(Left = Right, Value) :- % =
|
||||
!,
|
||||
var_or_function(Left, Value, LeftValue),
|
||||
process_equality(LeftValue, Right).
|
||||
xpath_condition(contains(Haystack, Needle), Value) :- % contains(Haystack, Needle)
|
||||
!,
|
||||
val_or_function(Haystack, Value, HaystackValue),
|
||||
val_or_function(Needle, Value, NeedleValue),
|
||||
( phrase((list(_),list(NeedleValue),list(_)), HaystackValue)
|
||||
-> true
|
||||
).
|
||||
xpath_condition(Spec, Dom) :-
|
||||
in_dom(Spec, Dom, _).
|
||||
|
||||
|
||||
%! process_equality(+Left, +Right) is semidet.
|
||||
%
|
||||
% Provides (very) partial support for XSLT functions that can be
|
||||
% applied according to the XPath 2 specification.
|
||||
%
|
||||
% For example the XPath expression in [1], and the equivalent
|
||||
% Prolog expression in [2], would both match the HTML element in
|
||||
% [3].
|
||||
%
|
||||
% ==
|
||||
% [1] //table[align=lower-case(center)]
|
||||
% [2] //table(@align=lower_case(center))
|
||||
% [3] <table align="CENTER">
|
||||
% ==
|
||||
|
||||
process_equality(Left, Right) :-
|
||||
var(Right),
|
||||
!,
|
||||
Left = Right.
|
||||
process_equality(Left, lower_case(Right)) :-
|
||||
!,
|
||||
downcase_atom(Left, Right).
|
||||
process_equality(Left, upper_case(Right)) :-
|
||||
!,
|
||||
upcase_atom(Left, Right).
|
||||
process_equality(Left, Right) :-
|
||||
Left = Right.
|
||||
|
||||
|
||||
var_or_function(Arg, _, Arg) :-
|
||||
var(Arg),
|
||||
!.
|
||||
var_or_function(Func, Value0, Value) :-
|
||||
xpath_function(Func),
|
||||
!,
|
||||
xpath_function(Func, Value0, Value).
|
||||
var_or_function(Value, _, Value).
|
||||
|
||||
val_or_function(Arg, _, Arg) :-
|
||||
var(Arg),
|
||||
!,
|
||||
instantiation_error(Arg).
|
||||
val_or_function(Func, Value0, Value) :- % TBD
|
||||
xpath_function(Func, Value0, Value),
|
||||
!.
|
||||
val_or_function(Value, _, Value).
|
||||
|
||||
|
||||
%! text_of_dom(+DOM, +As, -Text:(chars | atom)) is det.
|
||||
%
|
||||
% Text is the joined textual content of DOM.
|
||||
|
||||
text_of_dom(DOM, As, Text) :-
|
||||
phrase(text_of(DOM), Text0),
|
||||
( As == chars ->
|
||||
Text = Text0
|
||||
; As == atom ->
|
||||
atom_chars(Text, Text0)
|
||||
; domain_error(As, atom_or_chars, xpath)
|
||||
).
|
||||
|
||||
text_of(element(_,_,Content)) -->
|
||||
text_of_list(Content).
|
||||
text_of([]) -->
|
||||
[].
|
||||
text_of([H|T]) -->
|
||||
text_of(H),
|
||||
text_of(T).
|
||||
|
||||
|
||||
text_of_list([]) -->
|
||||
[].
|
||||
text_of_list([H|T]) -->
|
||||
text_of_1(H),
|
||||
text_of_list(T).
|
||||
|
||||
|
||||
text_of_1(element(_,_,Content)) -->
|
||||
text_of_list(Content).
|
||||
text_of_1([C|Cs]) --> list([C|Cs]).
|
||||
|
||||
list([]) --> [].
|
||||
list([L|Ls]) --> [L], list(Ls).
|
||||
|
||||
% For now, we use number_chars/2 to parse XML numbers.
|
||||
% If the need arises, we can extend this to additional
|
||||
% float constants and syntax that may occur in XML files.
|
||||
|
||||
xsd_number_chars(Number, Chars) :-
|
||||
number_chars(Number, Chars).
|
||||
|
||||
normalize_space(Text0, Text) :-
|
||||
Text0 = Text. % no conversion for the moment.
|
||||
@@ -2,14 +2,14 @@ use crate::divrem::*;
|
||||
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::arithmetic::*;
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::ordered_float::*;
|
||||
use crate::prolog::rug::{Integer, Rational};
|
||||
use crate::arithmetic::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::ordered_float::*;
|
||||
use crate::rug::{Integer, Rational};
|
||||
|
||||
use std::cmp;
|
||||
use std::convert::TryFrom;
|
||||
@@ -143,12 +143,10 @@ impl MachineState {
|
||||
|
||||
pub(crate)
|
||||
fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
|
||||
let a = self[r].clone();
|
||||
|
||||
let caller = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let caller = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
let mut interms: Vec<Number> = Vec::with_capacity(64);
|
||||
|
||||
for addr in self.post_order_iter(a) {
|
||||
for addr in self.post_order_iter(self[r]) {
|
||||
match self.heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::NamedStr(2, ref name, _) => {
|
||||
let a2 = interms.pop().unwrap();
|
||||
@@ -159,7 +157,7 @@ impl MachineState {
|
||||
"-" => interms.push(try_numeric_result!(self, a1 - a2, caller)?),
|
||||
"*" => interms.push(try_numeric_result!(self, a1 * a2, caller)?),
|
||||
"/" => interms.push(self.div(a1, a2)?),
|
||||
"**" => interms.push(self.pow(a1, a2, "(is)")?),
|
||||
"**" => interms.push(self.pow(a1, a2, "is")?),
|
||||
"^" => interms.push(self.int_pow(a1, a2)?),
|
||||
"max" => interms.push(self.max(a1, a2)?),
|
||||
"min" => interms.push(self.min(a1, a2)?),
|
||||
@@ -191,7 +189,16 @@ impl MachineState {
|
||||
"atan2" => interms.push(Number::Float(OrderedFloat(self.atan2(a1, a2)?))),
|
||||
"gcd" => interms.push(self.gcd(a1, a2)?),
|
||||
_ => {
|
||||
return Err(self.error_form(MachineError::instantiation_error(), caller))
|
||||
let evaluable_stub = MachineError::functor_stub(name.clone(), 2);
|
||||
|
||||
return Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Evaluable,
|
||||
evaluable_stub,
|
||||
),
|
||||
caller,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +226,16 @@ impl MachineState {
|
||||
"\\" => interms.push(self.bitwise_complement(a1)?),
|
||||
"sign" => interms.push(self.sign(a1)),
|
||||
_ => {
|
||||
return Err(self.error_form(MachineError::instantiation_error(), caller));
|
||||
let evaluable_stub = MachineError::functor_stub(name.clone(), 1);
|
||||
|
||||
return Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Evaluable,
|
||||
evaluable_stub,
|
||||
),
|
||||
caller,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,12 +257,44 @@ impl MachineState {
|
||||
&HeapCellValue::Atom(ref name, _) if name.as_str() == "pi" => {
|
||||
interms.push(Number::Float(OrderedFloat(f64::consts::PI)))
|
||||
}
|
||||
_ => {
|
||||
&HeapCellValue::NamedStr(arity, ref name, _) => {
|
||||
let evaluable_stub = MachineError::functor_stub(name.clone(), arity);
|
||||
|
||||
return Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Evaluable,
|
||||
evaluable_stub,
|
||||
),
|
||||
caller,
|
||||
));
|
||||
}
|
||||
&HeapCellValue::Atom(ref name, _) => {
|
||||
let evaluable_stub = MachineError::functor_stub(name.clone(), 0);
|
||||
|
||||
return Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Evaluable,
|
||||
evaluable_stub,
|
||||
),
|
||||
caller,
|
||||
));
|
||||
}
|
||||
&HeapCellValue::Addr(addr) if addr.is_ref() => {
|
||||
return Err(self.error_form(
|
||||
MachineError::instantiation_error(),
|
||||
caller,
|
||||
));
|
||||
}
|
||||
val => {
|
||||
return Err(self.type_error(
|
||||
ValidType::Number,
|
||||
val.context_free_clone(),
|
||||
clause_name!("is"),
|
||||
2,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +425,7 @@ impl MachineState {
|
||||
|
||||
pub(crate)
|
||||
fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
|
||||
if n1.is_zero() && n2.is_zero() {
|
||||
Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub))
|
||||
@@ -392,13 +440,13 @@ impl MachineState {
|
||||
pub(crate)
|
||||
fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
if n1.is_zero() && n2.is_negative() {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||
}
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if n1 != 1 && n2 < -1 {
|
||||
if !(n1 == 1 || n1 == 0 || n1 == -1) && n2 < 0 {
|
||||
let n = Number::from(n1);
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
@@ -424,7 +472,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
if n1 != 1 && &*n2 < &-1 {
|
||||
if !(n1 == 1 || n1 == 0 || n1 == -1) && &*n2 < &0 {
|
||||
let n = Number::from(n1);
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
@@ -442,7 +490,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
if &*n1 != &1 && n2 < -1 {
|
||||
if !(&*n1 == &1 || &*n1 == &0 || &*n1 == &-1) && n2 < 0 {
|
||||
let n = Number::Integer(n1);
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
@@ -460,7 +508,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
if &*n1 != &1 && &*n2 < &-1 {
|
||||
if !(&*n1 == &1 || &*n1 == &0 || &*n1 == &-1) && &*n2 < &0 {
|
||||
let n = Number::Integer(n1);
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
@@ -487,7 +535,7 @@ impl MachineState {
|
||||
let f2 = self.float(n2)?;
|
||||
|
||||
if n1.is_negative() && f2 != f2.floor() {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
return Err(
|
||||
self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub)
|
||||
);
|
||||
@@ -571,34 +619,7 @@ impl MachineState {
|
||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||
}
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if let Ok(n2) = u32::try_from(n2) {
|
||||
if let Some(result) = n1.checked_pow(n2) {
|
||||
return Ok(Number::from(result));
|
||||
}
|
||||
}
|
||||
|
||||
let n1 = Integer::from(n1);
|
||||
let n2 = Integer::from(n2);
|
||||
|
||||
Ok(Number::from(binary_pow(n1, &n2)))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(binary_pow(n1, n2.as_ref())))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
let n2 = Integer::from(n2);
|
||||
Ok(Number::from(binary_pow(n1.as_ref().clone(), &n2)))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(binary_pow(n1.as_ref().clone(), &*n2)))
|
||||
}
|
||||
(n1, n2) => {
|
||||
self.float_pow(n1, n2)
|
||||
}
|
||||
}
|
||||
self.float_pow(n1, n2)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -607,7 +628,7 @@ impl MachineState {
|
||||
where
|
||||
FloatFn: Fn(f64) -> f64,
|
||||
{
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
|
||||
let f1 = try_numeric_result!(self, result_f(&n1, rnd_f), stub)?;
|
||||
let f1 = result_f(&Number::Float(OrderedFloat(f(f1))), rnd_f);
|
||||
@@ -667,7 +688,7 @@ impl MachineState {
|
||||
pub(crate)
|
||||
fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
if n1.is_negative() {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||
}
|
||||
|
||||
@@ -677,7 +698,7 @@ impl MachineState {
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn float(&self, n: Number) -> Result<f64, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
try_numeric_result!(self, result_f(&n, rnd_f), stub)
|
||||
}
|
||||
|
||||
@@ -705,7 +726,7 @@ impl MachineState {
|
||||
|
||||
pub(crate)
|
||||
fn round(&self, n: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
|
||||
let result = n + Number::Float(OrderedFloat(0.5f64));
|
||||
let result = try_numeric_result!(self, result, stub)?;
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::prolog::heap_iter::*;
|
||||
use crate::prolog::machine::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::*;
|
||||
|
||||
use crate::indexmap::IndexSet;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::codegen::*;
|
||||
use crate::prolog::debray_allocator::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::machine::compile::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::codegen::*;
|
||||
use crate::debray_allocator::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::compile::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use crate::indexmap::IndexSet;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::mem;
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::instructions::*;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::parser::get_desc;
|
||||
use prolog_parser::tabled_rc::TabledData;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::parser::get_desc;
|
||||
use crate::prolog_parser::tabled_rc::TabledData;
|
||||
|
||||
use crate::prolog::codegen::*;
|
||||
use crate::prolog::debray_allocator::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::iterators::*;
|
||||
use crate::prolog::machine::code_walker::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::term_expansion::ExpansionAdditionResult;
|
||||
use crate::prolog::machine::toplevel::*;
|
||||
use crate::prolog::machine::*;
|
||||
use crate::codegen::*;
|
||||
use crate::debray_allocator::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::code_walker::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::term_expansion::ExpansionAdditionResult;
|
||||
use crate::machine::toplevel::*;
|
||||
use crate::machine::*;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -469,6 +469,7 @@ impl ClauseCodeGenerator {
|
||||
vec![Box::new(head.clone()), Box::new(tail.clone())],
|
||||
None,
|
||||
);
|
||||
|
||||
PredicateClause::Fact(clause, 0, 0)
|
||||
})
|
||||
.collect(),
|
||||
@@ -601,12 +602,7 @@ fn load_library(
|
||||
) -> Result<ClauseName, SessionError> {
|
||||
match LIBRARIES.borrow().get(name.as_str()) {
|
||||
Some(code) => {
|
||||
let mut lib_path = current_dir();
|
||||
|
||||
lib_path.pop();
|
||||
lib_path.push("lib");
|
||||
|
||||
let listing_src = ListingSource::from_file_and_path(name, lib_path);
|
||||
let listing_src = ListingSource::User;
|
||||
|
||||
load_module(
|
||||
wam,
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::stack::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::stack::*;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::IndexMut;
|
||||
@@ -104,7 +104,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
||||
if let &HeapCellValue::Addr(Addr::PStrLocation(h, _)) = &self.target[addr] {
|
||||
if h >= self.old_h {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, 0));
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, n));
|
||||
self.scan += 1;
|
||||
|
||||
return;
|
||||
@@ -114,14 +114,14 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
let threshold = self.target.threshold();
|
||||
|
||||
*self.value_at_scan() =
|
||||
HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
||||
HeapCellValue::Addr(Addr::PStrLocation(threshold, n));
|
||||
|
||||
self.scan += 1;
|
||||
|
||||
let (pstr, has_tail) =
|
||||
match &self.target[addr] {
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
(pstr.clone_from_offset(n), has_tail)
|
||||
(pstr.clone_from_offset(0), has_tail)
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -130,7 +130,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
|
||||
self.target.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
let replacement = HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
||||
let replacement = HeapCellValue::Addr(Addr::PStrLocation(threshold, n));
|
||||
|
||||
let trail_item = mem::replace(
|
||||
&mut self.target[addr],
|
||||
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::heap_print::*;
|
||||
use crate::prolog::machine::*;
|
||||
use crate::prolog::machine::compile::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::heap_print::*;
|
||||
use crate::machine::*;
|
||||
use crate::machine::compile::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::streams::*;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
@@ -66,6 +66,9 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
}
|
||||
Addr::Fixnum(arity) => {
|
||||
usize::try_from(arity).unwrap()
|
||||
}
|
||||
Addr::Usize(n) => {
|
||||
n
|
||||
}
|
||||
@@ -98,6 +101,18 @@ impl Machine {
|
||||
}
|
||||
|
||||
fn make_undefined(&mut self, name: ClauseName, arity: usize) {
|
||||
let module_name = name.owning_module();
|
||||
|
||||
match self.indices.modules.get(&module_name) {
|
||||
Some(ref module) => {
|
||||
if let Some(idx) = module.code_dir.get(&(name.clone(), arity)) {
|
||||
set_code_index!(idx, IndexPtr::DynamicUndefined, module_name);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(idx) = self.indices.code_dir.get(&(name, arity)) {
|
||||
set_code_index!(idx, IndexPtr::DynamicUndefined, clause_name!("user"));
|
||||
}
|
||||
@@ -258,7 +273,12 @@ impl Machine {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
Addr::Fixnum(arity) => {
|
||||
usize::try_from(arity).unwrap()
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
let (mut name, arity) = self.get_predicate_key(temp_v!(1), temp_v!(2));
|
||||
@@ -2,9 +2,9 @@ use core::marker::PhantomData;
|
||||
|
||||
use crate::prolog_parser::ast::Constant;
|
||||
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::partial_string::*;
|
||||
use crate::prolog::machine::raw_block::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::machine::raw_block::*;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::forms::{ModuleSource, Number, PredicateKey};
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::rug::Integer;
|
||||
use crate::forms::{ModuleSource, Number, PredicateKey};
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -43,6 +43,21 @@ impl TypeError for Addr {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for HeapCellValue {
|
||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), value(self)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for MachineStub {
|
||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
@@ -502,7 +517,7 @@ pub enum ValidType {
|
||||
InCharacter,
|
||||
Integer,
|
||||
List,
|
||||
// Number,
|
||||
Number,
|
||||
Pair,
|
||||
// PredicateIndicator,
|
||||
// Variable
|
||||
@@ -525,7 +540,7 @@ impl ValidType {
|
||||
ValidType::InCharacter => "in_character",
|
||||
ValidType::Integer => "integer",
|
||||
ValidType::List => "list",
|
||||
// ValidType::Number => "number",
|
||||
ValidType::Number => "number",
|
||||
ValidType::Pair => "pair",
|
||||
// ValidType::PredicateIndicator => "predicate_indicator",
|
||||
// ValidType::Variable => "variable"
|
||||
@@ -560,7 +575,7 @@ impl DomainErrorType {
|
||||
// from 7.12.2 f) of 13211-1:1995
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum RepFlag {
|
||||
// Character,
|
||||
Character,
|
||||
CharacterCode,
|
||||
InCharacterCode,
|
||||
MaxArity,
|
||||
@@ -571,7 +586,7 @@ pub enum RepFlag {
|
||||
impl RepFlag {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
// RepFlag::Character => "character",
|
||||
RepFlag::Character => "character",
|
||||
RepFlag::CharacterCode => "character_code",
|
||||
RepFlag::InCharacterCode => "in_character_code",
|
||||
RepFlag::MaxArity => "max_arity",
|
||||
@@ -825,5 +840,4 @@ impl From<ParserError> for EvalSession {
|
||||
fn from(err: ParserError) -> Self {
|
||||
EvalSession::from(SessionError::ParserError(err))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::fixtures::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::code_repo::CodeRepo;
|
||||
use crate::prolog::machine::Ball;
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::machine::partial_string::*;
|
||||
use crate::prolog::machine::raw_block::RawBlockTraits;
|
||||
use crate::prolog::machine::streams::Stream;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::ordered_float::OrderedFloat;
|
||||
use crate::prolog::rug::{Integer, Rational};
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::code_repo::CodeRepo;
|
||||
use crate::machine::Ball;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::machine::raw_block::RawBlockTraits;
|
||||
use crate::machine::streams::Stream;
|
||||
use crate::instructions::*;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::rug::{Integer, Rational};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
@@ -118,7 +118,7 @@ impl PartialEq<Ref> for Addr {
|
||||
}
|
||||
}
|
||||
|
||||
// for use in MachineState::bind.
|
||||
// for use crate::in MachineState::bind.
|
||||
impl PartialOrd<Ref> for Addr {
|
||||
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
||||
match self {
|
||||
@@ -272,19 +272,6 @@ impl Addr {
|
||||
&Addr::Float(f) => {
|
||||
Some(Constant::Float(f))
|
||||
}
|
||||
&Addr::PStrLocation(h, n) => {
|
||||
let mut heap_pstr_iter =
|
||||
machine_st.heap_pstr_iter(Addr::PStrLocation(h, n));
|
||||
|
||||
let buf = heap_pstr_iter.to_string();
|
||||
let end_addr = heap_pstr_iter.focus();
|
||||
|
||||
if end_addr == Addr::EmptyList {
|
||||
Some(Constant::String(Rc::new(buf)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
&Addr::Usize(n) => {
|
||||
Some(Constant::Usize(n))
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::heap_print::*;
|
||||
use crate::prolog::machine::attributed_variables::*;
|
||||
use crate::prolog::machine::copier::*;
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::modules::*;
|
||||
use crate::prolog::machine::stack::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::prolog::rug::Integer;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_print::*;
|
||||
use crate::machine::attributed_variables::*;
|
||||
use crate::machine::copier::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::modules::*;
|
||||
use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use downcast::Any;
|
||||
use crate::downcast::Any;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryFrom;
|
||||
@@ -636,11 +636,10 @@ impl MachineState {
|
||||
}
|
||||
|
||||
let mut orig_stream = stream.clone();
|
||||
let mut stream = self.open_parsing_stream(stream, "read_term", 3)?;
|
||||
|
||||
loop {
|
||||
match self.read(
|
||||
&mut stream,
|
||||
stream.clone(),
|
||||
indices.atom_tbl.clone(),
|
||||
&indices.op_dir,
|
||||
) {
|
||||
@@ -1337,14 +1336,8 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
}
|
||||
&BuiltInClauseType::Read => {
|
||||
let mut stream = machine_st.open_parsing_stream(
|
||||
current_input_stream.clone(),
|
||||
"read",
|
||||
1,
|
||||
)?;
|
||||
|
||||
match machine_st.read(
|
||||
&mut stream,
|
||||
current_input_stream.clone(),
|
||||
indices.atom_tbl.clone(),
|
||||
&indices.op_dir,
|
||||
) {
|
||||
@@ -1,24 +1,24 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::heap_iter::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::machine::INTERRUPT;
|
||||
use crate::prolog::machine::attributed_variables::*;
|
||||
use crate::prolog::machine::code_repo::CodeRepo;
|
||||
use crate::prolog::machine::copier::*;
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::machine::stack::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::prolog::ordered_float::*;
|
||||
use crate::prolog::rug::Integer;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::INTERRUPT;
|
||||
use crate::machine::attributed_variables::*;
|
||||
use crate::machine::code_repo::CodeRepo;
|
||||
use crate::machine::copier::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::ordered_float::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryFrom;
|
||||
@@ -689,7 +689,7 @@ impl MachineState {
|
||||
&mut HeapPtr::PStrChar(h, ref mut n) |
|
||||
&mut HeapPtr::PStrLocation(h, ref mut n) => {
|
||||
match &self.heap[h] {
|
||||
HeapCellValue::PartialString(ref pstr, _) => {
|
||||
&HeapCellValue::PartialString(ref pstr, _) => {
|
||||
for c in pstr.range_from(*n ..).take(rhs) {
|
||||
*n += c.len_utf8();
|
||||
}
|
||||
@@ -697,7 +697,6 @@ impl MachineState {
|
||||
self.s = HeapPtr::PStrLocation(h, *n);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -819,7 +818,7 @@ impl MachineState {
|
||||
|
||||
self.bind(addr.as_var().unwrap(), pstr_addr);
|
||||
}
|
||||
Addr::Lis(l) if !self.flags.double_quotes.is_atom() => {
|
||||
Addr::Lis(l) => {
|
||||
let h = self.heap.h();
|
||||
|
||||
let pstr_addr =
|
||||
@@ -921,7 +920,7 @@ impl MachineState {
|
||||
self.fail = true;
|
||||
}
|
||||
}
|
||||
Addr::Lis(l) if !self.flags.double_quotes.is_atom() => {
|
||||
Addr::Lis(l) => {
|
||||
let addr = self.heap.put_constant(c.clone());
|
||||
self.unify(Addr::Lis(l), addr);
|
||||
}
|
||||
@@ -953,7 +952,7 @@ impl MachineState {
|
||||
|
||||
pub(super)
|
||||
fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction) {
|
||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
|
||||
match instr {
|
||||
&ArithmeticInstruction::Add(ref a1, ref a2, t) => {
|
||||
@@ -1405,11 +1404,7 @@ impl MachineState {
|
||||
v
|
||||
}
|
||||
Addr::PStrLocation(..) => {
|
||||
if !self.flags.double_quotes.is_atom() {
|
||||
l
|
||||
} else {
|
||||
c
|
||||
}
|
||||
l
|
||||
}
|
||||
Addr::Char(_) | Addr::Con(_) | Addr::CutPoint(_) |
|
||||
Addr::EmptyList | Addr::Fixnum(_) | Addr::Float(_) | Addr::Usize(_) => {
|
||||
@@ -1885,11 +1880,10 @@ impl MachineState {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
(Addr::PStrLocation(..), Addr::Lis(_))
|
||||
| (Addr::Lis(_), Addr::PStrLocation(..))
|
||||
if !self.flags.double_quotes.is_atom() => {
|
||||
continue;
|
||||
}
|
||||
(Addr::PStrLocation(..), Addr::Lis(_)) |
|
||||
(Addr::Lis(_), Addr::PStrLocation(..)) => {
|
||||
continue;
|
||||
}
|
||||
(pstr1 @ Addr::PStrLocation(..), pstr2 @ Addr::PStrLocation(..)) => {
|
||||
let mut i1 = self.heap_pstr_iter(pstr1);
|
||||
let mut i2 = self.heap_pstr_iter(pstr2);
|
||||
@@ -2249,7 +2243,7 @@ impl MachineState {
|
||||
(
|
||||
Addr::PStrLocation(..),
|
||||
Addr::Lis(_),
|
||||
) if !self.flags.double_quotes.is_atom() => {
|
||||
) => {
|
||||
}
|
||||
(
|
||||
Addr::Lis(_),
|
||||
@@ -2278,7 +2272,7 @@ impl MachineState {
|
||||
(
|
||||
Addr::PStrLocation(..),
|
||||
Addr::Str(s),
|
||||
) if !self.flags.double_quotes.is_atom() => {
|
||||
) => {
|
||||
if let &HeapCellValue::NamedStr(a1, ref n1, _) = &self.heap[s] {
|
||||
if a1 != 2 || n1.as_str() != "." {
|
||||
return Some(a1.cmp(&2).then_with(|| n1.as_str().cmp(".")));
|
||||
@@ -2290,7 +2284,7 @@ impl MachineState {
|
||||
(
|
||||
Addr::Str(s),
|
||||
Addr::PStrLocation(..),
|
||||
) if !self.flags.double_quotes.is_atom() => {
|
||||
) => {
|
||||
if let &HeapCellValue::NamedStr(a1, ref n1, _) = &self.heap[s] {
|
||||
if a1 != 2 || n1.as_str() != "." {
|
||||
return Some(2.cmp(&a1).then_with(|| ".".cmp(n1.as_str())));
|
||||
@@ -2376,14 +2370,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
match d {
|
||||
Addr::Char(_) if self.flags.double_quotes.is_codes() => {
|
||||
self.p += 1;
|
||||
}
|
||||
_ => {
|
||||
self.fail = true;
|
||||
}
|
||||
}
|
||||
self.fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2474,22 +2461,29 @@ impl MachineState {
|
||||
fn try_functor_fabricate_struct(
|
||||
&mut self,
|
||||
name: ClauseName,
|
||||
arity: isize,
|
||||
arity: usize,
|
||||
spec: Option<SharedOpDesc>,
|
||||
op_dir: &OpDir,
|
||||
r: Ref,
|
||||
) {
|
||||
let spec = fetch_atom_op_spec(name.clone(), spec, op_dir);
|
||||
let spec = spec.and_then(|spec| {
|
||||
if spec.arity() != arity {
|
||||
fetch_op_spec(name.clone(), arity, op_dir)
|
||||
} else {
|
||||
Some(spec)
|
||||
}
|
||||
});
|
||||
|
||||
let f_a = if name.as_str() == "." && arity == 2 {
|
||||
Addr::Lis(self.heap.h())
|
||||
} else {
|
||||
self.heap.to_unifiable(HeapCellValue::NamedStr(arity as usize, name, spec))
|
||||
self.heap.to_unifiable(HeapCellValue::NamedStr(arity, name, spec))
|
||||
};
|
||||
|
||||
for _ in 0..arity {
|
||||
let h = self.heap.h();
|
||||
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
||||
let h = self.heap.h();
|
||||
|
||||
for i in 0 .. arity {
|
||||
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + i)));
|
||||
}
|
||||
|
||||
self.bind(r, f_a);
|
||||
@@ -2510,7 +2504,13 @@ impl MachineState {
|
||||
}
|
||||
Addr::Str(o) => match self.heap.clone(o) {
|
||||
HeapCellValue::NamedStr(arity, name, spec) => {
|
||||
let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir);
|
||||
let spec = fetch_op_spec_from_existing(
|
||||
name.clone(),
|
||||
arity,
|
||||
spec,
|
||||
&indices.op_dir,
|
||||
);
|
||||
|
||||
self.try_functor_compound_case(name, arity, spec)
|
||||
}
|
||||
_ => {
|
||||
@@ -2518,7 +2518,13 @@ impl MachineState {
|
||||
}
|
||||
},
|
||||
Addr::Lis(_) | Addr::PStrLocation(..) => {
|
||||
let spec = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
|
||||
let spec = fetch_op_spec_from_existing(
|
||||
clause_name!("."),
|
||||
2,
|
||||
None,
|
||||
&indices.op_dir,
|
||||
);
|
||||
|
||||
self.try_functor_compound_case(clause_name!("."), 2, spec)
|
||||
}
|
||||
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => {
|
||||
@@ -2589,7 +2595,7 @@ impl MachineState {
|
||||
if let HeapCellValue::Atom(name, spec) = self.heap.clone(h) {
|
||||
self.try_functor_fabricate_struct(
|
||||
name,
|
||||
arity,
|
||||
arity as usize,
|
||||
spec,
|
||||
&indices.op_dir,
|
||||
a1.as_var().unwrap(),
|
||||
@@ -2609,7 +2615,7 @@ impl MachineState {
|
||||
Addr::Char(c) => {
|
||||
self.try_functor_fabricate_struct(
|
||||
clause_name!(c.to_string(), indices.atom_tbl),
|
||||
arity,
|
||||
arity as usize,
|
||||
None,
|
||||
&indices.op_dir,
|
||||
a1.as_var().unwrap(),
|
||||
@@ -2889,7 +2895,7 @@ impl MachineState {
|
||||
| (
|
||||
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
||||
HeapCellValue::Addr(Addr::Lis(_)),
|
||||
) if !self.flags.double_quotes.is_atom() => {
|
||||
) => {
|
||||
}
|
||||
(
|
||||
HeapCellValue::NamedStr(ar1, n1, _),
|
||||
@@ -1,12 +1,12 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::clause_types::*;
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::heap_print::*;
|
||||
use crate::prolog::instructions::*;
|
||||
use crate::prolog::machine::heap::*;
|
||||
use crate::prolog::read::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_print::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::read::*;
|
||||
|
||||
mod attributed_variables;
|
||||
pub(super) mod code_repo;
|
||||
@@ -32,17 +32,17 @@ mod arithmetic_ops;
|
||||
mod machine_state_impl;
|
||||
mod system_calls;
|
||||
|
||||
use crate::prolog::machine::attributed_variables::*;
|
||||
use crate::prolog::machine::code_repo::*;
|
||||
use crate::prolog::machine::compile::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::machine::modules::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::prolog::machine::toplevel::*;
|
||||
use crate::machine::attributed_variables::*;
|
||||
use crate::machine::code_repo::*;
|
||||
use crate::machine::compile::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::modules::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::machine::toplevel::*;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
@@ -212,17 +212,6 @@ impl SubModuleUser for IndexStore {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn current_dir() -> std::path::PathBuf {
|
||||
let mut path_buf = std::path::PathBuf::from(PROJECT_DIR);
|
||||
|
||||
// file!() always produces a path relative to PROJECT_DIR.
|
||||
path_buf = path_buf.join(std::path::PathBuf::from(file!()));
|
||||
|
||||
path_buf.pop();
|
||||
path_buf
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/libraries.rs"));
|
||||
|
||||
static TOPLEVEL: &str = include_str!("../toplevel.pl");
|
||||
@@ -230,12 +219,7 @@ static TOPLEVEL: &str = include_str!("../toplevel.pl");
|
||||
impl Machine {
|
||||
fn compile_special_forms(&mut self)
|
||||
{
|
||||
let current_dir = current_dir();
|
||||
|
||||
let verify_attrs_src = ListingSource::from_file_and_path(
|
||||
clause_name!("attributed_variables.pl"),
|
||||
current_dir.clone(),
|
||||
);
|
||||
let verify_attrs_src = ListingSource::User;
|
||||
|
||||
match compile_special_form(
|
||||
self,
|
||||
@@ -250,10 +234,7 @@ impl Machine {
|
||||
panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
|
||||
}
|
||||
|
||||
let project_attrs_src = ListingSource::from_file_and_path(
|
||||
clause_name!("project_attributes.pl"),
|
||||
current_dir,
|
||||
);
|
||||
let project_attrs_src = ListingSource::User;
|
||||
|
||||
match compile_special_form(
|
||||
self,
|
||||
@@ -273,13 +254,7 @@ impl Machine {
|
||||
{
|
||||
self.toplevel_idx = self.code_repo.code.len();
|
||||
|
||||
let mut current_dir = current_dir();
|
||||
current_dir.pop();
|
||||
|
||||
let top_lvl_src = ListingSource::from_file_and_path(
|
||||
clause_name!("toplevel.pl"),
|
||||
current_dir,
|
||||
);
|
||||
let top_lvl_src = ListingSource::User;
|
||||
|
||||
compile_user_module(
|
||||
self,
|
||||
@@ -371,6 +346,8 @@ impl Machine {
|
||||
|
||||
pub fn new(current_input_stream: Stream, current_output_stream: Stream) -> Self
|
||||
{
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
|
||||
let mut wam = Machine {
|
||||
machine_st: MachineState::new(),
|
||||
inner_heap: Heap::new(),
|
||||
@@ -383,78 +360,59 @@ impl Machine {
|
||||
};
|
||||
|
||||
let atom_tbl = wam.indices.atom_tbl.clone();
|
||||
let mut lib_path = current_dir();
|
||||
|
||||
lib_path.pop();
|
||||
lib_path.push("lib");
|
||||
|
||||
wam.indices.add_term_and_goal_expansion_indices();
|
||||
|
||||
compile_listing(
|
||||
&mut wam,
|
||||
Stream::from(BUILTINS),
|
||||
Stream::from(LIBRARIES.borrow()["builtins"]),
|
||||
default_index_store!(atom_tbl.clone()),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("builtins.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
wam.compile_special_forms();
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(ERROR),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("error"),
|
||||
lib_path.clone(),
|
||||
)
|
||||
compile_user_module(
|
||||
&mut wam,
|
||||
Stream::from(LIBRARIES.borrow()["error"]),
|
||||
true,
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(PAIRS),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("pairs"),
|
||||
lib_path.clone(),
|
||||
)
|
||||
compile_user_module(
|
||||
&mut wam,
|
||||
Stream::from(LIBRARIES.borrow()["pairs"]),
|
||||
true,
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(LISTS),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("lists"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
compile_user_module(
|
||||
&mut wam,
|
||||
Stream::from(LIBRARIES.borrow()["lists"]),
|
||||
true,
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(ISO_EXT),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("iso_ext"),
|
||||
lib_path.clone(),
|
||||
)
|
||||
compile_user_module(
|
||||
&mut wam,
|
||||
Stream::from(LIBRARIES.borrow()["iso_ext"]),
|
||||
true,
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(SI),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("si"),
|
||||
lib_path.clone(),
|
||||
)
|
||||
compile_user_module(
|
||||
&mut wam,
|
||||
Stream::from(LIBRARIES.borrow()["si"]),
|
||||
true,
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(CHARSIO),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("si"),
|
||||
lib_path.clone(),
|
||||
)
|
||||
compile_user_module(
|
||||
&mut wam,
|
||||
Stream::from(LIBRARIES.borrow()["charsio"]),
|
||||
true,
|
||||
ListingSource::User,
|
||||
);
|
||||
|
||||
if wam.compile_top_level().is_err() {
|
||||
@@ -681,8 +639,15 @@ impl Machine {
|
||||
name.clone(),
|
||||
HeapCellValue::Addr(Addr::Char(c)) =>
|
||||
clause_name!(c.to_string(), self.indices.atom_tbl),
|
||||
_ =>
|
||||
unreachable!(),
|
||||
HeapCellValue::Addr(addr @ Addr::PStrLocation(..)) => {
|
||||
let mut heap_pstr_iter =
|
||||
self.machine_st.heap_pstr_iter(*addr);
|
||||
clause_name!(
|
||||
heap_pstr_iter.to_string(),
|
||||
self.indices.atom_tbl
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::machine::code_repo::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::code_repo::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::mem;
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::raw_block::*;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::raw_block::*;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::ptr;
|
||||
@@ -1,22 +1,26 @@
|
||||
use crate::prolog_parser::ast::*;
|
||||
|
||||
use crate::prolog::read::PrologStream;
|
||||
use crate::prolog::read::readline::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::read::PrologStream;
|
||||
use crate::read::readline::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::cmp::{min, Ordering};
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{stdout, Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::mem;
|
||||
use std::net::{Shutdown, TcpStream};
|
||||
use std::ops::DerefMut;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::native_tls::TlsStream;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum StreamType {
|
||||
Binary,
|
||||
@@ -90,17 +94,81 @@ impl EOFAction {
|
||||
}
|
||||
}
|
||||
|
||||
fn parser_top_to_bytes(mut buf: Vec<io::Result<char>>) -> io::Result<Vec<u8>> {
|
||||
let mut str_buf = String::new();
|
||||
|
||||
while let Some(c) = buf.pop() {
|
||||
str_buf.push(c?);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let array = str_buf.as_bytes_mut();
|
||||
array.reverse();
|
||||
Ok(Vec::from(array))
|
||||
}
|
||||
}
|
||||
|
||||
/* all these streams are closed automatically when the instance is
|
||||
* dropped. */
|
||||
pub enum StreamInstance {
|
||||
Bytes(Cursor<Vec<u8>>),
|
||||
DynReadSource(Box<dyn Read>),
|
||||
InputFile(ClauseName, File),
|
||||
OutputFile(ClauseName, File, bool), // File, append.
|
||||
Null,
|
||||
PausedPrologStream(Vec<u8>, Box<StreamInstance>),
|
||||
ReadlineStream(ReadlineStream),
|
||||
StaticStr(Cursor<&'static str>),
|
||||
Stdout,
|
||||
TcpStream(ClauseName, TcpStream),
|
||||
TlsStream(ClauseName, TlsStream<TcpStream>)
|
||||
}
|
||||
|
||||
impl StreamInstance {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
match self {
|
||||
StreamInstance::PausedPrologStream(ref mut put_back, ref mut stream) => {
|
||||
let mut index = 0;
|
||||
|
||||
while index < min(buf.len(), put_back.len()) {
|
||||
let b = put_back.pop().unwrap();
|
||||
buf[index] = b;
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if index == buf.len() {
|
||||
Ok(buf.len())
|
||||
} else {
|
||||
stream.read(&mut buf[index ..])
|
||||
}
|
||||
}
|
||||
StreamInstance::InputFile(_, ref mut file) => {
|
||||
file.read(buf)
|
||||
}
|
||||
StreamInstance::TcpStream(_, ref mut tcp_stream) => {
|
||||
tcp_stream.read(buf)
|
||||
}
|
||||
StreamInstance::TlsStream(_, ref mut tls_stream) => {
|
||||
tls_stream.read(buf)
|
||||
}
|
||||
StreamInstance::ReadlineStream(ref mut rl_stream) => {
|
||||
rl_stream.read(buf)
|
||||
}
|
||||
StreamInstance::StaticStr(ref mut src) => {
|
||||
src.read(buf)
|
||||
}
|
||||
StreamInstance::Bytes(ref mut cursor) => {
|
||||
cursor.read(buf)
|
||||
}
|
||||
StreamInstance::OutputFile(..) |
|
||||
StreamInstance::Stdout |
|
||||
StreamInstance::Null => {
|
||||
Err(std::io::Error::new(
|
||||
ErrorKind::PermissionDenied,
|
||||
StreamError::ReadFromOutputStream,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for StreamInstance {
|
||||
@@ -109,6 +177,9 @@ impl Drop for StreamInstance {
|
||||
StreamInstance::TcpStream(_, ref mut tcp_stream) => {
|
||||
discard_result!(tcp_stream.shutdown(Shutdown::Both));
|
||||
}
|
||||
StreamInstance::TlsStream(_, ref mut tls_stream) => {
|
||||
discard_result!(tls_stream.shutdown());
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
@@ -120,17 +191,24 @@ impl fmt::Debug for StreamInstance {
|
||||
match self {
|
||||
&StreamInstance::Bytes(ref bytes) =>
|
||||
write!(fmt, "Bytes({:?})", bytes),
|
||||
&StreamInstance::DynReadSource(_) =>
|
||||
write!(fmt, "DynReadSource(_)"), // Hacky solution.
|
||||
&StreamInstance::InputFile(_, ref file) => write!(fmt, "InputFile({:?})", file),
|
||||
&StreamInstance::OutputFile(_, ref file, _) => write!(fmt, "OutputFile({:?})", file),
|
||||
&StreamInstance::Null => write!(fmt, "Null"),
|
||||
&StreamInstance::StaticStr(_) =>
|
||||
write!(fmt, "StaticStr(_)"), // Hacky solution.
|
||||
&StreamInstance::InputFile(_, ref file) =>
|
||||
write!(fmt, "InputFile({:?})", file),
|
||||
&StreamInstance::OutputFile(_, ref file, _) =>
|
||||
write!(fmt, "OutputFile({:?})", file),
|
||||
&StreamInstance::Null =>
|
||||
write!(fmt, "Null"),
|
||||
&StreamInstance::PausedPrologStream(ref put_back, ref stream) =>
|
||||
write!(fmt, "PausedPrologStream({:?}, {:?})", put_back, stream),
|
||||
&StreamInstance::ReadlineStream(ref readline_stream) =>
|
||||
write!(fmt, "ReadlineStream({:?})", readline_stream),
|
||||
// &StreamInstance::Stdin => write!(fmt, "Stdin"),
|
||||
&StreamInstance::Stdout => write!(fmt, "Stdout"),
|
||||
&StreamInstance::Stdout =>
|
||||
write!(fmt, "Stdout"),
|
||||
&StreamInstance::TcpStream(_, ref tcp_stream) =>
|
||||
write!(fmt, "TcpStream({:?})", tcp_stream),
|
||||
&StreamInstance::TlsStream(_, ref tls_stream) =>
|
||||
write!(fmt, "TlsStream({:?})", tls_stream),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,7 +352,7 @@ impl From<ReadlineStream> for Stream {
|
||||
|
||||
impl From<&'static str> for Stream {
|
||||
fn from(src: &'static str) -> Stream {
|
||||
Stream::from_inst(StreamInstance::DynReadSource(Box::new(src.as_bytes())))
|
||||
Stream::from_inst(StreamInstance::StaticStr(Cursor::new(src)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,12 +483,14 @@ impl Stream {
|
||||
fn mode(&self) -> &'static str {
|
||||
match self.stream_inst.0.borrow().1 {
|
||||
StreamInstance::Bytes(_) |
|
||||
StreamInstance::PausedPrologStream(..) |
|
||||
StreamInstance::ReadlineStream(_) |
|
||||
StreamInstance::DynReadSource(_) |
|
||||
StreamInstance::StaticStr(_) |
|
||||
StreamInstance::InputFile(..) => {
|
||||
"read"
|
||||
}
|
||||
StreamInstance::TcpStream(..) => {
|
||||
StreamInstance::TcpStream(..) |
|
||||
StreamInstance::TlsStream(..) => {
|
||||
"read_append"
|
||||
}
|
||||
StreamInstance::OutputFile(_, _, true) => {
|
||||
@@ -449,6 +529,12 @@ impl Stream {
|
||||
Stream::from_inst(StreamInstance::TcpStream(address, tcp_stream))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn from_tls_stream(address: ClauseName, tls_stream: TlsStream<TcpStream>) -> Self {
|
||||
Stream::from_inst(StreamInstance::TlsStream(address, tls_stream))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn from_file_as_output(name: ClauseName, file: File, in_append_mode: bool) -> Self {
|
||||
@@ -478,7 +564,6 @@ impl Stream {
|
||||
pub(crate)
|
||||
fn is_stdin(&self) -> bool {
|
||||
match self.stream_inst.0.borrow().1 {
|
||||
//StreamInstance::Stdin |
|
||||
StreamInstance::ReadlineStream(_) => {
|
||||
true
|
||||
}
|
||||
@@ -508,11 +593,12 @@ impl Stream {
|
||||
pub(crate)
|
||||
fn is_input_stream(&self) -> bool {
|
||||
match self.stream_inst.0.borrow().1 {
|
||||
// StreamInstance::Stdin |
|
||||
StreamInstance::TcpStream(..) |
|
||||
StreamInstance::TlsStream(..) |
|
||||
StreamInstance::Bytes(_) |
|
||||
StreamInstance::PausedPrologStream(..) |
|
||||
StreamInstance::ReadlineStream(_) |
|
||||
StreamInstance::DynReadSource(_) |
|
||||
StreamInstance::StaticStr(_) |
|
||||
StreamInstance::InputFile(..) => {
|
||||
true
|
||||
}
|
||||
@@ -528,6 +614,7 @@ impl Stream {
|
||||
match self.stream_inst.0.borrow().1 {
|
||||
StreamInstance::Stdout
|
||||
| StreamInstance::TcpStream(..)
|
||||
| StreamInstance::TlsStream(..)
|
||||
| StreamInstance::Bytes(_)
|
||||
| StreamInstance::OutputFile(..) => {
|
||||
true
|
||||
@@ -538,27 +625,49 @@ impl Stream {
|
||||
}
|
||||
}
|
||||
|
||||
fn unpause_stream(&mut self) {
|
||||
let stream_inst =
|
||||
match self.stream_inst.0.borrow_mut().1 {
|
||||
StreamInstance::PausedPrologStream(ref put_back, ref mut stream_inst)
|
||||
if put_back.is_empty() => {
|
||||
mem::replace(&mut **stream_inst, StreamInstance::Null)
|
||||
}
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
self.stream_inst.0.borrow_mut().1 = stream_inst;
|
||||
}
|
||||
|
||||
// returns true on success.
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn reset(&mut self) -> bool {
|
||||
self.stream_inst.0.borrow_mut().0 = false;
|
||||
|
||||
match self.stream_inst.0.borrow_mut().1 {
|
||||
StreamInstance::Bytes(ref mut cursor) => {
|
||||
cursor.set_position(0);
|
||||
true
|
||||
}
|
||||
StreamInstance::InputFile(_, ref mut file) => {
|
||||
file.seek(SeekFrom::Start(0)).unwrap();
|
||||
true
|
||||
}
|
||||
StreamInstance::ReadlineStream(_) => {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
loop {
|
||||
match self.stream_inst.0.borrow_mut().1 {
|
||||
StreamInstance::Bytes(ref mut cursor) => {
|
||||
cursor.set_position(0);
|
||||
return true;
|
||||
}
|
||||
StreamInstance::InputFile(_, ref mut file) => {
|
||||
file.seek(SeekFrom::Start(0)).unwrap();
|
||||
return true;
|
||||
}
|
||||
StreamInstance::PausedPrologStream(ref mut put_back, _) => {
|
||||
put_back.clear();
|
||||
}
|
||||
StreamInstance::ReadlineStream(_) => {
|
||||
return true;
|
||||
}
|
||||
_ => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
self.unpause_stream();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,7 +728,7 @@ impl Stream {
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn peek_char(&mut self) -> std::io::Result<char> {
|
||||
use unicode_reader::CodePoints;
|
||||
use crate::unicode_reader::CodePoints;
|
||||
|
||||
match self.stream_inst.0.borrow_mut().1 {
|
||||
StreamInstance::InputFile(_, ref mut file) => {
|
||||
@@ -670,6 +779,34 @@ impl Stream {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn pause_stream(&mut self, buf: Vec<io::Result<char>>) -> io::Result<()> {
|
||||
match self.stream_inst.0.borrow_mut().1 {
|
||||
StreamInstance::PausedPrologStream(ref mut inner_buf, _) => {
|
||||
inner_buf.extend(parser_top_to_bytes(buf)?.into_iter());
|
||||
return Ok(());
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
|
||||
if !buf.is_empty() {
|
||||
let stream_inst = mem::replace(
|
||||
&mut self.stream_inst.0.borrow_mut().1,
|
||||
StreamInstance::Null,
|
||||
);
|
||||
|
||||
self.stream_inst.0.borrow_mut().1 =
|
||||
StreamInstance::PausedPrologStream(
|
||||
parser_top_to_bytes(buf)?,
|
||||
Box::new(stream_inst),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
@@ -866,7 +1003,7 @@ impl MachineState {
|
||||
stub_name: &'static str,
|
||||
stub_arity: usize,
|
||||
) -> Result<PrologStream, MachineStub> {
|
||||
match parsing_stream(stream.clone()) {
|
||||
match parsing_stream(stream) {
|
||||
Ok(parsing_stream) => {
|
||||
Ok(parsing_stream)
|
||||
}
|
||||
@@ -1028,35 +1165,11 @@ impl MachineState {
|
||||
}
|
||||
|
||||
impl Read for Stream {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
match self.stream_inst.0.borrow_mut().1 {
|
||||
StreamInstance::InputFile(_, ref mut file) => {
|
||||
file.read(buf)
|
||||
}
|
||||
StreamInstance::TcpStream(_, ref mut tcp_stream) => {
|
||||
tcp_stream.read(buf)
|
||||
}
|
||||
StreamInstance::ReadlineStream(ref mut rl_stream) => {
|
||||
rl_stream.read(buf)
|
||||
}
|
||||
StreamInstance::DynReadSource(ref mut src) => {
|
||||
src.read(buf)
|
||||
}
|
||||
StreamInstance::Bytes(ref mut cursor) => {
|
||||
cursor.read(buf)
|
||||
}
|
||||
/*
|
||||
StreamInstance::Stdin => {
|
||||
stdin().read(buf)
|
||||
}
|
||||
*/
|
||||
StreamInstance::OutputFile(..) | StreamInstance::Stdout | StreamInstance::Null => {
|
||||
Err(std::io::Error::new(
|
||||
ErrorKind::PermissionDenied,
|
||||
StreamError::ReadFromOutputStream,
|
||||
))
|
||||
}
|
||||
}
|
||||
let bytes_read = self.stream_inst.0.borrow_mut().1.read(buf)?;
|
||||
self.unpause_stream();
|
||||
Ok(bytes_read)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,14 +1182,20 @@ impl Write for Stream {
|
||||
StreamInstance::TcpStream(_, ref mut tcp_stream) => {
|
||||
tcp_stream.write(buf)
|
||||
}
|
||||
StreamInstance::TlsStream(_, ref mut tls_stream) => {
|
||||
tls_stream.write(buf)
|
||||
}
|
||||
StreamInstance::Bytes(ref mut cursor) => {
|
||||
cursor.write(buf)
|
||||
}
|
||||
StreamInstance::Stdout => {
|
||||
stdout().write(buf)
|
||||
}
|
||||
StreamInstance::DynReadSource(_) | StreamInstance::ReadlineStream(_) |
|
||||
StreamInstance::InputFile(..) | StreamInstance::Null => {
|
||||
StreamInstance::PausedPrologStream(..) |
|
||||
StreamInstance::StaticStr(_) |
|
||||
StreamInstance::ReadlineStream(_) |
|
||||
StreamInstance::InputFile(..) |
|
||||
StreamInstance::Null => {
|
||||
Err(std::io::Error::new(
|
||||
ErrorKind::PermissionDenied,
|
||||
StreamError::WriteToInputStream,
|
||||
@@ -1093,14 +1212,20 @@ impl Write for Stream {
|
||||
StreamInstance::TcpStream(_, ref mut tcp_stream) => {
|
||||
tcp_stream.flush()
|
||||
}
|
||||
StreamInstance::TlsStream(_, ref mut tls_stream) => {
|
||||
tls_stream.flush()
|
||||
}
|
||||
StreamInstance::Bytes(ref mut cursor) => {
|
||||
cursor.flush()
|
||||
}
|
||||
StreamInstance::Stdout => {
|
||||
stdout().flush()
|
||||
}
|
||||
StreamInstance::DynReadSource(_) | StreamInstance::ReadlineStream(_) |
|
||||
StreamInstance::InputFile(..) | StreamInstance::Null => {
|
||||
StreamInstance::PausedPrologStream(..) |
|
||||
StreamInstance::StaticStr(_) |
|
||||
StreamInstance::ReadlineStream(_) |
|
||||
StreamInstance::InputFile(..) |
|
||||
StreamInstance::Null => {
|
||||
Err(std::io::Error::new(
|
||||
ErrorKind::PermissionDenied,
|
||||
StreamError::FlushToInputStream,
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::parser::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::parser::*;
|
||||
|
||||
use crate::prolog::machine::machine_indices::HeapCellValue;
|
||||
use crate::prolog::machine::*;
|
||||
use crate::prolog::rug::ops::Pow;
|
||||
use crate::prolog::rug::Integer;
|
||||
use crate::machine::machine_indices::HeapCellValue;
|
||||
use crate::machine::*;
|
||||
use crate::rug::ops::Pow;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -165,7 +165,7 @@ impl<'a> TermStream<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn eof(&mut self) -> Result<bool, ParserError> {
|
||||
self.parser.devour_whitespace()?; // eliminate dangling comments before checking for EOF.
|
||||
self.parser.devour_whitespace()?; // eliminate dangling comments before checking for EOF.
|
||||
Ok(self.stack.is_empty() && self.parser.eof()?)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use crate::prolog_parser::ast::*;
|
||||
use crate::prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::prolog::forms::*;
|
||||
use crate::prolog::iterators::*;
|
||||
use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::term_expansion::*;
|
||||
use crate::prolog::machine::*;
|
||||
use crate::forms::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::term_expansion::*;
|
||||
use crate::machine::*;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::borrow::BorrowMut;
|
||||
use std::cell::Cell;
|
||||
@@ -340,16 +340,37 @@ fn setup_module_decl(
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, ParserError> {
|
||||
fn read_library_path(
|
||||
term: Term,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
) -> Option<ClauseName> {
|
||||
match term {
|
||||
Term::Constant(_, Constant::Atom(atom, _)) => {
|
||||
Some(atom.defrock_brackets())
|
||||
}
|
||||
_ => {
|
||||
let mut atoms = vec![];
|
||||
|
||||
for term in unfold_by_str(term, "/") {
|
||||
match term {
|
||||
Term::Constant(_, Constant::Atom(atom, _)) => {
|
||||
atoms.push(atom.as_str().to_owned());
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
|
||||
Some(clause_name!(atoms.join("/"), atom_tbl))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_use_module_decl(mut terms: Vec<Box<Term>>, atom_tbl: TabledData<Atom>) -> Result<ModuleSource, ParserError> {
|
||||
match *terms.pop().unwrap() {
|
||||
Term::Clause(_, ref name, ref mut terms, None)
|
||||
if name.as_str() == "library" && terms.len() == 1 =>
|
||||
{
|
||||
terms
|
||||
.pop()
|
||||
.unwrap()
|
||||
.to_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
read_library_path(*terms.pop().unwrap(), atom_tbl)
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(ParserError::InvalidUseModuleDecl)
|
||||
}
|
||||
@@ -396,11 +417,7 @@ fn setup_qualified_import(
|
||||
Term::Clause(_, ref name, ref mut terms, None)
|
||||
if name.as_str() == "library" && terms.len() == 1 =>
|
||||
{
|
||||
terms
|
||||
.pop()
|
||||
.unwrap()
|
||||
.to_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
read_library_path(*terms.pop().unwrap(), atom_tbl.clone())
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(ParserError::InvalidUseModuleDecl)
|
||||
}
|
||||
@@ -685,7 +702,7 @@ fn setup_declaration<'a, 'b, 'c>(
|
||||
}
|
||||
}
|
||||
("use_module", 1) => {
|
||||
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
|
||||
Ok(Declaration::UseModule(setup_use_module_decl(terms, indices.atom_tbl())?))
|
||||
}
|
||||
("use_module", 2) => {
|
||||
let (name, exports) = setup_qualified_import(terms, indices.atom_tbl())?;
|
||||
@@ -121,6 +121,9 @@ macro_rules! functor_term {
|
||||
(atom($e:expr), $arity:expr, $aux_lens:expr, $addendum: ident) => (
|
||||
HeapCellValue::Atom(clause_name!($e), None)
|
||||
);
|
||||
(value($e:expr), $arity:expr, $aux_lens:expr, $addendum: ident) => (
|
||||
$e
|
||||
);
|
||||
(string($h:expr, $e:expr), $arity:expr, $aux_lens:expr, $addendum: ident) => ({
|
||||
let len: usize = $aux_lens.iter().sum();
|
||||
let h = len + $arity + 1 + $addendum.h() + $h;
|
||||
39
src/main.rs
39
src/main.rs
@@ -1,3 +1,6 @@
|
||||
extern crate blake2;
|
||||
extern crate chrono;
|
||||
extern crate cpu_time;
|
||||
extern crate crossterm;
|
||||
extern crate divrem;
|
||||
#[macro_use]
|
||||
@@ -8,19 +11,45 @@ extern crate indexmap;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
extern crate native_tls;
|
||||
extern crate nix;
|
||||
extern crate openssl;
|
||||
extern crate ordered_float;
|
||||
#[macro_use]
|
||||
extern crate prolog_parser;
|
||||
#[macro_use]
|
||||
extern crate ref_thread_local;
|
||||
extern crate ring;
|
||||
extern crate ripemd160;
|
||||
extern crate rug;
|
||||
extern crate rustyline;
|
||||
extern crate sha3;
|
||||
extern crate unicode_reader;
|
||||
|
||||
use nix::sys::signal;
|
||||
use crate::nix::sys::signal;
|
||||
|
||||
mod prolog;
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod allocator;
|
||||
mod arithmetic;
|
||||
mod codegen;
|
||||
mod clause_types;
|
||||
mod debray_allocator;
|
||||
mod fixtures;
|
||||
mod forms;
|
||||
mod heap_iter;
|
||||
mod heap_print;
|
||||
mod indexing;
|
||||
mod instructions;
|
||||
mod iterators;
|
||||
mod machine;
|
||||
mod read;
|
||||
mod targets;
|
||||
mod write;
|
||||
|
||||
use crate::prolog::machine::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::prolog::read::*;
|
||||
use machine::*;
|
||||
use machine::streams::*;
|
||||
use read::*;
|
||||
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ extern crate prolog_parser;
|
||||
extern crate rug;
|
||||
#[cfg(feature = "num-rug-adapter")]
|
||||
extern crate num_rug_adapter as rug;
|
||||
extern crate rustyline;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
@@ -1,15 +0,0 @@
|
||||
:- use_module(library(charsio)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
:- initialization(unit_test).
|
||||
|
||||
unit_test :-
|
||||
chars_utf8bytes("a£\x2124\", Bs),
|
||||
Bs = [97, 194, 163, 226, 132, 164].
|
||||
|
||||
write_f :-
|
||||
open('x.txt', write, Stream, [type(binary)]),
|
||||
F = put_byte(Stream),
|
||||
chars_utf8bytes("£\x2124\\x2764\\x1F496\\n", Bs),
|
||||
maplist(F, Bs),
|
||||
close(Stream).
|
||||
@@ -1,24 +0,0 @@
|
||||
:- module(pio, [phrase_from_file/2,
|
||||
phrase_from_file/3]).
|
||||
|
||||
:- use_module(library(dcgs)).
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(lists), [member/2]).
|
||||
|
||||
phrase_from_file(NT, File) :-
|
||||
phrase_from_file(NT, File, []).
|
||||
|
||||
phrase_from_file(NT, File, Options) :-
|
||||
( var(File) -> instantiation_error(phrase_from_file/3)
|
||||
; (\+ atom(File) ; File = []) ->
|
||||
domain_error(source_sink, File, phrase_from_file/3)
|
||||
; must_be(list, Options),
|
||||
( member(Var, Options), var(Var) -> instantiation_error(phrase_from_file/3)
|
||||
; member(type(Type), Options) ->
|
||||
must_be(atom, Type),
|
||||
member(Type, [text,binary])
|
||||
; Type = text
|
||||
),
|
||||
'$file_to_chars'(File, Chars, Type),
|
||||
phrase(NT, Chars)
|
||||
).
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user