diff options
author | Mark Thom <markjordanthom@gmail.com> | 2022-11-10 07:18:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-10 07:18:10 +0100 |
commit | eb9d865635c92b32e5865618b25945b9808dea39 (patch) | |
tree | 8ad9546d6bc58fc6149786ffee31cf121dae763a | |
parent | c7e1f5d56805f35af7f52d4b2c1482de232e683f (diff) | |
parent | 694c87cb61289be678288947cce8a6a9889513c1 (diff) |
Merge pull request #1635 from mthom/rebis-devv0.9.1
Merge rebis-dev into master
63 files changed, 5165 insertions, 2534 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index db4801c9..edcd1993 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,3 +52,20 @@ jobs: crate: cargo-msrv - name: Verify MSRV run: cargo msrv --verify + windows: + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + steps: + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + base-devel + mingw-w64-x86_64-rust + - name: Checkout sources + uses: actions/checkout@v3 + - name: Test on Windows + run: cargo test --verbose --all @@ -3,6 +3,15 @@ version = 3 [[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -39,9 +48,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "az" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f771a5d1f5503f7f4279a30f3643d3421ba149848b89ecaaec0ea2acf04a5ac4" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" [[package]] name = "base64" @@ -51,9 +60,9 @@ checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "bit-set" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ "bit-vec", ] @@ -78,11 +87,20 @@ checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" dependencies = [ "byte-tools", "crypto-mac", - "digest", + "digest 0.8.1", "opaque-debug", ] [[package]] +name = "blake2" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +dependencies = [ + "digest 0.10.5", +] + +[[package]] name = "block-buffer" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -91,7 +109,16 @@ dependencies = [ "block-padding", "byte-tools", "byteorder", - "generic-array", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array 0.14.6", ] [[package]] @@ -116,9 +143,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "byte-tools" @@ -134,15 +161,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" [[package]] name = "cfg-if" @@ -152,22 +179,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "time", + "wasm-bindgen", "winapi", ] [[package]] name = "clipboard-win" -version = "4.4.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3e1238132dc01f081e1cbb9dace14e5ef4c3a51ee244bd982275fb514605db" +checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219" dependencies = [ "error-code", "str-buf", @@ -184,6 +213,16 @@ dependencies = [ ] [[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] name = "core-foundation" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -210,6 +249,15 @@ dependencies = [ ] [[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] name = "crossterm" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -235,26 +283,91 @@ dependencies = [ ] [[package]] +name = "crrl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db40892a506901e4e8281f00e42687df82d1d3448cb0289ae9183a60cb42ec1" +dependencies = [ + "blake2 0.10.4", + "rand_core 0.6.4", + "sha2", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.6", + "typenum", +] + +[[package]] name = "crypto-mac" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" dependencies = [ - "generic-array", - "subtle", + "generic-array 0.12.4", + "subtle 1.0.0", ] [[package]] name = "ctrlc" -version = "3.2.2" +version = "3.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865" +checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" dependencies = [ - "nix 0.24.1", + "nix 0.25.0", "winapi", ] [[package]] +name = "cxx" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2 1.0.47", + "quote 1.0.21", + "scratch", + "syn 1.0.103", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" +dependencies = [ + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", +] + +[[package]] name = "difflib" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -266,7 +379,18 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "generic-array", + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +dependencies = [ + "block-buffer 0.10.3", + "crypto-common", + "subtle 2.4.1", ] [[package]] @@ -304,18 +428,18 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "ed25519" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d5c4b5e5959dc2c2b89918d8e2cc40fcdd623cef026ed09d2f0ee05199dc8e4" +checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" dependencies = [ "signature", ] [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "endian-type" @@ -356,22 +480,22 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] [[package]] name = "fd-lock" -version = "3.0.5" +version = "3.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e245f4c8ec30c6415c56cb132c07e69e74f1942f6b4a4061da748b49f486ca" +checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27" dependencies = [ "cfg-if", "rustix", - "windows-sys 0.30.0", + "windows-sys 0.42.0", ] [[package]] @@ -412,42 +536,92 @@ dependencies = [ ] [[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", +] [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -469,14 +643,24 @@ dependencies = [ ] [[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -496,16 +680,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] name = "gmp-mpfr-sys" -version = "1.4.7" +version = "1.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a146a7357ce9573bdcc416fc4a99b960e166e72d8eaffa7c59966d51866b5bfb" +checksum = "ea3f42dadb6c75f122e9aa87e757ef11d4282f664c9f2e6476a9c2c8970f9d19" dependencies = [ "libc", "winapi", @@ -513,9 +697,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -532,9 +716,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -581,9 +765,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -592,9 +776,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -603,9 +787,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -615,9 +799,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.18" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -651,10 +835,34 @@ dependencies = [ ] [[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg 1.1.0", "hashbrown", @@ -671,39 +879,43 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "0.6.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9448015e586b611e5d322f6703812bbca2f1e709d5773ecd38ddb4e3bb649504" +checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] [[package]] name = "keccak" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" [[package]] name = "lazy_static" @@ -736,9 +948,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.121" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "libsodium-sys" @@ -753,25 +965,35 @@ dependencies = [ ] [[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] name = "linux-raw-sys" -version = "0.0.42" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5284f00d480e1c39af34e72f8ad60b94f47007e3481cd3b731c1d67190ddc7b7" +checksum = "bb68f22743a3fb35785f1e7f844ca5a3de2dde5bd0c0ef5b372065814699b121" [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] [[package]] name = "log" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -807,9 +1029,9 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -835,16 +1057,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", - "miow", - "ntapi", "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -870,16 +1090,16 @@ name = "modular-bitfield-impl" version = "0.11.2" source = "git+https://github.com/mthom/modular-bitfield#213535c684af277563678179d8496f11b84a283f" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] name = "native-tls" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bf6f32a3afefd0b587ee42ed19acd945c6d1f3b5424040f50b2f24ab16be77" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", @@ -923,10 +1143,11 @@ dependencies = [ [[package]] name = "nix" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" dependencies = [ + "autocfg 1.1.0", "bitflags", "cfg-if", "libc", @@ -942,64 +1163,29 @@ dependencies = [ ] [[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg 1.1.0", - "num-integer", - "num-traits", -] - -[[package]] name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg 1.1.0", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.2.4" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg 1.1.0", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rug-adapter" -version = "0.1.6" -source = "git+https://github.com/mthom/num-rug-adapter#58ec611ca8ac4d6ebf41e41f588f472e51a23e60" -dependencies = [ - "libc", - "num-bigint", - "num-integer", - "num-rational", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg 1.1.0", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", @@ -1007,9 +1193,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -1019,43 +1205,45 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] [[package]] -name = "openssl-probe" -version = "0.1.5" +name = "openssl-macros" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", +] [[package]] -name = "openssl-src" -version = "111.18.0+1.1.1n" +name = "openssl-probe" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7897a926e1e8d00219127dc020130eca4292e5ca666dd592480d72c3eca2ff6c" -dependencies = [ - "cc", -] +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.72" +version = "0.9.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" dependencies = [ "autocfg 1.1.0", "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -1082,12 +1270,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.1", + "parking_lot_core 0.9.4", ] [[package]] @@ -1106,15 +1294,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.32.0", + "windows-sys 0.42.0", ] [[package]] @@ -1176,9 +1364,9 @@ dependencies = [ "phf_generator 0.9.1", "phf_shared 0.9.0", "proc-macro-hack", - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] @@ -1201,9 +1389,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -1213,15 +1401,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "precomputed-hash" @@ -1231,9 +1419,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "predicates" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" +checksum = "ab68289ded120dcbf9d571afcf70163233229052aec9b08ab09532f698d0e1e6" dependencies = [ "difflib", "itertools", @@ -1242,15 +1430,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb" +checksum = "a6e7125585d872860e9955ca571650b27a4979c5823084168c5ed5bbfb016b56" [[package]] name = "predicates-tree" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032" +checksum = "ad3f7fa8d61e139cbc7c3edfebf3b6678883a53f5ffac65d1259329a93ee43a5" dependencies = [ "predicates-core", "termtree", @@ -1268,16 +1456,16 @@ version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" dependencies = [ - "unicode-xid 0.1.0", + "unicode-xid", ] [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid 0.2.2", + "unicode-ident", ] [[package]] @@ -1291,11 +1479,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.17" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ - "proc-macro2 1.0.36", + "proc-macro2 1.0.47", ] [[package]] @@ -1335,7 +1523,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1355,7 +1543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1375,9 +1563,9 @@ checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -1455,18 +1643,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7776223e2696f1aa4c6b0170e83212f47296a00424305117d013dfe86fb0fe55" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", @@ -1515,8 +1703,8 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" dependencies = [ - "block-buffer", - "digest", + "block-buffer 0.7.3", + "digest 0.8.1", "opaque-debug", ] @@ -1531,9 +1719,9 @@ dependencies = [ [[package]] name = "rug" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac804305677221f4c82469fd7eb8bfe00dd01420aa191197cb87d738520feef" +checksum = "203180f444c95eac53586ed04793ecf6454c5d28f9eca8eead815fc19e136c47" dependencies = [ "az", "gmp-mpfr-sys", @@ -1542,23 +1730,23 @@ dependencies = [ [[package]] name = "rustix" -version = "0.34.1" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3cc851a13d30a34cb747ba2a0c5101a4b2e8b1677a29b213ee465365ea495e" +checksum = "812a2ec2043c4d6bc6482f5be2ab8244613cac2493d128d36c0759e52a626ab3" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" [[package]] name = "rustyline" @@ -1586,9 +1774,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -1601,12 +1789,12 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "winapi", + "windows-sys 0.36.1", ] [[package]] @@ -1616,18 +1804,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] name = "scryer-prolog" -version = "0.9.0" +version = "0.9.1" dependencies = [ "assert_cmd", "base64", - "blake2", + "blake2 0.8.1", "chrono", "cpu-time", "crossterm", + "crrl", "ctrlc", "dirs-next", "divrem", + "futures", "fxhash", "git-version", "hostname", @@ -1639,13 +1835,11 @@ dependencies = [ "libc", "modular-bitfield", "native-tls", - "num-rug-adapter", - "openssl", "ordered-float", "phf 0.9.0", "predicates-core", - "proc-macro2 1.0.36", - "quote 1.0.17", + "proc-macro2 1.0.47", + "quote 1.0.21", "ref_thread_local", "ring", "ripemd160", @@ -1661,7 +1855,7 @@ dependencies = [ "static_assertions", "strum", "strum_macros", - "syn 1.0.90", + "syn 1.0.103", "to-syn-value", "to-syn-value_derive", "tokio", @@ -1670,9 +1864,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -1703,26 +1897,26 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.136" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", @@ -1746,9 +1940,20 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.5", ] [[package]] @@ -1757,18 +1962,18 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" dependencies = [ - "block-buffer", + "block-buffer 0.7.3", "byte-tools", - "digest", + "digest 0.8.1", "keccak", "opaque-debug", ] [[package]] name = "signal-hook" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" dependencies = [ "libc", "signal-hook-registry", @@ -1796,9 +2001,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.5.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "siphasher" @@ -1814,21 +2019,24 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg 1.1.0", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -1860,9 +2068,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str-buf" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" [[package]] name = "string_cache" @@ -1887,8 +2095,8 @@ checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6" dependencies = [ "phf_generator 0.7.24", "phf_shared 0.7.24", - "proc-macro2 1.0.36", - "quote 1.0.17", + "proc-macro2 1.0.47", + "quote 1.0.21", "string_cache_shared", ] @@ -1911,10 +2119,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" dependencies = [ "heck", - "proc-macro2 1.0.36", - "quote 1.0.17", + "proc-macro2 1.0.47", + "quote 1.0.21", "rustversion", - "syn 1.0.90", + "syn 1.0.103", ] [[package]] @@ -1924,6 +2132,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] name = "syn" version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1931,18 +2145,18 @@ checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" dependencies = [ "proc-macro2 0.4.30", "quote 0.6.13", - "unicode-xid 0.1.0", + "unicode-xid", ] [[package]] name = "syn" -version = "1.0.90" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "unicode-xid 0.2.2", + "proc-macro2 1.0.47", + "quote 1.0.21", + "unicode-ident", ] [[package]] @@ -1971,38 +2185,48 @@ dependencies = [ ] [[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] name = "termtree" -version = "0.2.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" +checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] name = "time" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] @@ -2012,7 +2236,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45dcb7b4108a4793bdd74aa3714296c6eaf43663edf73fa8625d0d7621e68447" dependencies = [ - "syn 1.0.90", + "syn 1.0.103", "to-syn-value_derive", ] @@ -2022,24 +2246,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd4fdec6de01b568c1d3721c9d46a352623c536cd55a8a5acfefb63d1fccccbc" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] name = "tokio" -version = "1.17.0" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ + "autocfg 1.1.0", "bytes", "libc", "memchr", - "mio 0.8.2", + "mio 0.8.5", "num_cpus", - "once_cell", - "parking_lot 0.12.0", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2049,13 +2273,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", ] [[package]] @@ -2070,29 +2294,29 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.32" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -2101,11 +2325,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.23" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -2121,16 +2345,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] name = "unicode-segmentation" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" @@ -2139,12 +2369,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2169,6 +2393,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2200,9 +2430,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasi" @@ -2212,9 +2442,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2222,53 +2452,53 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", - "lazy_static", "log", - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "once_cell", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ - "quote 1.0.17", + "quote 1.0.21", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ - "proc-macro2 1.0.36", - "quote 1.0.17", - "syn 1.0.90", + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -2307,92 +2537,106 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030b7ff91626e57a05ca64a07c481973cbb2db774e4852c9c7ca342408c6a99a" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc 0.30.0", - "windows_i686_gnu 0.30.0", - "windows_i686_msvc 0.30.0", - "windows_x86_64_gnu 0.30.0", - "windows_x86_64_msvc 0.30.0", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] [[package]] name = "windows-sys" -version = "0.32.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_msvc 0.32.0", - "windows_i686_gnu 0.32.0", - "windows_i686_msvc 0.32.0", - "windows_x86_64_gnu 0.32.0", - "windows_x86_64_msvc 0.32.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", ] [[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] name = "windows_aarch64_msvc" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_aarch64_msvc" -version = "0.32.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_gnu" -version = "0.32.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_i686_msvc" -version = "0.32.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_gnu" -version = "0.32.0" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "windows_x86_64_msvc" -version = "0.32.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" [[package]] name = "xmlparser" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" +checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.9.0" +version = "0.9.1" authors = ["Mark Thom <markjordanthom@gmail.com>"] edition = "2021" description = "A modern Prolog implementation written mostly in Rust." @@ -10,13 +10,9 @@ license = "BSD-3-Clause" keywords = ["prolog", "prolog-interpreter", "prolog-system"] categories = ["command-line-utilities"] build = "build/main.rs" -rust-version = "1.57" +rust-version = "1.61" [features] -num = ["num-rug-adapter"] -# no default features to make num tests work -# workaround for --no-default-features and --features not working intuitively for workspaces with a root package -# see rust-lang/cargo#7160 default = ["rug"] [build-dependencies] @@ -44,7 +40,6 @@ lexical = "5.2.2" libc = "0.2.62" modular-bitfield = "0.11.2" ctrlc = "3.2.2" -num-rug-adapter = { version = "0.1.6", optional = true } ordered-float = "2.6.0" phf = { version = "0.9", features = ["macros"] } ref_thread_local = "0.0.0" @@ -54,7 +49,7 @@ ring = "0.16.13" ripemd160 = "0.8.0" sha3 = "0.8.2" blake2 = "0.8.1" -openssl = { version = "0.10.29", features = ["vendored"] } +crrl ="0.2.0" native-tls = "0.2.4" chrono = "0.4.11" select = "0.4.3" @@ -67,6 +62,7 @@ ryu = "1.0.9" hyper = { version = "0.14", features = ["full"] } hyper-tls = "0.5.0" tokio = { version = "1", features = ["full"] } +futures = "0.3" [dev-dependencies] assert_cmd = "1.0.3" @@ -75,7 +71,6 @@ serial_test = "0.5.1" [patch.crates-io] modular-bitfield = { git = "https://github.com/mthom/modular-bitfield" } -num-rug-adapter = { git = "https://github.com/mthom/num-rug-adapter" } [profile.release] -debug = true
\ No newline at end of file +debug = true @@ -539,7 +539,7 @@ The modules that ship with Scryer Prolog are also called Probabilistic predicates and random number generators. * [`http/http_open`](src/lib/http/http_open.pl) Open a stream to read answers from web servers. HTTPS is also supported. -* [`http/http_server`](src/lib/http/http_server.pl) Runs a HTTP/1.0 web server. +* [`http/http_server`](src/lib/http/http_server.pl) Runs a HTTP/1.1 and HTTP/2.0 web server. Uses [Hyper](https://hyper.rs) as a backend. Supports some query and form handling. * [`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 diff --git a/build/instructions_template.rs b/build/instructions_template.rs index ed891b49..bc1ca703 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -190,9 +190,9 @@ enum REPLCodePtr { DynamicProperty, #[strum_discriminants(strum(props(Arity = "3", Name = "$abolish_clause")))] AbolishClause, - #[strum_discriminants(strum(props(Arity = "5", Name = "$asserta")))] + #[strum_discriminants(strum(props(Arity = "3", Name = "$asserta")))] Asserta, - #[strum_discriminants(strum(props(Arity = "5", Name = "$assertz")))] + #[strum_discriminants(strum(props(Arity = "3", Name = "$assertz")))] Assertz, #[strum_discriminants(strum(props(Arity = "4", Name = "$retract_clause")))] Retract, @@ -404,8 +404,6 @@ enum SystemClauseType { InferenceLevel, #[strum_discriminants(strum(props(Arity = "1", Name = "$clean_up_block")))] CleanUpBlock, - #[strum_discriminants(strum(props(Arity = "0", Name = "$erase_ball")))] - EraseBall, #[strum_discriminants(strum(props(Arity = "0", Name = "$fail")))] Fail, #[strum_discriminants(strum(props(Arity = "1", Name = "$get_ball")))] @@ -434,6 +432,12 @@ enum SystemClauseType { ReturnFromVerifyAttr, #[strum_discriminants(strum(props(Arity = "1", Name = "$set_ball")))] SetBall, + #[strum_discriminants(strum(props(Arity = "0", Name = "$push_ball_stack")))] + PushBallStack, + #[strum_discriminants(strum(props(Arity = "0", Name = "$pop_ball_stack")))] + PopBallStack, + #[strum_discriminants(strum(props(Arity = "0", Name = "$pop_from_ball_stack")))] + PopFromBallStack, #[strum_discriminants(strum(props(Arity = "1", Name = "$set_cp_by_default")))] SetCutPointByDefault(RegType), #[strum_discriminants(strum(props(Arity = "1", Name = "$set_double_quotes")))] @@ -492,7 +496,7 @@ enum SystemClauseType { CryptoDataEncrypt, #[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))] CryptoDataDecrypt, - #[strum_discriminants(strum(props(Arity = "5", Name = "$crypto_curve_scalar_mult")))] + #[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_curve_scalar_mult")))] CryptoCurveScalarMult, #[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign")))] Ed25519Sign, @@ -544,10 +548,22 @@ enum SystemClauseType { DeterministicLengthRundown, #[strum_discriminants(strum(props(Arity = "7", Name = "$http_open")))] HttpOpen, + #[strum_discriminants(strum(props(Arity = "2", Name = "$http_listen")))] + HttpListen, + #[strum_discriminants(strum(props(Arity = "7", Name = "$http_accept")))] + HttpAccept, + #[strum_discriminants(strum(props(Arity = "4", Name = "$http_answer")))] + HttpAnswer, #[strum_discriminants(strum(props(Arity = "3", Name = "$predicate_defined")))] PredicateDefined, #[strum_discriminants(strum(props(Arity = "3", Name = "$strip_module")))] StripModule, + #[strum_discriminants(strum(props(Arity = "4", Name = "$compile_inline_or_expanded_goal")))] + CompileInlineOrExpandedGoal, + #[strum_discriminants(strum(props(Arity = "arity", Name = "$call_inline")))] + InlineCallN(usize), + #[strum_discriminants(strum(props(Arity = "1", Name = "$is_expanded_or_inlined")))] + IsExpandedOrInlined, REPL(REPLCodePtr), } @@ -1435,6 +1451,12 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::DefaultExecuteN(arity, _) => { functor!(atom!("execute_default_n"), [fixnum(arity)]) } + &Instruction::CallInlineCallN(arity, _) => { + functor!(atom!("call_n_inline"), [fixnum(arity)]) + } + &Instruction::ExecuteInlineCallN(arity, _) => { + functor!(atom!("call_n_inline"), [fixnum(arity)]) + } &Instruction::CallTermGreaterThan(_) | &Instruction::CallTermLessThan(_) | &Instruction::CallTermGreaterThanOrEqual(_) | @@ -1597,6 +1619,8 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallDeleteHeadAttribute(_) | &Instruction::CallDynamicModuleResolution(..) | &Instruction::CallPrepareCallClause(..) | + &Instruction::CallCompileInlineOrExpandedGoal(..) | + &Instruction::CallIsExpandedOrInlined(_) | &Instruction::CallEnqueueAttributedVar(_) | &Instruction::CallFetchGlobalVar(_) | &Instruction::CallFirstStream(_) | @@ -1660,7 +1684,6 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallSetStreamPosition(_) | &Instruction::CallInferenceLevel(_) | &Instruction::CallCleanUpBlock(_) | - &Instruction::CallEraseBall(_) | &Instruction::CallFail(_) | &Instruction::CallGetBall(_) | &Instruction::CallGetCurrentBlock(_) | @@ -1672,6 +1695,9 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallCpuNow(_) | &Instruction::CallDeterministicLengthRundown(_) | &Instruction::CallHttpOpen(_) | + &Instruction::CallHttpListen(_) | + &Instruction::CallHttpAccept(_) | + &Instruction::CallHttpAnswer(_) | &Instruction::CallPredicateDefined(_) | &Instruction::CallStripModule(_) | &Instruction::CallCurrentTime(_) | @@ -1680,6 +1706,9 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallResetBlock(_) | &Instruction::CallReturnFromVerifyAttr(_) | &Instruction::CallSetBall(_) | + &Instruction::CallPushBallStack(_) | + &Instruction::CallPopBallStack(_) | + &Instruction::CallPopFromBallStack(_) | &Instruction::CallSetCutPointByDefault(..) | &Instruction::CallSetDoubleQuotes(_) | &Instruction::CallSetSeed(_) | @@ -1804,6 +1833,8 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteDeleteHeadAttribute(_) | &Instruction::ExecuteDynamicModuleResolution(..) | &Instruction::ExecutePrepareCallClause(..) | + &Instruction::ExecuteCompileInlineOrExpandedGoal(..) | + &Instruction::ExecuteIsExpandedOrInlined(_) | &Instruction::ExecuteEnqueueAttributedVar(_) | &Instruction::ExecuteFetchGlobalVar(_) | &Instruction::ExecuteFirstStream(_) | @@ -1867,7 +1898,6 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteSetStreamPosition(_) | &Instruction::ExecuteInferenceLevel(_) | &Instruction::ExecuteCleanUpBlock(_) | - &Instruction::ExecuteEraseBall(_) | &Instruction::ExecuteFail(_) | &Instruction::ExecuteGetBall(_) | &Instruction::ExecuteGetCurrentBlock(_) | @@ -1879,6 +1909,9 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteCpuNow(_) | &Instruction::ExecuteDeterministicLengthRundown(_) | &Instruction::ExecuteHttpOpen(_) | + &Instruction::ExecuteHttpListen(_) | + &Instruction::ExecuteHttpAccept(_) | + &Instruction::ExecuteHttpAnswer(_) | &Instruction::ExecutePredicateDefined(_) | &Instruction::ExecuteStripModule(_) | &Instruction::ExecuteCurrentTime(_) | @@ -1887,6 +1920,9 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteResetBlock(_) | &Instruction::ExecuteReturnFromVerifyAttr(_) | &Instruction::ExecuteSetBall(_) | + &Instruction::ExecutePushBallStack(_) | + &Instruction::ExecutePopBallStack(_) | + &Instruction::ExecutePopFromBallStack(_) | &Instruction::ExecuteSetCutPointByDefault(_, _) | &Instruction::ExecuteSetDoubleQuotes(_) | &Instruction::ExecuteSetSeed(_) | @@ -2179,6 +2215,7 @@ pub fn generate_instructions_rs() -> TokenStream { let mut clause_type_from_name_and_arity_arms = vec![]; let mut clause_type_to_instr_arms = vec![]; let mut clause_type_name_arms = vec![]; + let mut is_inbuilt_arms = vec![]; for (name, arity, variant) in instr_data.compare_number_variants { let ident = variant.ident.clone(); @@ -2233,6 +2270,12 @@ pub fn generate_instructions_rs() -> TokenStream { ) => Instruction::#instr_ident(#(#placeholder_ids),*, 0) } ); + + is_inbuilt_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.compare_term_variants { @@ -2262,6 +2305,12 @@ pub fn generate_instructions_rs() -> TokenStream { ) => Instruction::#instr_ident(0) } ); + + is_inbuilt_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.builtin_type_variants { @@ -2323,6 +2372,12 @@ pub fn generate_instructions_rs() -> TokenStream { ) => Instruction::#instr_ident(0) } }); + + is_inbuilt_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.inlined_type_variants { @@ -2382,6 +2437,12 @@ pub fn generate_instructions_rs() -> TokenStream { ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) } ); + + is_inbuilt_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.system_clause_type_variants { @@ -2412,6 +2473,12 @@ pub fn generate_instructions_rs() -> TokenStream { SystemClauseType::#ident(temp_v!(1)) ) } + } else if ident.to_string() == "InlineCallN" { + quote! { + (atom!(#name), arity) => ClauseType::System( + SystemClauseType::#ident(arity) + ) + } } else { quote! { (atom!(#name), #arity) => ClauseType::System( @@ -2442,6 +2509,7 @@ pub fn generate_instructions_rs() -> TokenStream { }); let ident = variant.ident; + let instr_ident = if ident != "CallContinuation" { format_ident!("Call{}", ident) } else { @@ -2465,6 +2533,18 @@ pub fn generate_instructions_rs() -> TokenStream { ) => Instruction::#instr_ident(0) } }); + + is_inbuilt_arms.push( + if let Arity::Ident("arity") = &arity { + quote! { + (atom!(#name), _arity) => true + } + } else { + quote! { + (atom!(#name), #arity) => true + } + } + ); } for (name, arity, variant) in instr_data.repl_code_ptr_variants { @@ -2530,6 +2610,12 @@ pub fn generate_instructions_rs() -> TokenStream { )) => Instruction::#instr_ident(0) } }); + + is_inbuilt_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.clause_type_variants { @@ -2537,7 +2623,7 @@ pub fn generate_instructions_rs() -> TokenStream { if ident == "Named" { clause_type_from_name_and_arity_arms.push(quote! { - (name, arity) => ClauseType::Named(arity, name, CodeIndex::default()) + (name, arity) => ClauseType::Named(arity, name, CodeIndex::default(arena)) }); clause_type_to_instr_arms.push(quote! { @@ -2599,6 +2685,12 @@ pub fn generate_instructions_rs() -> TokenStream { ClauseType::#ident => Instruction::#ident(0) } }); + + is_inbuilt_arms.push( + quote! { + (atom!(#name), _arity) => true + } + ); } let to_execute_arms: Vec<_> = instr_data.instr_variants @@ -2933,7 +3025,7 @@ pub fn generate_instructions_rs() -> TokenStream { } impl ClauseType { - pub fn from(name: Atom, arity: usize) -> ClauseType { + pub fn from(name: Atom, arity: usize, arena: &mut Arena) -> ClauseType { match (name, arity) { #( #clause_type_from_name_and_arity_arms, @@ -2949,19 +3041,12 @@ pub fn generate_instructions_rs() -> TokenStream { } } - pub fn is_builtin(&self) -> bool { - if let ClauseType::BuiltIn(_) = self { - true - } else { - false - } - } - - pub fn is_inlined(&self) -> bool { - if let ClauseType::Inlined(_) = self { - true - } else { - false + pub fn is_inbuilt(name: Atom, arity: usize) -> bool { + match (name, arity) { + #( + #is_inbuilt_arms, + )* + _ => false, } } @@ -3156,7 +3241,7 @@ enum Arity { impl From<&'static str> for Arity { fn from(arity: &'static str) -> Self { usize::from_str_radix(&arity, 10) - .map(|n| Arity::Static(n)) + .map(Arity::Static) .unwrap_or_else(|_| Arity::Ident(arity)) } } diff --git a/build/static_string_indexing.rs b/build/static_string_indexing.rs index 6f57b37f..ca5ac765 100644 --- a/build/static_string_indexing.rs +++ b/build/static_string_indexing.rs @@ -66,7 +66,7 @@ impl<'ast> Visit<'ast> for StaticStrVisitor { if let Some(Lit::Str(string)) = m.parse_body::<Lit>().ok() { self.static_strs.insert(string.value()); } - } else if path.is_ident("read_heap_cell") { + } else if path.is_ident("read_heap_cell") || path.is_ident("match_untyped_arena_ptr") { if let Some(m) = m.parse_body::<ReadHeapCellExprAndArms>().ok() { self.visit_expr(&m.expr); diff --git a/src/arena.rs b/src/arena.rs index 2f9a6018..3e75e120 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -1,10 +1,10 @@ +use crate::http::{HttpListener, HttpResponse}; use crate::machine::loader::LiveLoadState; use crate::machine::machine_indices::*; use crate::machine::streams::*; use crate::raw_block::*; use crate::read::*; -use modular_bitfield::prelude::*; use ordered_float::OrderedFloat; use crate::parser::rug::{Integer, Rational}; @@ -21,7 +21,7 @@ macro_rules! arena_alloc { ($e:expr, $arena:expr) => {{ let result = $e; #[allow(unused_unsafe)] - unsafe { $arena.alloc(result) } + unsafe { ArenaAllocated::alloc($arena, result) } }}; } @@ -140,7 +140,8 @@ pub enum ArenaHeaderTag { OutputFileStream = 0b10100, NamedTcpStream = 0b011100, NamedTlsStream = 0b100000, - NamedHttpClientStream = 0b100001, + HttpReadStream = 0b100001, + HttpWriteStream = 0b100010, ReadlineStream = 0b110000, StaticStringStream = 0b110100, ByteStream = 0b111000, @@ -148,7 +149,13 @@ pub enum ArenaHeaderTag { StandardErrorStream = 0b11000, NullStream = 0b111100, TcpListener = 0b1000000, + HttpListener = 0b1000001, + HttpResponse = 0b1000010, Dropped = 0b1000100, + IndexPtrDynamicUndefined = 0b1000101, + IndexPtrDynamicIndex = 0b1000110, + IndexPtrIndex = 0b1000111, + IndexPtrUndefined = 0b1001000, } #[bitfield] @@ -234,7 +241,7 @@ impl<T: fmt::Display> fmt::Display for TypedArenaPtr<T> { } } -impl<T: ?Sized> TypedArenaPtr<T> { +impl<T: ?Sized + ArenaAllocated> TypedArenaPtr<T> { #[inline] pub const fn new(data: *mut T) -> Self { unsafe { TypedArenaPtr(ptr::NonNull::new_unchecked(data)) } @@ -248,14 +255,14 @@ impl<T: ?Sized> TypedArenaPtr<T> { #[inline] pub fn header_ptr(&self) -> *const ArenaHeader { let mut ptr = self.as_ptr() as *const u8 as usize; - ptr -= mem::size_of::<*const ArenaHeader>(); + ptr -= T::header_offset_from_payload(); // mem::size_of::<*const ArenaHeader>(); ptr as *const ArenaHeader } #[inline] fn header_ptr_mut(&mut self) -> *mut ArenaHeader { let mut ptr = self.as_ptr() as *const u8 as usize; - ptr -= mem::size_of::<*const ArenaHeader>(); + ptr -= T::header_offset_from_payload(); // mem::size_of::<*const ArenaHeader>(); ptr as *mut ArenaHeader } @@ -289,14 +296,35 @@ impl<T: ?Sized> TypedArenaPtr<T> { } } -pub trait ArenaAllocated { +pub trait ArenaAllocated: Sized { type PtrToAllocated; fn tag() -> ArenaHeaderTag; fn size(&self) -> usize; - fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated - where - Self: Sized; + fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated; + + fn header_offset_from_payload() -> usize { + mem::size_of::<*const ArenaHeader>() + } + + unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated { + let size = value.size() + mem::size_of::<AllocSlab>(); + + let align = mem::align_of::<AllocSlab>(); + let layout = alloc::Layout::from_size_align_unchecked(size, align); + + let slab = alloc::alloc(layout) as *mut AllocSlab; + + (*slab).next = arena.base; + (*slab).header = ArenaHeader::build_with(value.size() as u64, Self::tag()); + + let offset = (*slab).payload_offset(); + let result = value.copy_to_arena(offset as *mut Self); + + arena.base = slab; + + result + } } #[derive(Copy, Clone, Debug)] @@ -536,6 +564,93 @@ impl ArenaAllocated for TcpListener { } } +impl ArenaAllocated for HttpListener { + type PtrToAllocated = TypedArenaPtr<HttpListener>; + + #[inline] + fn tag() -> ArenaHeaderTag { + ArenaHeaderTag::HttpListener + } + + #[inline] + fn size(&self) -> usize { + mem::size_of::<Self>() + } + + #[inline] + fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated { + unsafe { + ptr::write(dst, self); + TypedArenaPtr::new(dst as *mut Self) + } + } +} + +impl ArenaAllocated for HttpResponse { + type PtrToAllocated = TypedArenaPtr<HttpResponse>; + + #[inline] + fn tag() -> ArenaHeaderTag { + ArenaHeaderTag::HttpResponse + } + + #[inline] + fn size(&self) -> usize { + mem::size_of::<Self>() + } + + #[inline] + fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated { + unsafe { + ptr::write(dst, self); + TypedArenaPtr::new(dst as *mut Self) + } + } +} + +impl ArenaAllocated for IndexPtr { + type PtrToAllocated = TypedArenaPtr<IndexPtr>; + + #[inline] + fn tag() -> ArenaHeaderTag { + ArenaHeaderTag::IndexPtrUndefined + } + + #[inline] + fn size(&self) -> usize { + mem::size_of::<Self>() + } + + #[inline] + fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated { + unsafe { + ptr::write(dst, self); + TypedArenaPtr::new(dst as *mut Self) + } + } + + #[inline] + fn header_offset_from_payload() -> usize { + 0 + } + + unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated { + let size = mem::size_of::<AllocSlab>(); + + let align = mem::align_of::<AllocSlab>(); + let layout = alloc::Layout::from_size_align_unchecked(size, align); + + let slab = alloc::alloc(layout) as *mut AllocSlab; + + (*slab).next = arena.base; + + let result = value.copy_to_arena(mem::transmute::<_, *mut IndexPtr>(&(*slab).header)); + arena.base = slab; + + result + } +} + #[derive(Clone, Copy, Debug)] struct AllocSlab { next: *mut AllocSlab, @@ -556,25 +671,6 @@ impl Arena { pub fn new() -> Self { Arena { base: ptr::null_mut(), f64_tbl: F64Table::new() } } - - pub unsafe fn alloc<T: ArenaAllocated>(&mut self, value: T) -> T::PtrToAllocated { - let size = value.size() + mem::size_of::<AllocSlab>(); - - let align = mem::align_of::<AllocSlab>(); - let layout = alloc::Layout::from_size_align_unchecked(size, align); - - let slab = alloc::alloc(layout) as *mut AllocSlab; - - (*slab).next = self.base; - (*slab).header = ArenaHeader::build_with(value.size() as u64, T::tag()); - - let offset = (*slab).payload_offset(); - let result = value.copy_to_arena(offset as *mut T); - - self.base = slab; - - result - } } unsafe fn drop_slab_in_place(value: &mut AllocSlab) { @@ -599,9 +695,12 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) { ArenaHeaderTag::NamedTlsStream => { ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<NamedTlsStream>>>()); } - ArenaHeaderTag::NamedHttpClientStream => { - ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<NamedHttpClientStream>>>()); + ArenaHeaderTag::HttpReadStream => { + ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<HttpReadStream>>>()); } + ArenaHeaderTag::HttpWriteStream => { + ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<HttpWriteStream>>>()); + } ArenaHeaderTag::ReadlineStream => { ptr::drop_in_place(value.payload_offset::<StreamLayout<ReadlineStream>>()); } @@ -622,13 +721,21 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) { ArenaHeaderTag::TcpListener => { ptr::drop_in_place(value.payload_offset::<TcpListener>()); } + ArenaHeaderTag::HttpListener => { + ptr::drop_in_place(value.payload_offset::<HttpListener>()); + } + ArenaHeaderTag::HttpResponse => { + ptr::drop_in_place(value.payload_offset::<HttpResponse>()); + } ArenaHeaderTag::StandardOutputStream => { ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardOutputStream>>()); } ArenaHeaderTag::StandardErrorStream => { ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardErrorStream>>()); } - ArenaHeaderTag::NullStream => { + ArenaHeaderTag::NullStream | ArenaHeaderTag::IndexPtrUndefined | + ArenaHeaderTag::IndexPtrDynamicUndefined | ArenaHeaderTag::IndexPtrDynamicIndex | + ArenaHeaderTag::IndexPtrIndex => { } } } @@ -745,7 +852,8 @@ mod tests { // integer let big_int: Integer = 2 * Integer::from(1u64 << 63); - let big_int_ptr: TypedArenaPtr<Integer> = arena_alloc!(big_int, wam.machine_st.arena); + let big_int_ptr: TypedArenaPtr<Integer> = + arena_alloc!(big_int, &mut wam.machine_st.arena); assert!(!big_int_ptr.as_ptr().is_null()); diff --git a/src/arithmetic.rs b/src/arithmetic.rs index 02870f81..172af5bb 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -13,7 +13,6 @@ use crate::parser::rug::ops::PowAssign; use crate::parser::rug::{Assign, Integer, Rational}; use crate::machine::machine_errors::*; -use crate::machine::machine_indices::*; use ordered_float::*; @@ -65,19 +64,22 @@ impl<'a> ArithInstructionIterator<'a> { fn from(term: &'a Term) -> Result<Self, ArithmeticError> { let state = match term { Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar), - Term::Clause(cell, name, terms) => match ClauseType::from(*name, terms.len()) { + Term::Clause(cell, name, terms) => { + TermIterState::Clause(Level::Shallow, 0, cell, *name, terms) + } + /* match ClauseType::from(*name, terms.len()) { ct @ ClauseType::Named(..) => { Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)) } - ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => { - let ct = ClauseType::Named(1, atom!("float"), CodeIndex::default()); + ct @ ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => { + // let ct = ClauseType::Named(1, atom!("float"), CodeIndex::default()); Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)) } _ => Err(ArithmeticError::NonEvaluableFunctor( Literal::Atom(*name), terms.len(), )), - }?, + }?,*/ Term::Literal(cell, cons) => TermIterState::Literal(Level::Shallow, cell, cons), Term::Cons(..) | Term::PartialString(..) | Term::CompleteString(..) => { return Err(ArithmeticError::NonEvaluableFunctor( @@ -108,17 +110,17 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { while let Some(iter_state) = self.state_stack.pop() { match iter_state { TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)), - TermIterState::Clause(lvl, child_num, cell, ct, subterms) => { + TermIterState::Clause(lvl, child_num, cell, name, subterms) => { let arity = subterms.len(); if child_num == arity { - return Some(Ok(ArithTermRef::Op(ct.name(), arity))); + return Some(Ok(ArithTermRef::Op(name, arity))); } else { self.state_stack.push(TermIterState::Clause( lvl, child_num + 1, cell, - ct, + name, subterms, )); diff --git a/src/codegen.rs b/src/codegen.rs index 832c4c89..ec69f277 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -263,6 +263,27 @@ impl DebrayAllocator { } } +// if the final argument of the structure is a Literal::Index, +// decrement the arity of the PutStructure instruction by 1. +fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) { + match instr { + Instruction::PutStructure(_, ref mut arity, _) | + Instruction::GetStructure(_, ref mut arity, _) => { + if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg { + // it is acceptable if arity == 0 is the result of + // this decrement. call/N will have to read the index + // constant for '$call_inline' to succeed. to find it, + // it must know the heap location of the index. + // self.store must stop before reading the atom into a + // register. + + *arity -= 1; + } + } + _ => {} + } +} + impl<'b> CodeGenerator<'b> { pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self { CodeGenerator { @@ -369,9 +390,15 @@ impl<'b> CodeGenerator<'b> { self.marker.mark_anon_var::<Target>(lvl, term_loc, &mut target); } } - TermRef::Clause(lvl, cell, ct, terms) => { + TermRef::Clause(lvl, cell, name, terms) => { self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target); - target.push(Target::to_structure(ct.name(), terms.len(), cell.get())); + target.push(Target::to_structure(name, terms.len(), cell.get())); + + if let Some(instr) = target.last_mut() { + if let Some(term) = terms.last() { + trim_structure_by_last_arg(instr, term); + } + } for subterm in terms { self.subterm_to_instr::<Target>(subterm, term_loc, is_exposed, &mut target); @@ -1039,10 +1066,7 @@ impl<'b> CodeGenerator<'b> { let iter = query_term_post_order_iter(term); let query = self.compile_target::<QueryInstruction, _>(iter, term_loc, is_exposed); - if !query.is_empty() { - code.extend(query.into_iter()); - } - + code.extend(query.into_iter()); self.add_conditional_call(code, term, num_perm_vars_left); } diff --git a/src/forms.rs b/src/forms.rs index 8433e1e6..97864370 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -154,24 +154,21 @@ impl ClauseInfo for PredicateKey { impl ClauseInfo for Term { fn name(&self) -> Option<Atom> { - //, atom_tbl: &AtomTable) -> Option<StringBuffer> { match self { Term::Clause(_, name, terms) => { - // let str_buf = StringBuffer::from(*name, atom_tbl); - match name.as_str() { - // str_buf.as_str() { - ":-" => { + match name { + atom!(":-") => { match terms.len() { 1 => None, // a declaration. - 2 => terms[0].name(), //.map(|name| StringBuffer::from(name, atom_tbl)), + 2 => terms[0].name(), _ => Some(*name), } } _ => Some(*name), //str_buf), } } - Term::Literal(_, Literal::Atom(name)) => Some(*name), //Some(StringBuffer::from(*name, atom_tbl)), + Term::Literal(_, Literal::Atom(name)) => Some(*name), _ => None, } } diff --git a/src/heap_iter.rs b/src/heap_iter.rs index 4ef5e633..9760be9e 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -89,6 +89,17 @@ impl<'a> Drop for StackfulPreOrderHeapIter<'a> { } } +pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> { + fn focus(&self) -> usize; +} + +impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> { + #[inline] + fn focus(&self) -> usize { + self.h + } +} + impl<'a> StackfulPreOrderHeapIter<'a> { #[inline] fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self { @@ -127,11 +138,6 @@ impl<'a> StackfulPreOrderHeapIter<'a> { } #[inline] - pub fn focus(&self) -> usize { - self.h - } - - #[inline] pub fn pop_stack(&mut self) -> Option<HeapCellValue> { while let Some(h) = self.stack.pop() { let is_readable_marked = h.is_marked(); @@ -271,13 +277,14 @@ pub(crate) fn stackful_preorder_iter( } #[derive(Debug)] -pub(crate) struct PostOrderIterator<Iter: Iterator<Item = HeapCellValue>> { +pub(crate) struct PostOrderIterator<Iter: FocusedHeapIter> { + focus: usize, base_iter: Iter, base_iter_valid: bool, - parent_stack: Vec<(usize, HeapCellValue)>, // number of children, parent node. + parent_stack: Vec<(usize, HeapCellValue, usize)>, // number of children, parent node, focus. } -impl<Iter: Iterator<Item = HeapCellValue>> Deref for PostOrderIterator<Iter> { +impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> { type Target = Iter; fn deref(&self) -> &Self::Target { @@ -285,9 +292,10 @@ impl<Iter: Iterator<Item = HeapCellValue>> Deref for PostOrderIterator<Iter> { } } -impl<Iter: Iterator<Item = HeapCellValue>> PostOrderIterator<Iter> { +impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> { pub(crate) fn new(base_iter: Iter) -> Self { PostOrderIterator { + focus: 0, base_iter, base_iter_valid: true, parent_stack: vec![], @@ -295,32 +303,36 @@ impl<Iter: Iterator<Item = HeapCellValue>> PostOrderIterator<Iter> { } } -impl<Iter: Iterator<Item = HeapCellValue>> Iterator for PostOrderIterator<Iter> { +impl<Iter: FocusedHeapIter> Iterator for PostOrderIterator<Iter> { type Item = HeapCellValue; fn next(&mut self) -> Option<Self::Item> { loop { - if let Some((child_count, node)) = self.parent_stack.pop() { + if let Some((child_count, node, focus)) = self.parent_stack.pop() { if child_count == 0 { + self.focus = focus; return Some(node); } - self.parent_stack.push((child_count - 1, node)); + self.parent_stack.push((child_count - 1, node, focus)); } if self.base_iter_valid { if let Some(item) = self.base_iter.next() { + let focus = self.base_iter.focus(); + read_heap_cell!(item, (HeapCellValueTag::Atom, (_name, arity)) => { - self.parent_stack.push((arity, item)); + self.parent_stack.push((arity, item, focus)); } (HeapCellValueTag::Lis) => { - self.parent_stack.push((2, item)); + self.parent_stack.push((2, item, focus)); } (HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => { - self.parent_stack.push((1, item)); + self.parent_stack.push((1, item, focus)); } _ => { + self.focus = focus; return Some(item); } ); @@ -338,12 +350,40 @@ impl<Iter: Iterator<Item = HeapCellValue>> Iterator for PostOrderIterator<Iter> } } +impl<Iter: FocusedHeapIter> FocusedHeapIter for PostOrderIterator<Iter> { + #[inline(always)] + fn focus(&self) -> usize { + self.focus + } +} + +impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> { + /* return true if the term at heap offset idx_loc is a + * direct/inlined subterm of a structure at the focus of + * self.stack.last(). this function is used to determine, e.g., + * ownership of inlined code indices. + */ + #[inline] + pub(crate) fn direct_subterm_of_str(&self, idx_loc: usize) -> bool { + if let Some((_child_count, item, focus)) = self.parent_stack.last() { + read_heap_cell!(item, + (HeapCellValueTag::Atom, (_name, arity)) => { + return focus + arity >= idx_loc && *focus < idx_loc; + } + _ => {} + ); + } + + false + } +} + pub(crate) type LeftistPostOrderHeapIter<'a> = PostOrderIterator<StackfulPreOrderHeapIter<'a>>; impl<'a> LeftistPostOrderHeapIter<'a> { #[inline] pub fn pop_stack(&mut self) { - if let Some((child_count, _)) = self.parent_stack.last() { + if let Some((child_count, ..)) = self.parent_stack.last() { for _ in 0 .. *child_count { self.base_iter.pop_stack(); } diff --git a/src/heap_print.rs b/src/heap_print.rs index 41d2b809..54f52cd6 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -1,6 +1,5 @@ use crate::arena::*; use crate::atom_table::*; -use crate::instructions::*; use crate::parser::ast::*; use crate::parser::rug::{Integer, Rational}; use crate::{ @@ -377,9 +376,9 @@ impl HCValueOutputter for PrinterOutputter { } } -#[inline] -fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool { - arity == 1 && ct.name() == atom!("$VAR") +#[inline(always)] +fn is_numbered_var(name: Atom, arity: usize) -> bool { + arity == 1 && name == atom!("$VAR") } #[inline] @@ -469,7 +468,6 @@ pub fn fmt_float(mut fl: f64) -> String { pub struct HCPrinter<'a, Outputter> { outputter: Outputter, iter: StackfulPreOrderHeapIter<'a>, - arena: &'a mut Arena, op_dir: &'a OpDir, state_stack: Vec<TokenOrRedirect>, toplevel_spec: Option<DirectedOp>, @@ -534,7 +532,6 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option<String> impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { pub fn new( heap: &'a mut Heap, - arena: &'a mut Arena, op_dir: &'a OpDir, output: Outputter, cell: HeapCellValue, @@ -542,7 +539,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { HCPrinter { outputter: output, iter: stackful_preorder_iter(heap, cell), - arena, op_dir, state_stack: vec![], toplevel_spec: None, @@ -563,9 +559,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { requires_space(tail, atom) } - fn enqueue_op(&mut self, mut max_depth: usize, ct: ClauseType, spec: OpDesc) { - let name = ct.name(); - + fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) { if is_postfix!(spec.get_spec()) { if self.check_max_depth(&mut max_depth) { self.iter.pop_stack(); @@ -652,25 +646,30 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { self.iter.pop_stack(); } - self.state_stack.push(TokenOrRedirect::Close); - self.state_stack.push(TokenOrRedirect::Atom(atom!("..."))); - self.state_stack.push(TokenOrRedirect::Open); + if arity > 0 { + self.state_stack.push(TokenOrRedirect::Close); + self.state_stack.push(TokenOrRedirect::Atom(atom!("..."))); + self.state_stack.push(TokenOrRedirect::Open); + } self.state_stack.push(TokenOrRedirect::Atom(name)); return false; } - self.state_stack.push(TokenOrRedirect::Close); + if arity > 0 { + self.state_stack.push(TokenOrRedirect::Close); + + for _ in 0..arity { + self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); + self.state_stack.push(TokenOrRedirect::Comma); + } - for _ in 0..arity { - self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); - self.state_stack.push(TokenOrRedirect::Comma); - } + self.state_stack.pop(); - self.state_stack.pop(); + self.state_stack.push(TokenOrRedirect::Open); + } - self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Atom(name)); true @@ -767,17 +766,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { &mut self, max_depth: usize, arity: usize, - ct: ClauseType, + name: Atom, op_desc: Option<OpDesc>, ) -> bool { - if self.numbervars && is_numbered_var(&ct, arity) { + if self.numbervars && is_numbered_var(name, arity) { if self.format_numbered_vars() { return true; } } let dot_atom = atom!("."); - let name = ct.name(); if let Some(spec) = op_desc { if dot_atom == name && is_infix!(spec.get_spec()) { @@ -788,7 +786,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { } if !self.ignore_ops && spec.get_prec() > 0 { - self.enqueue_op(max_depth, ct, spec); + self.enqueue_op(max_depth, name, spec); return true; } } @@ -858,7 +856,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { None } var_opt => { - if is_cyclic && addr.is_compound() { + if is_cyclic && addr.is_compound(self.iter.heap) { // self-referential variables are marked "cyclic". match var_opt { Some(var) => { @@ -1333,9 +1331,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { self.state_stack.push(TokenOrRedirect::Close); } - let ct = ClauseType::from(name, arity); - - if self.format_clause(max_depth, arity, ct, Some(op_desc)) && add_brackets { + if self.format_clause(max_depth, arity, name, Some(op_desc)) && add_brackets { self.state_stack.push(TokenOrRedirect::Open); if let Some(ref op) = &op { @@ -1349,10 +1345,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { #[allow(dead_code)] fn print_tcp_listener(&mut self, tcp_listener: &TcpListener, max_depth: usize) { let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() { - ( - addr.ip(), - Number::arena_from(addr.port() as usize, self.arena), - ) + (addr.ip(), addr.port()) } else { let disconnected_atom = atom!("$disconnected_tcp_listener"); self.state_stack @@ -1371,7 +1364,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { self.state_stack.push(TokenOrRedirect::NumberFocus( max_depth, - NumberFocus::Unfocused(port), + NumberFocus::Unfocused(Number::Fixnum(Fixnum::build_with(port as i64))), None, )); self.state_stack.push(TokenOrRedirect::Comma); @@ -1382,6 +1375,31 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { } } + fn print_index_ptr(&mut self, index_ptr: IndexPtr, max_depth: usize) { + if self.format_struct(max_depth, 1, atom!("$index_ptr")) { + let atom = self.state_stack.pop().unwrap(); + + self.state_stack.pop(); + self.state_stack.pop(); + + let offset = if index_ptr.is_undefined() || index_ptr.is_dynamic_undefined() { + TokenOrRedirect::Atom(atom!("undefined")) + } else { + let idx = index_ptr.p() as i64; + + TokenOrRedirect::NumberFocus( + max_depth, + NumberFocus::Unfocused(Number::Fixnum(Fixnum::build_with(idx))), + None, + ) + }; + + self.state_stack.push(offset); + self.state_stack.push(TokenOrRedirect::Open); + self.state_stack.push(atom); + } + } + fn print_stream(&mut self, stream: Stream, max_depth: usize) { if let Some(alias) = stream.options().get_alias() { self.print_atom(alias); @@ -1439,8 +1457,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { ); } else { push_space_if_amb!(self, name.as_str(), { - let ct = ClauseType::from(name, arity); - self.format_clause(max_depth, arity, ct, None); + self.format_clause(max_depth, arity, name, None); }); } } else if fetch_op_spec(name, arity, self.op_dir).is_some() { @@ -1485,8 +1502,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { ); } else { push_space_if_amb!(self, name.as_str(), { - let ct = ClauseType::from(name, arity); - self.format_clause(max_depth, arity, ct, None); + self.format_clause(max_depth, arity, name, None); }); } } @@ -1531,10 +1547,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { self.print_stream(stream, max_depth); } (ArenaHeaderTag::OssifiedOpDir, _op_dir) => { - append_str!(self, "'$ossified_op_dir'"); + self.print_atom(atom!("$ossified_op_dir")); } (ArenaHeaderTag::Dropped, _value) => { - append_str!(self, "'$dropped_value'"); + self.print_atom(atom!("$dropped_value")); + } + (ArenaHeaderTag::IndexPtr, index_ptr) => { + self.print_index_ptr(*index_ptr, max_depth); } _ => { } @@ -1631,7 +1650,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0) @@ -1659,7 +1677,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0) @@ -1682,7 +1699,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0) @@ -1694,7 +1710,6 @@ mod tests { let mut printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0) @@ -1726,7 +1741,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0), @@ -1744,7 +1758,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0), @@ -1760,7 +1773,6 @@ mod tests { { let mut printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0) @@ -1791,7 +1803,6 @@ mod tests { { let mut printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0) @@ -1813,7 +1824,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), pstr_loc_as_cell!(0) @@ -1840,7 +1850,6 @@ mod tests { { let printer = HCPrinter::new( &mut wam.machine_st.heap, - &mut wam.machine_st.arena, &wam.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(0), diff --git a/src/http.rs b/src/http.rs new file mode 100644 index 00000000..887366f8 --- /dev/null +++ b/src/http.rs @@ -0,0 +1,25 @@ +use std::sync::Arc; +use std::convert::Infallible; + +use hyper::{Response, Request, Body}; +use tokio::sync::Mutex; +use tokio::sync::mpsc::{channel, Receiver, Sender}; + +pub struct HttpListener { + pub incoming: Receiver<HttpRequest> +} + +#[derive(Debug)] +pub struct HttpRequest { + pub request: Request<Body>, + pub response: HttpResponse, +} + +pub type HttpResponse = Sender<Response<Body>>; + +pub async fn serve_req(req: Request<Body>, tx: Arc<Mutex<Sender<HttpRequest>>>) -> Result<Response<Body>, Infallible> { + let (response_tx, mut rx) = channel(1); + let http_request = HttpRequest { request: req, response: response_tx }; + tx.lock().await.send(http_request).await.unwrap(); + Ok(rx.recv().await.unwrap()) +} diff --git a/src/indexing.rs b/src/indexing.rs index ceace331..bad75be4 100644 --- a/src/indexing.rs +++ b/src/indexing.rs @@ -1466,17 +1466,20 @@ impl<I: Indexer> CodeOffsets<I> { atom_tbl: &mut AtomTable, ) { match optimal_arg { + &Term::Clause(_, atom!("."), ref terms) if terms.len() == 2 => { + clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0); + self.index_list(index); + } + &Term::Cons(..) | &Term::Literal(_, Literal::String(_)) | &Term::PartialString(..) => { + clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0); + self.index_list(index); + } &Term::Clause(_, name, ref terms) => { clause_index_info.opt_arg_index_key = OptArgIndexKey::Structure(self.optimal_index, 0, name.clone(), terms.len()); self.index_structure(name, terms.len(), index); } - &Term::Cons(..) | &Term::Literal(_, Literal::String(_)) | &Term::PartialString(..) => { - clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0); - - self.index_list(index); - } &Term::Literal(_, constant) => { let overlapping_constants = self.index_constant(atom_tbl, constant, index); diff --git a/src/iterators.rs b/src/iterators.rs index f6ee98f2..62054b04 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -1,7 +1,6 @@ use crate::atom_table::*; use crate::forms::*; use crate::instructions::*; -use crate::machine::machine_indices::*; use crate::parser::ast::*; use std::cell::Cell; @@ -16,7 +15,7 @@ pub(crate) enum TermRef<'a> { AnonVar(Level), Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term), Literal(Level, &'a Cell<RegType>, &'a Literal), - Clause(Level, &'a Cell<RegType>, ClauseType, &'a Vec<Term>), + Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>), PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), CompleteString(Level, &'a Cell<RegType>, Atom), Var(Level, &'a Cell<VarReg>, Rc<String>), @@ -40,7 +39,7 @@ impl<'a> TermRef<'a> { pub(crate) enum TermIterState<'a> { AnonVar(Level), Literal(Level, &'a Cell<RegType>, &'a Literal), - Clause(Level, usize, &'a Cell<RegType>, ClauseType, &'a Vec<Term>), + Clause(Level, usize, &'a Cell<RegType>, Atom, &'a Vec<Term>), InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term), FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term), InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), @@ -54,8 +53,7 @@ impl<'a> TermIterState<'a> { match term { Term::AnonVar => TermIterState::AnonVar(lvl), Term::Clause(cell, name, subterms) => { - let ct = ClauseType::Named(subterms.len(), *name, CodeIndex::default()); - TermIterState::Clause(lvl, 0, cell, ct, subterms) + TermIterState::Clause(lvl, 0, cell, *name, subterms) } Term::Cons(cell, head, tail) => { TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()) @@ -105,7 +103,7 @@ impl<'a> QueryIterator<'a> { Level::Root, 0, r, - ClauseType::from(*name, terms.len()), + *name, terms, ), Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, var.clone()), @@ -118,14 +116,14 @@ impl<'a> QueryIterator<'a> { fn new(term: &'a QueryTerm) -> Self { match term { - &QueryTerm::Clause(ref cell, ClauseType::CallN(arity), ref terms, _) => { - let state = TermIterState::Clause(Level::Root, 1, cell, ClauseType::CallN(arity), terms); + &QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => { + let state = TermIterState::Clause(Level::Root, 1, cell, atom!("$call"), terms); QueryIterator { state_stack: vec![state], } } &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => { - let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms); + let state = TermIterState::Clause(Level::Root, 0, cell, ct.name(), terms); QueryIterator { state_stack: vec![state], } @@ -167,28 +165,25 @@ impl<'a> Iterator for QueryIterator<'a> { TermIterState::AnonVar(lvl) => { return Some(TermRef::AnonVar(lvl)); } - TermIterState::Clause(lvl, child_num, cell, ct, child_terms) => { + TermIterState::Clause(lvl, child_num, cell, name, child_terms) => { if child_num == child_terms.len() { - match ct { - ClauseType::CallN(_) => { + match name { + atom!("$call") if lvl == Level::Root => { self.push_subterm(Level::Shallow, &child_terms[0]); } - ClauseType::Named(..) => { + _ => { return match lvl { Level::Root => None, - lvl => Some(TermRef::Clause(lvl, cell, ct, child_terms)), + lvl => Some(TermRef::Clause(lvl, cell, name, child_terms)), } } - _ => { - return None; - } }; } else { self.state_stack.push(TermIterState::Clause( lvl, child_num + 1, cell, - ct, + name, child_terms, )); @@ -257,8 +252,7 @@ impl<'a> FactIterator<'a> { vec![TermIterState::AnonVar(Level::Root)] } Term::Clause(cell, name, terms) => { - let ct = ClauseType::from(*name, terms.len()); - vec![TermIterState::Clause(Level::Root, 0, cell, ct, terms)] + vec![TermIterState::Clause(Level::Root, 0, cell, *name, terms)] } Term::Cons(cell, head, tail) => vec![TermIterState::InitialCons( Level::Root, @@ -305,14 +299,14 @@ impl<'a> Iterator for FactIterator<'a> { TermIterState::AnonVar(lvl) => { return Some(TermRef::AnonVar(lvl)); } - TermIterState::Clause(lvl, _, cell, ct, child_terms) => { + TermIterState::Clause(lvl, _, cell, name, child_terms) => { for child_term in child_terms { self.push_subterm(lvl.child_level(), child_term); } match lvl { Level::Root if !self.iterable_root => continue, - _ => return Some(TermRef::Clause(lvl, cell, ct, child_terms)), + _ => return Some(TermRef::Clause(lvl, cell, name, child_terms)), }; } TermIterState::InitialCons(lvl, cell, head, tail) => { @@ -19,6 +19,7 @@ mod fixtures; mod forms; mod heap_iter; pub mod heap_print; +mod http; mod indexing; #[macro_use] pub mod instructions { diff --git a/src/lib/builtins.pl b/src/lib/builtins.pl index 59f214c9..1d2d0aed 100644 --- a/src/lib/builtins.pl +++ b/src/lib/builtins.pl @@ -1,7 +1,5 @@ :- module(builtins, [(=)/2, (\=)/2, (\+)/1, !/0, (',')/2, (->)/2, - (;)/2, (=..)/2, (:)/2, (:)/3, (:)/4, (:)/5, - (:)/6, (:)/7, (:)/8, (:)/9, (:)/10, (:)/11, - (:)/12, abolish/1, asserta/1, assertz/1, + (;)/2, (=..)/2, abolish/1, asserta/1, assertz/1, at_end_of_stream/0, at_end_of_stream/1, atom_chars/2, atom_codes/2, atom_concat/3, atom_length/2, bagof/3, call/1, call/2, call/3, @@ -41,81 +39,26 @@ false :- '$fail'. % Once Scryer is bootstrapped, each is replaced with a version that % uses expand_goal to pass the expanded goal along to '$call'. -call(G) :- '$call'(G). +call(_). -call(G, A) :- '$call'(G, A). +call(_, _). -call(G, A, B) :- '$call'(G, A, B). +call(_, _, _). -call(G, A, B, C) :- '$call'(G, A, B, C). +call(_, _, _, _). -call(G, A, B, C, D) :- '$call'(G, A, B, C, D). +call(_, _, _, _, _). -call(G, A, B, C, D, E) :- '$call'(G, A, B, C, D, E). +call(_, _, _, _, _, _). -call(G, A, B, C, D, E, F) :- '$call'(G, A, B, C, D, E, F). +call(_, _, _, _, _, _, _). -call(G, A, B, C, D, E, F, G) :- '$call'(G, A, B, C, D, E, F, G). +call(_, _, _, _, _, _, _, _). -call(G, A, B, C, D, E, F, G, H) :- '$call'(G, A, B, C, D, E, F, G, H). +call(_, _, _, _, _, _, _, _, _). -% dynamic module resolution. -Module : Predicate :- - ( atom(Module) -> '$module_call'(Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1) :- - ( atom(Module) -> - '$module_call'(A1, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2) :- - ( atom(Module) -> '$module_call'(A1, A2, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4, A5) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4, A5, A6) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, A9, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). - -:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) :- - ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, Module, Predicate) - ; throw(error(type_error(atom, Module), (:)/2)) - ). +:- meta_predicate catch(0, ?, 0). % flags. @@ -185,7 +128,7 @@ fail :- '$fail'. :- meta_predicate \+(0). -\+ G :- '$call'(G), !, false. +\+ G :- call(G), !, false. \+ _. @@ -195,7 +138,7 @@ _ \= _. :- meta_predicate once(0). -once(G) :- '$call'(G), !. +once(G) :- call(G), !. repeat. @@ -216,17 +159,17 @@ G1 -> G2 :- control_entry_point((G1 -> G2)). staggered_if_then(G1, G2) :- '$get_staggered_cp'(B), - '$call'(G1), + call(G1), '$set_cp'(B), - '$call'(G2). + call(G2). G1 ; G2 :- control_entry_point((G1 ; G2)). :- non_counted_backtracking staggered_sc/2. -staggered_sc(G, _) :- '$call'(G). -staggered_sc(_, G) :- '$call'(G). +staggered_sc(G, _) :- call(G). +staggered_sc(_, G) :- call(G). !. @@ -257,7 +200,7 @@ control_entry_point_(G) :- :- non_counted_backtracking cont_list_to_goal/2. cont_list_goal([Cont], Cont) :- !. -cont_list_goal(Conts, builtins:dispatch_call_list(Conts)). +cont_list_goal(Conts, '$call'(builtins:dispatch_call_list(Conts))). :- non_counted_backtracking module_qualified_cut/1. @@ -289,7 +232,7 @@ dispatch_prep(Gs, B, [Cont|Conts]) :- dispatch_prep(G2, B, IConts1), cont_list_goal(IConts0, Cont0), cont_list_goal(IConts1, Cont1), - Cont = builtins:staggered_sc(Cont0, Cont1), + Cont = '$call'(builtins:staggered_sc(Cont0, Cont1)), Conts = [] ; functor(Gs, ->, 2) -> arg(1, Gs, G1), @@ -298,10 +241,10 @@ dispatch_prep(Gs, B, [Cont|Conts]) :- dispatch_prep(G2, B, IConts2), cont_list_goal(IConts1, Cont1), cont_list_goal(IConts2, Cont2), - Cont = builtins:staggered_if_then(Cont1, Cont2), + Cont = '$call'(builtins:staggered_if_then(Cont1, Cont2)), Conts = [] ; ( Gs == ! ; module_qualified_cut(Gs) ) -> - Cont = builtins:set_cp(B), + Cont = '$call'(builtins:set_cp(B)), Conts = [] ; Cont = Gs, Conts = [] @@ -318,56 +261,56 @@ dispatch_prep(Gs, B, [Cont|Conts]) :- dispatch_call_list([]). dispatch_call_list([G1,G2,G3,G4,G5,G6,G7,G8|Gs]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)), - '$call_with_inference_counting'('$call'(G3)), - '$call_with_inference_counting'('$call'(G4)), - '$call_with_inference_counting'('$call'(G5)), - '$call_with_inference_counting'('$call'(G6)), - '$call_with_inference_counting'('$call'(G7)), - '$call_with_inference_counting'('$call'(G8)), + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)), + '$call_with_inference_counting'(call(G3)), + '$call_with_inference_counting'(call(G4)), + '$call_with_inference_counting'(call(G5)), + '$call_with_inference_counting'(call(G6)), + '$call_with_inference_counting'(call(G7)), + '$call_with_inference_counting'(call(G8)), dispatch_call_list(Gs). dispatch_call_list([G1,G2,G3,G4,G5,G6,G7]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)), - '$call_with_inference_counting'('$call'(G3)), - '$call_with_inference_counting'('$call'(G4)), - '$call_with_inference_counting'('$call'(G5)), - '$call_with_inference_counting'('$call'(G6)), - '$call_with_inference_counting'('$call'(G7)). + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)), + '$call_with_inference_counting'(call(G3)), + '$call_with_inference_counting'(call(G4)), + '$call_with_inference_counting'(call(G5)), + '$call_with_inference_counting'(call(G6)), + '$call_with_inference_counting'(call(G7)). dispatch_call_list([G1,G2,G3,G4,G5,G6]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)), - '$call_with_inference_counting'('$call'(G3)), - '$call_with_inference_counting'('$call'(G4)), - '$call_with_inference_counting'('$call'(G5)), - '$call_with_inference_counting'('$call'(G6)). + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)), + '$call_with_inference_counting'(call(G3)), + '$call_with_inference_counting'(call(G4)), + '$call_with_inference_counting'(call(G5)), + '$call_with_inference_counting'(call(G6)). dispatch_call_list([G1,G2,G3,G4,G5]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)), - '$call_with_inference_counting'('$call'(G3)), - '$call_with_inference_counting'('$call'(G4)), - '$call_with_inference_counting'('$call'(G5)). + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)), + '$call_with_inference_counting'(call(G3)), + '$call_with_inference_counting'(call(G4)), + '$call_with_inference_counting'(call(G5)). dispatch_call_list([G1,G2,G3,G4]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)), - '$call_with_inference_counting'('$call'(G3)), - '$call_with_inference_counting'('$call'(G4)). + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)), + '$call_with_inference_counting'(call(G3)), + '$call_with_inference_counting'(call(G4)). dispatch_call_list([G1,G2,G3]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)), - '$call_with_inference_counting'('$call'(G3)). + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)), + '$call_with_inference_counting'(call(G3)). dispatch_call_list([G1,G2]) :- !, - '$call_with_inference_counting'('$call'(G1)), - '$call_with_inference_counting'('$call'(G2)). + '$call_with_inference_counting'(call(G1)), + '$call_with_inference_counting'(call(G2)). dispatch_call_list([G1]) :- - '$call_with_inference_counting'('$call'(G1)). + '$call_with_inference_counting'(call(G1)). % univ. @@ -444,7 +387,7 @@ get_args([Arg|Args], Func, I0, N) :- get_args(Args, Func, I1, N). -:- meta_predicate parse_options_list(?, 0, ?, ?, ?). +:- meta_predicate parse_options_list(?, 2, ?, ?, ?). parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :- '$skip_max_list'(_, _, Options, Tail), @@ -455,7 +398,10 @@ parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :- ; Tail \== [] -> throw(error(type_error(list, Options), Stub)) % 8.11.5.3e) ), - ( lists:maplist(nonvar, Options), + ( lists:maplist('$call'(nonvar), Options), % need '$call' because + % maplist isn't + % declared as a + % meta-predicate yet catch(lists:maplist(Selector, Options, OptionPairs0), error(E, _), builtins:throw(error(E, Stub))) -> @@ -619,8 +565,6 @@ term_variables(Term, Vars) :- % exceptions. -:- meta_predicate catch(0, ?, 0). - :- non_counted_backtracking catch/3. catch(G,C,R) :- @@ -633,11 +577,12 @@ catch(G,C,R) :- catch(G,C,R,Bb) :- '$install_new_block'(NBb), - '$call_with_inference_counting'('$call'(G)), + '$call_with_inference_counting'(call(G)), end_block(Bb, NBb). catch(G,C,R,Bb) :- '$reset_block'(Bb), '$get_ball'(Ball), + '$push_ball_stack', % move ball to ball stack. handle_ball(Ball, C, R). @@ -654,9 +599,10 @@ end_block(Bb, NBb) :- handle_ball(C, C, R) :- !, - '$erase_ball', - '$call'(R). + '$pop_ball_stack', % remove ball from ball stack. + call(R). handle_ball(_, _, _) :- + '$pop_from_ball_stack', % restore ball from ball stack. '$unwind_stack'. :- non_counted_backtracking throw/1. @@ -671,7 +617,7 @@ throw(Ball) :- :- non_counted_backtracking '$iterate_find_all'/4. '$iterate_find_all'(Template, Goal, _, LhOffset) :- - '$call_with_inference_counting'('$call'(Goal)), + '$call_with_inference_counting'(call(Goal)), '$copy_to_lh'(LhOffset, Template), '$fail'. '$iterate_find_all'(_, _, Solutions, LhOffset) :- @@ -684,6 +630,12 @@ truncate_lh_to(LhLength) :- '$truncate_lh_to'(LhLength). :- meta_predicate findall(?, 0, ?). +:- non_counted_backtracking findall_cleanup/2. + +findall_cleanup(LhLength, Error) :- + truncate_lh_to(LhLength), + throw(Error). + :- non_counted_backtracking findall/3. findall(Template, Goal, Solutions) :- @@ -691,13 +643,13 @@ findall(Template, Goal, Solutions) :- '$lh_length'(LhLength), catch(builtins:'$iterate_find_all'(Template, Goal, Solutions, LhLength), Error, - ( builtins:truncate_lh_to(LhLength), builtins:throw(Error) ) + builtins:findall_cleanup(LhLength, Error) ). :- non_counted_backtracking '$iterate_find_all_diff'/5. '$iterate_find_all_diff'(Template, Goal, _, _, LhOffset) :- - '$call_with_inference_counting'('$call'(Goal)), + '$call_with_inference_counting'(call(Goal)), '$copy_to_lh'(LhOffset, Template), '$fail'. '$iterate_find_all_diff'(_, _, Solutions0, Solutions1, LhOffset) :- @@ -716,7 +668,7 @@ findall(Template, Goal, Solutions0, Solutions1) :- catch(builtins:'$iterate_find_all_diff'(Template, Goal, Solutions0, Solutions1, LhLength), Error, - ( builtins:truncate_lh_to(LhLength), builtins:throw(Error) ) + builtins:findall_cleanup(LhLength, Error) ). :- non_counted_backtracking set_difference/3. @@ -806,7 +758,8 @@ bagof(Template, Goal, Solution) :- :- non_counted_backtracking iterate_variants_and_sort/3. iterate_variants_and_sort([V-Solution0|GroupSolutions], V, Solution) :- - sort(Solution0, Solution), + sort(Solution0, Solution1), + Solution1 = Solution, ( GroupSolutions == [] -> ! ; true ). @@ -878,129 +831,35 @@ clause(H, B) :- ). -call_asserta(Head, Body, Name, Arity, Module) :- - '$clause_body_is_valid'(Body), - functor(_, Name, Arity), - '$asserta'(Head, Body, Name, Arity, Module). - - -module_asserta_clause(Head, Body, Module) :- - ( var(Head) -> - throw(error(instantiation_error, asserta/1)) - ; callable(Head), functor(Head, Name, Arity) -> - ( '$head_is_dynamic'(Module, Head) -> - call_asserta(Head, Body, Name, Arity, Module) - ; '$no_such_predicate'(Module, Head) -> - call_asserta(Head, Body, Name, Arity, Module) - ; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1)) - ) - ; throw(error(type_error(callable, Head), asserta/1)) - ). - - -asserta_clause(Head, Body) :- - ( var(Head) -> - throw(error(instantiation_error, asserta/1)) - ; callable(Head), functor(Head, Name, Arity) -> - ( Name == (:), - Arity =:= 2 -> - arg(1, Head, Module), - arg(2, Head, HeadAndBody), - ( HeadAndBody = (F :- Body1) -> - true - ; F = HeadAndBody, - Body1 = true - ), - module_asserta_clause(F, Body1, Module) - ; '$head_is_dynamic'(user, Head) -> - call_asserta(Head, Body, Name, Arity, user) - ; '$no_such_predicate'(user, Head) -> - call_asserta(Head, Body, Name, Arity, user) - ; throw(error(permission_error(modify, static_procedure, Name/Arity), - asserta/1)) - ) - ; throw(error(type_error(callable, Head), asserta/1)) - ). - - -:- meta_predicate asserta(0). +:- meta_predicate asserta(:). asserta(Clause0) :- - loader:strip_module(Clause0, Module, Clause), - ( var(Module) -> Module = user - ; true - ), - ( Clause \= (_ :- _) -> - Head = Clause, - Body = true, - module_asserta_clause(Head, Body, Module) - ; Clause = (Head :- Body) -> - module_asserta_clause(Head, Body, Module) - ). - - -module_assertz_clause(Head, Body, Module) :- - ( var(Head) -> - throw(error(instantiation_error, assertz/1)) - ; callable(Head), functor(Head, Name, Arity) -> - ( '$head_is_dynamic'(Module, Head) -> - call_assertz(Head, Body, Name, Arity, Module) - ; '$no_such_predicate'(Module, Head) -> - call_assertz(Head, Body, Name, Arity, Module) - ; throw(error(permission_error(modify, static_procedure, Name/Arity), - assertz/1)) - ) - ; throw(error(type_error(callable, Head), assertz/1)) - ). + loader:strip_subst_module(Clause0, user, Module, Clause), + iso_ext:asserta(Module, Clause). -call_assertz(Head, Body, Name, Arity, Module) :- - '$clause_body_is_valid'(Body), - functor(_, Name, Arity), - '$assertz'(Head, Body, Name, Arity, Module). +:- meta_predicate assertz(:). - -assertz_clause(Head, Body) :- - ( var(Head) -> - throw(error(instantiation_error, assertz/1)) - ; callable(Head), functor(Head, Name, Arity) -> - ( Name == (:), - Arity =:= 2 -> - arg(1, Head, Module), - arg(2, Head, HeadAndBody), - ( HeadAndBody = (F :- Body1) -> - true - ; F = HeadAndBody, - Body1 = true - ), - module_assertz_clause(F, Body1, Module) - ; '$head_is_dynamic'(user, Head) -> - call_assertz(Head, Body, Name, Arity, user) - ; '$no_such_predicate'(user, Head) -> - call_assertz(Head, Body, Name, Arity, user) - ; throw(error(permission_error(modify, static_procedure, Name/Arity), - assertz/1)) - ) - ; throw(error(type_error(callable, Head), assertz/1)) - ). +assertz(Clause0) :- + loader:strip_subst_module(Clause0, user, Module, Clause), + iso_ext:assertz(Module, Clause). -:- meta_predicate assertz(0). +:- meta_predicate retract(:). -assertz(Clause0) :- +retract(Clause0) :- loader:strip_module(Clause0, Module, Clause), - ( var(Module) -> Module = user - ; true - ), ( Clause \= (_ :- _) -> - Head = Clause, + loader:strip_module(Clause, Module, Head), + ( var(Module) -> Module = user + ; true + ), Body = true, - module_assertz_clause(Head, Body, Module) + retract_module_clause(Head, Body, Module) ; Clause = (Head :- Body) -> - module_assertz_clause(Head, Body, Module) + retract_module_clause(Head, Body, Module) ). - module_retract_clauses([Clause|Clauses0], Head, Body, Name, Arity, Module) :- functor(VarHead, Name, Arity), findall((VarHead :- VarBody), Module:'$clause'(VarHead, VarBody), Clauses1), @@ -1086,23 +945,7 @@ retract_clause(Head, Body) :- ). -:- meta_predicate retract(0). - -retract(Clause0) :- - loader:strip_module(Clause0, Module, Clause), - ( Clause \= (_ :- _) -> - loader:strip_module(Clause, Module, Head), - ( var(Module) -> Module = user - ; true - ), - Body = true, - retract_module_clause(Head, Body, Module) - ; Clause = (Head :- Body) -> - retract_module_clause(Head, Body, Module) - ). - - -:- meta_predicate retractall(0). +:- meta_predicate retractall(:). retractall(Head) :- retract_clause(Head, _), @@ -1139,7 +982,7 @@ module_abolish(Pred, Module) :- ). -:- meta_predicate abolish(0). +:- meta_predicate abolish(:). abolish(Pred) :- ( var(Pred) -> @@ -1208,7 +1051,6 @@ current_predicate(Pred) :- can_be_op_priority(Priority) :- var(Priority). can_be_op_priority(Priority) :- op_priority(Priority). - can_be_op_specifier(Spec) :- var(Spec). can_be_op_specifier(Spec) :- op_specifier(Spec). diff --git a/src/lib/charsio.pl b/src/lib/charsio.pl index 4ac7df2b..4240319d 100644 --- a/src/lib/charsio.pl +++ b/src/lib/charsio.pl @@ -251,7 +251,7 @@ chars_base64(Cs, Bs, Options) :- '$chars_base64'(Cs, Bs, Padding, Charset) ; must_be(chars, Cs), ( '$first_non_octet'(Cs, N) -> - domain_error(byte_char, N, chars_base64/3) + domain_error(octet_character, N, chars_base64/3) ; '$chars_base64'(Cs, Bs, Padding, Charset) ) ). diff --git a/src/lib/clpb.pl b/src/lib/clpb.pl index f41e2100..e2e9ce66 100644 --- a/src/lib/clpb.pl +++ b/src/lib/clpb.pl @@ -1122,6 +1122,8 @@ indomain(1). % CountAnd = 1. % == + + sat_count(Sat0, N) :- catch((parse_sat(Sat0, Sat), sat_bdd(Sat, BDD), diff --git a/src/lib/clpz.pl b/src/lib/clpz.pl index bb9ffcba..2734a683 100644 --- a/src/lib/clpz.pl +++ b/src/lib/clpz.pl @@ -123,6 +123,8 @@ :- use_module(library(si)). :- use_module(library(freeze)). :- use_module(library(arithmetic)). +:- use_module(library(debug)). +:- use_module(library(format)). % :- use_module(library(types)). @@ -194,6 +196,8 @@ type_error(Expectation, Term) :- type_error(Expectation, Term, unknown(Term)-1). +:- meta_predicate(partition(1, ?, ?, ?)). + partition(Pred, Ls0, As, Bs) :- include(Pred, Ls0, As), exclude(Pred, Ls0, Bs). @@ -214,6 +218,8 @@ partition_([X|Xs], Pred, Ls0, Es0, Gs0) :- include/3 and exclude/3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +:- meta_predicate(include(1, ?, ?)). + include(Goal, Ls0, Ls) :- include_(Ls0, Goal, Ls). @@ -226,6 +232,7 @@ include_([L|Ls0], Goal, Ls) :- include_(Ls0, Goal, Rest). +:- meta_predicate(exclude(1, ?, ?)). exclude(Goal, Ls0, Ls) :- exclude_(Ls0, Goal, Ls). @@ -2236,8 +2243,8 @@ all_distinct(Ls) :- fd_must_be_list(Ls, all_distinct(Ls)-1), maplist(fd_variable, Ls), make_propagator(pdistinct(Ls), Prop), - distinct_attach(Ls, Prop, []), - trigger_once(Prop). + new_queue(Q0), + phrase((distinct_attach(Ls, Prop, []),trigger_prop(Prop),do_queue), [Q0], _). %% nvalue(?N, +Vars). % @@ -4045,12 +4052,13 @@ trigger_props(fd_props(Gs,Bs,Os)) --> trigger_props_([]) --> []. trigger_props_([P|Ps]) --> trigger_prop(P), trigger_props_(Ps). -trigger_prop(_P) :- true. % TODO: What to do? +trigger_prop(P) :- trigger_once(P). trigger_prop(Propagator) --> { propagator_state(Propagator, State) }, ( { State == dead } -> [] ; { get_attr(State, clpz_aux, queued) } -> [] + ; { bb_get('$clpz_current_propagator', C), C == State } -> [] ; % passive %{ format("triggering: ~w\n", [Propagator]) }, { put_attr(State, clpz_aux, queued) }, @@ -4143,12 +4151,13 @@ no_reactivation(pgcc_single(_,_)). %no_reactivation(scalar_product(_,_,_,_)). activate_propagator(propagator(P,State)) --> + % { portray_clause(running(P)) }, ( State == dead -> [] ; { del_attr(State, clpz_aux) }, ( { no_reactivation(P) } -> - %b_setval('$clpz_current_propagator', State), TODO - run_propagator(P, State) - %b_setval('$clpz_current_propagator', []) + { bb_b_put('$clpz_current_propagator', State) }, + run_propagator(P, State), + { bb_b_put('$clpz_current_propagator', []) } ; run_propagator(P, State) ) ). @@ -4194,7 +4203,8 @@ queue_get_arg_(Queue, Which, Element) :- ). queue_enabled --> state(queue(_,_,_,Aux)), { \+ get_atts(Aux, +enabled(false)) }. - +disable_queue --> state(queue(_,_,_,Aux)), { put_atts(Aux, +enabled(false)) }. +enable_queue --> state(queue(_,_,_,Aux)), { put_atts(Aux, +enabled(true)) }. portray_propagator(propagator(P,_), F) :- functor(P, F, _). @@ -4389,14 +4399,14 @@ run_propagator(pdifferent(Left,Right,X,_), MState) --> run_propagator(pexclude(Left,Right,X), MState). run_propagator(pexclude(Left,Right,X), _) --> - { ( ground(X) -> - disable_queue, - exclude_fire(Left, Right, X), - enable_queue - ; true - ) }. + ( ground(X) -> + disable_queue, + exclude_fire(Left, Right, X), + enable_queue + ; true + ). -run_propagator(pdistinct(Ls), _MState) --> { distinct(Ls) }. +run_propagator(pdistinct(Ls), _MState) --> distinct(Ls). run_propagator(pnvalue(N, Vars), _MState) --> { propagate_nvalue(N, Vars) }. @@ -4430,8 +4440,8 @@ run_propagator(pgcc(Vs, _, Pairs), _) --> { gcc_global(Vs, Pairs) }. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% run_propagator(pcircuit(Vs), _MState) --> - { distinct(Vs), - propagate_circuit(Vs) }. + distinct(Vs), + { propagate_circuit(Vs) }. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -5928,12 +5938,12 @@ max_factor(L1, U1, L2, U2, Max) :- CSPs", AAAI-94, Seattle, WA, USA, pp 362--367, 1994 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -distinct_attach([], _, _). -distinct_attach([X|Xs], Prop, Right) :- +distinct_attach([], _, _) --> []. +distinct_attach([X|Xs], Prop, Right) --> ( var(X) -> - init_propagator(X, Prop), - make_propagator(pexclude(Xs,Right,X), P1), - init_propagator(X, P1), + { init_propagator(X, Prop), + make_propagator(pexclude(Xs,Right,X), P1), + init_propagator(X, P1) }, trigger_prop(P1) ; exclude_fire(Xs, Right, X) ), @@ -6102,59 +6112,26 @@ put_free(F) :- put_attr(F, free, true). free_node(F) :- get_attr(F, free, true). -del_vars_attr(Vars, Attr) :- maplist(del_attr(Attr), Vars). - -%del_attr_(Attr, Var) :- del_attr(Var, Attr). - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This needs to be spelt out. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -% del_attr_(edges, Var) :- del_attr(Var, edges). -% del_attr_(parent, Var) :- del_attr(Var, parent). -% del_attr_(g0_edges, Var) :- del_attr(Var, g0_edges). -% del_attr_(index, Var) :- del_attr(Var, index). -% del_attr_(visited, Var) :- del_attr(Var, visited). - -del_all_attrs(Var) :- - ( var(Var) -> - Atts = [clpz, - clpz_aux, - clpz_relation, - edges, - flow, - parent, - free, - g0_edges, - used, - lowlink, - value, - visited, - index, - in_stack, - clpz_gcc_vs, - clpz_gcc_num, - clpz_gcc_occurred], - maplist(remove_attr(Var), Atts) - ; true - ). - -remove_attr(Var, Attr) :- - functor(Term, Attr, 1), - put_atts(Var, -Term). - :- meta_predicate with_local_attributes(?, 0, ?). +:- dynamic(nat_copy/1). + with_local_attributes(Vars, Goal, Result) :- catch((Goal, - maplist(del_all_attrs, Vars), - % reset all attributes, only the result matters - throw(local_attributes(Result,Vars))), - local_attributes(Result,Vars), + % Create a copy where all attributes are removed. Only + % the result and its relation to Vars matters. We throw + % an exception to undo all modifications to attributes + % we made during propagation, and unify the variables + % in the thrown copy with Vars in order to get the + % intended variables in Result. + asserta(nat_copy(Vars-Result)), + retract(nat_copy(Copy)), + throw(local_attributes(Copy))), + local_attributes(Vars-Result), true). -distinct(Vars) :- - with_local_attributes(Vars, +distinct(Vars) --> + { with_local_attributes(Vars, ( difference_arcs(Vars, FreeLeft, FreeRight0), length(FreeLeft, LFL), length(FreeRight0, LFR), @@ -6165,11 +6142,16 @@ distinct(Vars) :- maplist(g_g0, FreeLeft), scc(FreeLeft, g0_successors), maplist(dfs_used, FreeRight), - phrase(distinct_goals(FreeLeft), Gs)), Gs), + phrase(distinct_goals(FreeLeft), Gs)), Gs) }, disable_queue, - maplist(call, Gs), + neq_nums(Gs), enable_queue. +neq_nums([]) --> []. +neq_nums([neq_num(V,N)|VNs]) --> + % { portray_clause(neq_num(V, N)) }, + neq_num(V, N), neq_nums(VNs). + distinct_goals([]) --> []. distinct_goals([V|Vs]) --> { get_attr(V, edges, Es) }, @@ -6184,7 +6166,7 @@ distinct_goals_([flow_to(F,To)|Es], V) --> get_attr(To, lowlink, L2), L1 =\= L2 } -> { get_attr(To, value, N) }, - [clpz:neq_num(V, N)] + [neq_num(V, N)] ; [] ), distinct_goals_(Es, V). @@ -6376,6 +6358,10 @@ exclude_fire(Left, Right, E) :- all_neq(Left, E), all_neq(Right, E). +exclude_fire(Left, Right, E) --> + all_neq(Left, E), + all_neq(Right, E). + list_contains([X|Xs], Y) :- ( X == Y -> true ; list_contains(Xs, Y) @@ -6937,6 +6923,11 @@ vs_key_min_others([V|Vs], Key, Min0, Min, Others) :- ) ). +all_neq([], _) --> []. +all_neq([X|Xs], C) --> + neq_num(X, C), + all_neq(Xs, C). + all_neq([], _). all_neq([X|Xs], C) :- neq_num(X, C), @@ -6968,8 +6959,8 @@ circuit(Vs) :- ( L =:= 1 -> true ; neq_index(Vs, 1), make_propagator(pcircuit(Vs), Prop), - distinct_attach(Vs, Prop, []), - trigger_once(Prop) + new_queue(Q0), + phrase((distinct_attach(Vs, Prop, []),trigger_prop(Prop),do_queue), [Q0], _) ). neq_index([], _). @@ -7149,10 +7140,6 @@ contribution_at(T, Task, Offset-Bs, Contribution) :- ?(Contribution) #= B*C ). -nth1(I, Es, E) :- - I0 is I-1, - nth0(I0, Es, E). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% disjoint2(+Rectangles) diff --git a/src/lib/crypto.pl b/src/lib/crypto.pl index 0ae05e5d..458283b7 100644 --- a/src/lib/crypto.pl +++ b/src/lib/crypto.pl @@ -65,8 +65,7 @@ hex_bytes(Hs, Bytes) :- ( ground(Hs) -> - must_be(list, Hs), - maplist(must_be(atom), Hs), + must_be(chars, Hs), ( phrase(hex_bytes(Hs), Bytes) -> true ; domain_error(hex_encoding, Hs, hex_bytes/2) @@ -104,10 +103,10 @@ must_be_bytes(Bytes, Context) :- ). -must_be_byte_chars(Chars, Context) :- +must_be_octet_chars(Chars, Context) :- must_be(chars, Chars), ( '$first_non_octet'(Chars, F) -> - domain_error(byte_char, F, Context) + domain_error(octet_character, F, Context) ; true ). @@ -611,7 +610,7 @@ encoding_chars(octet, Bs, Cs) :- maplist(char_code, Cs, Bs) ; Bs = Cs ), - must_be_byte_chars(Cs, crypto_encoding). + must_be_octet_chars(Cs, crypto_encoding). encoding_chars(utf8, Cs, Cs) :- must_be(chars, Cs). @@ -652,17 +651,17 @@ ed25519_new_keypair(Pair) :- '$ed25519_new_keypair'(Pair). ed25519_keypair_public_key(Pair, PublicKey) :- - must_be_byte_chars(Pair, ed25519_keypair_public_key), + must_be_octet_chars(Pair, ed25519_keypair_public_key), '$ed25519_keypair_public_key'(Pair, PublicKey). ed25519_sign(Key, Data0, Signature, Options) :- - must_be_byte_chars(Key, ed25519_sign), + must_be_octet_chars(Key, ed25519_sign), options_data_chars(Options, Data0, Data, Encoding), '$ed25519_sign'(Key, Data, Encoding, Signature0), hex_bytes(Signature, Signature0). ed25519_verify(Key, Data0, Signature0, Options) :- - must_be_byte_chars(Key, ed25519_verify), + must_be_octet_chars(Key, ed25519_verify), options_data_chars(Options, Data0, Data, Encoding), hex_bytes(Signature0, Signature), '$ed25519_verify'(Key, Data, Encoding, Signature). @@ -714,12 +713,17 @@ curve25519_scalar_mult(Scalar, Point, Result) :- '$curve25519_scalar_mult'(ScalarBytes, PointBytes, Result). bytes_integer(Bs, N) :- - foldl(pow, Bs, 0-0, N-_). + foldl(pow, Bs, t(0,0,N), t(N,_,_)). -pow(B, N0-I0, N-I) :- +pow(B, t(N0,P0,I0), t(N,P,I)) :- + ( integer(I0) -> + B #= I0 mod 256, + I #= I0 >> 8 + ; true + ), B in 0..255, - N #= N0 + B*256^I0, - I #= I0 + 1. + N #= N0 + B*256^P0, + P #= P0 + 1. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Operations on Elliptic Curves @@ -762,11 +766,15 @@ crypto_curve_scalar_mult(Curve, Scalar, point(X,Y), point(RX, RY)) :- 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). + phrase(format_("04~|~`0t~16r~*+~`0t~16r~*+", [X,L,Y,L]), PointHex), + hex_bytes(PointHex, PointBytes), + once(bytes_integer(ScalarBytes, Scalar)), + '$crypto_curve_scalar_mult'(Name, ScalarBytes, PointBytes, [_|Us]), + maplist(char_code, Us, Bs), + length(XBs, 32), + append(XBs, YBs, Bs), + maplist(reverse, [XBs,YBs], RBs), + maplist(bytes_integer, RBs, [RX,RY]). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ?- crypto_name_curve(secp256k1, Curve), @@ -818,16 +826,6 @@ fitting_exponent(N, E0, E) :- fitting_exponent(N, E1, E) ). -crypto_name_curve(secp112r1, - curve(secp112r1, - 0x00db7c2abf62e35e668076bead208b, - 0x00db7c2abf62e35e668076bead2088, - 0x659ef8ba043916eede8911702b22, - point(0x09487239995a5ee76b55f9c2f098, - 0xa89ce5af8724c0a23e0e0ff77500), - 0x00db7c2abf62e35e7628dfac6561c5, - 14, - 1)). crypto_name_curve(secp256k1, curve(secp256k1, 0x00fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f, diff --git a/src/lib/dcgs.pl b/src/lib/dcgs.pl index 0c30447a..77eb2f5e 100644 --- a/src/lib/dcgs.pl +++ b/src/lib/dcgs.pl @@ -12,16 +12,6 @@ :- use_module(library(lists), [append/3, member/2]). :- use_module(library(loader), [strip_module/3]). -load_context(GRBody, Module, GRBody0) :- - strip_module(GRBody, Module, GRBody0), - ( nonvar(Module) -> - true - ; prolog_load_context(module, Module) -> - true - ; true - ). - - :- meta_predicate phrase(2, ?). :- meta_predicate phrase(2, ?, ?). @@ -30,12 +20,14 @@ phrase(GRBody, S0) :- phrase(GRBody, S0, []). phrase(GRBody, S0, S) :- - load_context(GRBody, Module, GRBody0), - ( var(GRBody0) -> + strip_module(GRBody, M, GRBody1), + ( var(GRBody) -> instantiation_error(phrase/3) - ; dcg_body(GRBody0, S0, S, GRBody1, Module) -> - call(GRBody1) - ; type_error(callable, GRBody0, phrase/3) + ; nonvar(GRBody1), + dcg_constr(GRBody1), + dcg_body(GRBody1, S0, S, GRBody2) -> + call(M:GRBody2) + ; call(M:GRBody1, S0, S) ). @@ -48,25 +40,25 @@ module_call_qualified(M, Call, Call1) :- % The same version of the below two dcg_rule clauses, but with module scoping. dcg_rule(( M:NonTerminal, Terminals --> GRBody ), ( M:Head :- Body )) :- dcg_non_terminal(NonTerminal, S0, S, Head), - dcg_body(GRBody, S0, S1, Goal1, _), + dcg_body(GRBody, S0, S1, Goal1), dcg_terminals(Terminals, S, S1, Goal2), Body = ( Goal1, Goal2 ). dcg_rule(( M:NonTerminal --> GRBody ), ( M:Head :- Body )) :- NonTerminal \= ( _, _ ), dcg_non_terminal(NonTerminal, S0, S, Head), - dcg_body(GRBody, S0, S, Body, _). + dcg_body(GRBody, S0, S, Body). % This program uses append/3 as defined in the Prolog prologue. % Expands a DCG rule into a Prolog rule, when no error condition applies. dcg_rule(( NonTerminal, Terminals --> GRBody ), ( Head :- Body )) :- dcg_non_terminal(NonTerminal, S0, S, Head), - dcg_body(GRBody, S0, S1, Goal1, _), + dcg_body(GRBody, S0, S1, Goal1), dcg_terminals(Terminals, S, S1, Goal2), Body = ( Goal1, Goal2 ). dcg_rule(( NonTerminal --> GRBody ), ( Head :- Body )) :- NonTerminal \= ( _, _ ), dcg_non_terminal(NonTerminal, S0, S, Head), - dcg_body(GRBody, S0, S, Body, _). + dcg_body(GRBody, S0, S, Body). dcg_non_terminal(NonTerminal, S0, S, Goal) :- NonTerminal =.. NonTerminalUniv, @@ -76,21 +68,21 @@ dcg_non_terminal(NonTerminal, S0, S, Goal) :- dcg_terminals(Terminals, S0, S, S0 = List) :- append(Terminals, S, List). -dcg_body(Var, S0, S, Body, M) :- +dcg_body(Var, S0, S, Body) :- var(Var), - module_call_qualified(M, Var, Var1), - Body = phrase(Var1, S0, S). -dcg_body(GRBody, S0, S, Body, M) :- + Body = phrase(Var, S0, S). +dcg_body(GRBody, S0, S, Body) :- nonvar(GRBody), dcg_constr(GRBody), - dcg_cbody(GRBody, S0, S, Body, M). -dcg_body(NonTerminal, S0, S, Goal1, M) :- + dcg_cbody(GRBody, S0, S, Body). +dcg_body(NonTerminal, S0, S, Goal1) :- nonvar(NonTerminal), \+ dcg_constr(NonTerminal), NonTerminal \= ( _ -> _ ), NonTerminal \= ( \+ _ ), - module_call_qualified(M, Goal, Goal1), - dcg_non_terminal(NonTerminal, S0, S, Goal). + loader:strip_module(NonTerminal, M, NonTerminal0), + dcg_non_terminal(NonTerminal0, S0, S, Goal0), + module_call_qualified(M, Goal0, Goal1). % The following constructs in a grammar rule body % are defined in the corresponding subclauses. @@ -108,42 +100,44 @@ dcg_constr((_->_)). % 7.14.12 - if-then (existence implementation dep.) % The principal functor of the first argument indicates % the construct to be expanded. -dcg_cbody([], S0, S, S0 = S, _M). -dcg_cbody([T|Ts], S0, S, Goal, _M) :- +dcg_cbody([], S0, S, S0 = S). +dcg_cbody([T|Ts], S0, S, Goal) :- must_be(list, [T|Ts]), dcg_terminals([T|Ts], S0, S, Goal). -dcg_cbody(( GRFirst, GRSecond ), S0, S, ( First, Second ), M) :- - dcg_body(GRFirst, S0, S1, First, M), - dcg_body(GRSecond, S1, S, Second, M). -dcg_cbody(( GREither ; GROr ), S0, S, ( Either ; Or ), M) :- +dcg_cbody(( GRFirst, GRSecond ), S0, S, ( First, Second )) :- + dcg_body(GRFirst, S0, S1, First), + dcg_body(GRSecond, S1, S, Second). +dcg_cbody(( GREither ; GROr ), S0, S, ( Either ; Or )) :- \+ subsumes_term(( _ -> _ ), GREither), - dcg_body(GREither, S0, S, Either, M), - dcg_body(GROr, S0, S, Or, M). -dcg_cbody(( GRCond ; GRElse ), S0, S, ( Cond ; Else ), M) :- + dcg_body(GREither, S0, S, Either), + dcg_body(GROr, S0, S, Or). +dcg_cbody(( GRCond ; GRElse ), S0, S, ( Cond ; Else )) :- subsumes_term(( _GRIf -> _GRThen ), GRCond), - dcg_cbody(GRCond, S0, S, Cond, M), - dcg_body(GRElse, S0, S, Else, M). -dcg_cbody(( GREither '|' GROr ), S0, S, ( Either ; Or ), M) :- - dcg_body(GREither, S0, S, Either, M), - dcg_body(GROr, S0, S, Or, M). -dcg_cbody({Goal}, S0, S, ( Goal1, S0 = S ), M) :- - module_call_qualified(M, Goal, Goal1). -dcg_cbody(call(Cont), S0, S, call(Cont1, S0, S), M) :- - module_call_qualified(M, Cont, Cont1). -dcg_cbody(phrase(Body), S0, S, phrase(Body1, S0, S), M) :- - module_call_qualified(M, Body, Body1). -dcg_cbody(!, S0, S, ( !, S0 = S ), _M). -dcg_cbody(\+ GRBody, S0, S, ( \+ phrase(GRBody1,S0,_), S0 = S ), M) :- - module_call_qualified(M, GRBody, GRBody1). -dcg_cbody(( GRIf -> GRThen ), S0, S, ( If -> Then ), M) :- - dcg_body(GRIf, S0, S1, If, M), - dcg_body(GRThen, S1, S, Then, M). + dcg_cbody(GRCond, S0, S, Cond), + dcg_body(GRElse, S0, S, Else). +dcg_cbody(( GREither '|' GROr ), S0, S, ( Either ; Or )) :- + dcg_body(GREither, S0, S, Either), + dcg_body(GROr, S0, S, Or). +dcg_cbody({Goal}, S0, S, ( Goal, S0 = S )). +dcg_cbody(call(Cont), S0, S, call(Cont, S0, S)). +dcg_cbody(phrase(Body), S0, S, phrase(Body, S0, S)). +dcg_cbody(!, S0, S, ( !, S0 = S )). +dcg_cbody(\+ GRBody, S0, S, ( \+ phrase(GRBody,S0,_), S0 = S )). +dcg_cbody(( GRIf -> GRThen ), S0, S, ( If -> Then )) :- + dcg_body(GRIf, S0, S1, If), + dcg_body(GRThen, S1, S, Then). user:term_expansion(Term0, Term) :- nonvar(Term0), dcg_rule(Term0, Term). % Describes a sequence +seq(Xs, Cs0,Cs) :- + var(Xs), + Cs0 == [], + !, + Xs = [], + Cs0 = Cs. seq([]) --> []. seq([E|Es]) --> [E], seq(Es). @@ -152,19 +146,23 @@ seqq([]) --> []. seqq([Es|Ess]) --> seq(Es), seqq(Ess). % Describes an arbitrary number of elements +...(Cs0,Cs) :- + Cs0 == [], + !, + Cs0 = Cs. ... --> [] | [_], ... . - error_goal(error(E, must_be/2), error(E, must_be/2)). error_goal(error(E, (=..)/2), error(E, (=..)/2)). error_goal(E, _) :- throw(E). -user:goal_expansion(phrase(GRBody, S, S0), GRBody1) :- - load_context(GRBody, M, GRBody0), +user:goal_expansion(phrase(GRBody, S, S0), GRBody2) :- + loader:strip_module(GRBody, M, GRBody0), nonvar(GRBody0), - catch(dcgs:dcg_body(GRBody0, S, S0, GRBody1, M), + catch(dcgs:dcg_body(GRBody0, S, S0, GRBody1), E, dcgs:error_goal(E, GRBody1) - ). + ), + module_call_qualified(M, GRBody1, GRBody2). user:goal_expansion(phrase(GRBody, S), phrase(GRBody, S, [])). diff --git a/src/lib/error.pl b/src/lib/error.pl index 08919d51..7efb170e 100644 --- a/src/lib/error.pl +++ b/src/lib/error.pl @@ -10,6 +10,10 @@ type_error/3 ]). + +:- meta_predicate check_(1, ?, ?). + + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - must_be(Type, Term) @@ -31,6 +35,8 @@ - in_character - integer - list + - octet_character + - octet_chars - term - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -46,6 +52,11 @@ must_be_(var, Term) :- ; throw(error(uninstantiation_error(Term), must_be/2)) ). must_be_(integer, Term) :- check_(integer, integer, Term). +must_be_(not_less_than_zero, N) :- + must_be(integer, N), + ( N >= 0 -> true + ; domain_error(not_less_than_zero, N, must_be/2) + ). must_be_(atom, Term) :- check_(atom, atom, Term). must_be_(character, T) :- check_(error:character, character, T). must_be_(in_character, T) :- check_(error:in_character, in_character, T). @@ -59,6 +70,17 @@ must_be_(chars, Ls) :- true ; all_characters(Ls) ). +must_be_(octet_character, C) :- + must_be(character, C), + ( octet_character(C) -> true + ; domain_error(octet_character, C, must_be/2) + ). +must_be_(octet_chars, Cs) :- + must_be(chars, Cs), + ( '$first_non_octet'(Cs, C) -> + domain_error(octet_character, C, must_be/2) + ; true + ). must_be_(list, Term) :- check_(error:ilist, list, Term). must_be_(type, Term) :- check_(error:type, type, Term). must_be_(boolean, Term) :- check_(error:boolean, boolean, Term). @@ -90,6 +112,10 @@ character(C) :- atom(C), atom_length(C, 1). +octet_character(C) :- + char_code(C, Code), + 0 =< Code, Code =< 0xff. + in_character(C) :- ( character(C) ; C == end_of_file @@ -107,11 +133,14 @@ type(integer). type(atom). type(character). type(in_character). +type(octet_character). +type(octet_chars). type(chars). type(list). type(var). type(boolean). type(term). +type(not_less_than_zero). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - can_be(Type, Term) @@ -135,6 +164,13 @@ can_be(Type, Term) :- ). can_(integer, Term) :- integer(Term). +can_(not_less_than_zero, N) :- + ( integer(N) -> + ( N >= 0 -> true + ; domain_error(not_less_than_zero, N, can_be/2) + ) + ; type_error(integer, N, can_be/2) + ). can_(atom, Term) :- atom(Term). can_(character, T) :- character(T). can_(in_character, T) :- in_character(T). @@ -143,6 +179,17 @@ can_(chars, Ls) :- ; can_be(list, Ls), can_be_chars(Ls) ). +can_(octet_character, C) :- + ( octet_character(C) -> true + ; domain_error(octet_character, C, can_be/2) + ). +can_(octet_chars, Cs) :- + can_be(chars, Cs), + ( '$skip_max_list'(_, _, Cs, []), % temporarily turn Cs into a list + '$first_non_octet'(Cs, C) -> + domain_error(octet_character, C, can_be/2) + ; true + ). can_(list, Term) :- list_or_partial_list(Term). can_(boolean, Term) :- boolean(Term). can_(term, Term) :- diff --git a/src/lib/files.pl b/src/lib/files.pl index f0bdaafb..ef73e851 100644 --- a/src/lib/files.pl +++ b/src/lib/files.pl @@ -1,5 +1,5 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written June 2020 by Markus Triska (triska@metalevel.at) + Written 2020, 2022 by Markus Triska (triska@metalevel.at) Part of Scryer Prolog. Predicates for reasoning about files and directories. @@ -65,6 +65,7 @@ :- use_module(library(error)). :- use_module(library(lists)). :- use_module(library(charsio)). +:- use_module(library(dcgs)). directory_files(Directory, Files) :- must_be(chars, Directory), @@ -73,7 +74,6 @@ directory_files(Directory, Files) :- file_size(File, Size) :- file_must_exist(File, file_size/2), - must_be(chars, File), can_be(integer, Size), '$file_size'(File, Size). @@ -95,12 +95,10 @@ make_directory_path(Directory) :- delete_file(File) :- file_must_exist(File, delete_file/1), - must_be(chars, File), '$delete_file'(File). rename_file(File, Renamed) :- file_must_exist(File, rename_file/2), - must_be(chars, File), must_be(chars, Renamed), '$rename_file'(File, Renamed). @@ -201,19 +199,19 @@ path_segments(Path, Segments) :- ( var(Path) -> must_be(list, Segments), maplist(must_be(chars), Segments), - append_with_separator(Segments, Sep, Path) + phrase(append_with_separator(Segments, Sep), Path) ; must_be(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([], _) --> []. +append_with_separator([Segment|Segments], Sep) --> + append_with_separator_(Segments, Segment, Sep). -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). +append_with_separator_([], Segment, _) --> seq(Segment). +append_with_separator_([Segment|Segments], Prev, Sep) --> + seq(Prev), [Sep], + append_with_separator_(Segments, Segment, Sep). path_to_segments(Path, Sep, Segments) :- ( append(Front, [Sep|Ps], Path) -> diff --git a/src/lib/freeze.pl b/src/lib/freeze.pl index c005672f..b9f8005d 100644 --- a/src/lib/freeze.pl +++ b/src/lib/freeze.pl @@ -3,7 +3,7 @@ :- use_module(library(atts)). :- use_module(library(dcgs)). -:- meta_predicate freeze(?, 0). +:- meta_predicate freeze(-, 0). :- attribute frozen/1. diff --git a/src/lib/http/http_server.pl b/src/lib/http/http_server.pl index 72657c35..0f467fd4 100644 --- a/src/lib/http/http_server.pl +++ b/src/lib/http/http_server.pl @@ -1,11 +1,11 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written in December 2020 by Adrián Arroyo (adrian.arroyocalle@gmail.com) + Updated in March 2022 by Adrián Arroyo to use the Hyper backend Part of Scryer Prolog This library provides an starting point to build HTTP server based applications. - It currently implements a subset of HTTP/1.0. It is recommended to put a reverse - proxy like nginx in front of this server to have access to more advanced features - (gzip compression, HTTPS, ...) + It is based on Hyper, which allows for HTTP/1.0, HTTP/1.1 and HTTP/2. However, + some advanced features that Hyper provides are still not accesible. Usage ========== @@ -41,37 +41,36 @@ Some things that are still missing: - Read forms in multipart format - HTTP Basic Auth - - Keep-Alive support - Session handling via cookies - HTML Templating I place this code in the public domain. Use it in any way you want. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + :- module(http_server, [ - http_listen/2, - http_headers/2, - http_status_code/2, - http_body/2, - http_redirect/2, - http_query/3, - url_decode//1 + http_listen/2, + http_headers/2, + http_status_code/2, + http_body/2, + http_redirect/2, + http_query/3 ]). -:- meta_predicate http_listen(?, 2). +:- meta_predicate http_listen(?, :). -:- use_module(library(sockets)). -:- use_module(library(dcgs)). -:- use_module(library(format)). -:- use_module(library(error)). :- use_module(library(charsio)). -:- use_module(library(lists)). +:- use_module(library(crypto)). +:- use_module(library(error)). +:- use_module(library(format)). :- use_module(library(iso_ext)). +:- use_module(library(lists)). +:- use_module(library(pio)). :- use_module(library(time)). -:- use_module(library(crypto)). -% Module prefix workaround with meta_predicate http_listen(Port, Module:Handlers0) :- + must_be(integer, Port), + must_be(list, Handlers0), maplist(module_qualification(Module), Handlers0, Handlers), http_listen_(Port, Handlers). @@ -79,49 +78,84 @@ module_qualification(M, H0, H) :- H0 =.. [Method, Path, Goal], H =.. [Method, Path, M:Goal]. -% Server initialization http_listen_(Port, Handlers) :- - must_be(integer, Port), - must_be(list, Handlers), - once(socket_server_open(Port, Socket)), - format("Listening at port ~d\n", [Port]), - accept_loop(Socket, Handlers). - -% Server loop -accept_loop(Socket, Handlers) :- - setup_call_cleanup(socket_server_accept(Socket, _Client, Stream, [type(binary)]), - ( - read_header_lines(Stream, Lines), - [Request|Headers] = Lines, - ( - (phrase(parse_request(_Version, Method, Path, Queries), Request), maplist(map_parse_header, Headers, HeadersKV)) -> ( - ( - member("content-length"-ContentLength, HeadersKV) -> - (number_chars(ContentLengthN, ContentLength), get_bytes(Stream, ContentLengthN, Body)) - ;true - ), - current_time(Time), - phrase(format_time("%Y-%m-%d (%H:%M:%S)", Time), TimeString), - format("~s ~w ~s\n", [TimeString, Method, Path]), - ( - match_handler(Handlers, Method, Path, Handler) -> - ( - HttpRequest = http_request(HeadersKV, binary(Body), Queries), - HttpResponse = http_response(_, _, _), - (call(Handler, HttpRequest, HttpResponse) -> - send_response(Stream, HttpResponse) - ; format(Stream, "HTTP/1.0 500 Internal Server Error\r\n\r\n", []) - ) - ) - ; format(Stream, "HTTP/1.0 404 Not Found\r\n\r\n", []) - ) - );( - format(Stream, "HTTP/1.0 400 Bad Request\r\n\r\n", []) % bad format - ) - ), - ! % Remove - ), close(Stream)), - accept_loop(Socket, Handlers). + phrase(format_("0.0.0.0:~d", [Port]), Addr), + '$http_listen'(Addr, HttpListener),!, + format("Listening at ~s\n", [Addr]), + http_loop(HttpListener, Handlers). + +http_loop(HttpListener, Handlers) :- + '$http_accept'(HttpListener, RequestMethod, RequestPath, RequestHeaders, RequestQuery, RequestStream, ResponseHandle), + current_time(Time), + phrase(format_time("%Y-%m-%d (%H:%M:%S)", Time), TimeString), + format("~s ~w ~s\n", [TimeString, RequestMethod, RequestPath]), + maplist(map_header_kv, RequestHeaders, RequestHeadersKV), + phrase(parse_queries(RequestQueries), RequestQuery), + ( + match_handler(Handlers, RequestMethod, RequestPath, Handler) -> + ( + HttpRequest = http_request(RequestHeadersKV, stream(RequestStream), RequestQueries), + HttpResponse = http_response(_, _, _), + (call(Handler, HttpRequest, HttpResponse) -> + send_response(ResponseHandle, HttpResponse) + ; ( + '$http_answer'(ResponseHandle, 500, [], ResponseStream), + call_cleanup(format(ResponseStream, "Internal Server Error", []), close(ResponseStream))) + ) + ) + ; ( + '$http_answer'(ResponseHandle, 404, [], ResponseStream), + call_cleanup(format(ResponseStream, "Not Found"), close(ResponseStream))) + ), + http_loop(HttpListener, Handlers). + +send_response(ResponseHandle, http_response(StatusCode0, text(ResponseText), ResponseHeaders0)) :- + default(StatusCode0, 200, StatusCode), + maplist(map_header_kv_2, ResponseHeaders, ResponseHeaders0), + '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream), + call_cleanup( + format(ResponseStream, "~s", [ResponseText]), + close(ResponseStream) + ). + +send_response(ResponseHandle, http_response(StatusCode0, bytes(ResponseBytes), ResponseHeaders0)) :- + default(StatusCode0, 200, StatusCode), + maplist(map_header_kv_2, ResponseHeaders, ResponseHeaders0), + '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream), + call_cleanup( + format(ResponseStream, "~s", [ResponseBytes]), + close(ResponseStream) + ). + +send_response(ResponseHandle, http_response(StatusCode0, file(Filename), ResponseHeaders0)) :- + default(StatusCode0, 200, StatusCode), + maplist(map_header_kv_2, ResponseHeaders, ResponseHeaders0), + '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream), + call_cleanup( + setup_call_cleanup( + open(Filename, read, FileStream, [type(binary)]), + ( + get_n_chars(FileStream, _, FileCs), + format(ResponseStream, "~s", [FileCs]) + ), + close(FileStream) + ), + close(ResponseStream) + ). + + +default(Var, Default, Out) :- + (var(Var) -> Out = Default + ; Var = Out + ). + +map_header_kv(T, K-V) :- + T =.. [K0, V], + atom_chars(K0, K). + +map_header_kv_2(T, K-V) :- + atom_chars(K0, K), + T =.. [K0, V]. match_handler(Handlers, Method, "/", Handler) :- member(H, Handlers), @@ -139,27 +173,6 @@ match_handler(Handlers, Method, Path, Handler) :- var(Var), Var = Path. - -% Helper and recommended predicates - -http_headers(http_request(Headers, _, _), Headers). -http_headers(http_response(_, _, Headers), Headers). - -http_body(http_request(_, binary(ByteBody), _), text(TextBody)) :- chars_utf8bytes(TextBody, ByteBody). -http_body(http_request(Headers, binary(ByteBody), _), form(FormBody)) :- - member("content-type"-"application/x-www-form-urlencoded", Headers), - chars_utf8bytes(TextBody, ByteBody), - phrase(parse_queries(FormBody), TextBody). -http_body(http_request(_, Body, _), Body). -http_body(http_response(_, Body, _), Body). - -http_status_code(http_response(StatusCode, _, _), StatusCode). - -http_redirect(http_response(307, text("Moved Temporarily"), ["Location"-Uri]), Uri). - -http_query(http_request(_, _, Queries), Key, Value) :- member(Key-Value, Queries). - -% Route matching path(Pattern) --> { Pattern =.. Parts, @@ -183,76 +196,31 @@ path(Pattern) --> path([]) --> []. -% Send responses -send_response(Stream, http_response(StatusCode0, file(Filename), Headers)) :- - default(StatusCode0, 200, StatusCode), - format(Stream, "HTTP/1.0 ~d\r\n", [StatusCode]), - overwrite_header("connection"-"Close", Headers, Headers0), - write_headers(Stream, Headers0), - format(Stream, "\r\n", []), - setup_call_cleanup( - open(Filename, read, FileStream, [type(binary)]), - pipe_bytes(FileStream, Stream), - close(FileStream) - ). - -send_response(Stream, http_response(StatusCode0, text(TextResponse), Headers)) :- - default(StatusCode0, 200, StatusCode), - format(Stream, "HTTP/1.0 ~d\r\n", [StatusCode]), - overwrite_header("content-type"-"text/plain", Headers, Headers0), - overwrite_header("connection"-"Close", Headers0, Headers1), - write_headers(Stream, Headers1), - format(Stream, "\r\n~s", [TextResponse]). +string_without(Not, [Char|String]) --> + [Char], + { + \+ member(Char, Not) + }, + string_without(Not, String). -send_response(Stream, http_response(StatusCode0, binary(BinaryResponse), Headers)) :- - default(StatusCode0, 200, StatusCode), - format(Stream, "HTTP/1.0 ~d\r\n", [StatusCode]), - overwrite_header("connection"-"Close", Headers, Headers0), - write_headers(Stream, Headers0), - format(Stream, "\r\n", []), - put_bytes(Stream, BinaryResponse). +string_without(_, []) --> + []. -default(Var, Default, Out) :- - (var(Var) -> Out = Default - ; Var = Out - ). +http_headers(http_request(Headers, _, _), Headers). +http_headers(http_response(_, _, Headers), Headers). -header([]) --> []. -header([Key-Value|Headers]) --> - format_("~s: ~s\r\n", [Key, Value]), - header(Headers). - -write_headers(Stream, Headers) :- - phrase(header(Headers), Cs), - format(Stream, "~s", [Cs]). - -overwrite_header(Key-Value, [], [Key-Value]). -overwrite_header(Key-Value, [Header|Headers], [Header|HeadersOut]) :- - Header = Key0-_, - Key0 \= Key, - overwrite_header(Key-Value, Headers, HeadersOut). -overwrite_header(Key-Value, [Header|Headers], [NewHeader|Headers]) :- - Header = Key-_, - NewHeader = Key-Value. - -parse_request(http_version(Major, Minor), Method, Path, Queries) --> - method(Method), - " ", - parse_path(Path, Queries), - " ", - "HTTP/", - natural(Major), - ".", - natural(Minor), - "\r\n". - -parse_path(Path, Queries) --> - string_without("?", Path), - "?", - parse_queries(Queries). +http_body(http_request(_, stream(StreamBody), _), bytes(BytesBody)) :- get_n_chars(StreamBody, _, BytesBody). +http_body(http_request(_, stream(StreamBody), _), text(TextBody)) :- get_n_chars(StreamBody, _, TextBody). +http_body(http_request(Headers, stream(StreamBody), _), form(FormBody)) :- + member("content-type"-"application/x-www-form-urlencoded", Headers), + get_n_chars(StreamBody, _, TextBody), + phrase(parse_queries(FormBody), TextBody). +http_body(http_request(_, Body, _), Body). +http_body(http_response(_, Body, _), Body). -parse_path(Path, []) --> - string_without(" ", Path). +http_status_code(http_response(StatusCode, _, _), StatusCode). +http_redirect(http_response(307, text("Moved Temporarily"), ["Location"-Uri]), Uri). +http_query(http_request(_, _, Queries), Key, Value) :- member(Key-Value, Queries). parse_queries([Key-Value|Queries]) --> string_without("=", Key0), @@ -278,94 +246,9 @@ parse_queries([Key-Value]) --> phrase(url_decode(Value), Value0) }. -map_parse_header(Header, HeaderKV) :- - phrase(parse_header(HeaderKV), Header). - -parse_header(Key-Value) --> - string_without(":", Key0), - { - chars_lower(Key0, Key) - }, - ": ", - string_without("\r", Value), - "\r\n". - -method(options) --> "OPTIONS". -method(get) --> "GET". -method(head) --> "HEAD". -method(post) --> "POST". -method(put) --> "PUT". -method(delete) --> "DELETE". - -string_without(Not, [Char|String]) --> - [Char], - { - \+ member(Char, Not) - }, - string_without(Not, String). - -string_without(_, []) --> +parse_queries([]) --> []. -natural(Nat) --> - natural_(NatChars), - { - number_chars(Nat, NatChars) - }. - -natural_([Nat|Nats]) --> - [Nat], - { - char_type(Nat, decimal_digit) - }, - natural_(Nats). - -natural_([]) --> - []. - -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) - ). - -get_bytes(Stream, Length, Res) :- get_bytes(Stream, Length, [], Res). -get_bytes(Stream, Length, Acc, Res) :- - (Length > 0 -> ( - get_byte(Stream, B), - B =\= -1, - get_bytes(Stream, Length - 1, [B|Acc], Res) - ); reverse(Acc, Res)). - -put_bytes(_, []). -put_bytes(Stream, [Byte|Bytes]) :- - put_byte(Stream, Byte), - put_bytes(Stream, Bytes). - -pipe_bytes(StreamIn, StreamOut) :- - get_byte(StreamIn, Byte), - ( - Byte =\= -1 -> - ( - put_byte(StreamOut, Byte), - pipe_bytes(StreamIn, StreamOut) - ) - ; true). - -% WARNING: This only works for ASCII chars. This code can be modified to support -% Latin1 characters also but a completely different approach is needed for other -% languages. Since HTTP internals are ASCII, this is fine for this usecase. -chars_lower(Chars, Lower) :- - maplist(char_lower, Chars, Lower). -char_lower(Char, Lower) :- - char_code(Char, Code), - ((Code >= 65,Code =< 90) -> - LowerCode is Code + 32, - char_code(Lower, LowerCode) - ; Char = Lower). - % Decodes a UTF-8 URL Encoded string: RFC-1738 url_decode([Char|Chars]) --> [Char], diff --git a/src/lib/iso_ext.pl b/src/lib/iso_ext.pl index 52dbd178..26b4713c 100644 --- a/src/lib/iso_ext.pl +++ b/src/lib/iso_ext.pl @@ -1,8 +1,3 @@ -%% for builtins that are not part of the ISO standard. -%% must be loaded at the REPL with - -%% ?- use_module(library(iso_ext)). - :- module(iso_ext, [bb_b_put/2, bb_get/2, bb_put/2, @@ -14,8 +9,9 @@ partial_string_tail/2, setup_call_cleanup/3, call_nth/2, -% variant/2, - copy_term_nat/2]). + copy_term_nat/2, + asserta/2, + assertz/2]). :- use_module(library(error), [can_be/2, domain_error/3, @@ -64,7 +60,7 @@ call_cleanup(G, C) :- setup_call_cleanup(true, G, C). setup_call_cleanup(S, G, C) :- '$get_b_value'(B), - '$call_with_inference_counting'('$call'(S)), + '$call_with_inference_counting'(call(S)), '$set_cp_by_default'(B), '$get_current_block'(Bb), ( C = _:CC, @@ -80,20 +76,20 @@ setup_call_cleanup(S, G, C) :- scc_helper(C, G, Bb) :- '$get_cp'(Cp), '$install_scc_cleaner'(C, NBb), - '$call_with_inference_counting'('$call'(G)), - ( '$check_cp'(Cp) -> - '$reset_block'(Bb), - run_cleaners_without_handling(Cp) - ; true - ; '$reset_block'(NBb), - '$fail' + '$call_with_inference_counting'(call(G)), + ( '$check_cp'(Cp) -> + '$reset_block'(Bb), + run_cleaners_without_handling(Cp) + ; true + ; '$reset_block'(NBb), + '$fail' ). scc_helper(_, _, Bb) :- '$reset_block'(Bb), - '$get_ball'(Ball), - '$erase_ball', + '$push_ball_stack', run_cleaners_with_handling, - throw(Ball). + '$pop_from_ball_stack', + '$unwind_stack'. scc_helper(_, _, _) :- '$get_cp'(Cp), run_cleaners_without_handling(Cp), @@ -115,7 +111,7 @@ run_cleaners_with_handling :- run_cleaners_without_handling(Cp) :- '$get_scc_cleaner'(C), '$get_level'(B), - '$call'(C), + call(C), '$set_cp_by_default'(B), run_cleaners_without_handling(Cp). run_cleaners_without_handling(Cp) :- @@ -136,10 +132,13 @@ end_block(B, _Bb, NBb, L) :- :- non_counted_backtracking handle_ile/3. -handle_ile(B, inference_limit_exceeded(B), inference_limit_exceeded) :- !. -handle_ile(B, E, _) :- +handle_ile(B, inference_limit_exceeded(B), inference_limit_exceeded) :- + !, + '$pop_ball_stack'. +handle_ile(B, _, _) :- '$remove_call_policy_check'(B), - throw(E). + '$pop_from_ball_stack', + '$unwind_stack'. :- meta_predicate(call_with_inference_limit(0, ?, ?)). @@ -170,21 +169,21 @@ install_inference_counter(B, L, Count0) :- call_with_inference_limit(G, L, R, Bb, B) :- '$install_new_block'(NBb), '$install_inference_counter'(B, L, Count0), - '$call_with_inference_counting'('$call'(G)), + '$call_with_inference_counting'(call(G)), '$inference_level'(R, B), '$remove_inference_counter'(B, Count1), - is(Diff, L - (Count1 - Count0)), + Diff is L - (Count1 - Count0), end_block(B, Bb, NBb, Diff). call_with_inference_limit(_, _, R, Bb, B) :- '$reset_block'(Bb), '$remove_inference_counter'(B, _), ( '$get_ball'(Ball), + '$push_ball_stack', '$get_level'(Cp), '$set_cp_by_default'(Cp) ; '$remove_call_policy_check'(B), '$fail' ), - '$erase_ball', handle_ile(B, Ball, R). partial_string(String, L, L0) :- @@ -250,3 +249,17 @@ call_nth_nesting(C, ID) :- copy_term_nat(Source, Dest) :- '$copy_term_without_attr_vars'(Source, Dest). + + +asserta(Module, (Head :- Body)) :- + !, + '$asserta'(Module, Head, Body). +asserta(Module, Fact) :- + '$asserta'(Module, Fact, true). + +assertz(Module, (Head :- Body)) :- + !, + '$assertz'(Module, Head, Body). +assertz(Module, Fact) :- + '$assertz'(Module, Fact, true). + diff --git a/src/lib/lists.pl b/src/lib/lists.pl index 52f862bb..4eb204b1 100644 --- a/src/lib/lists.pl +++ b/src/lib/lists.pl @@ -1,7 +1,7 @@ :- module(lists, [member/2, select/3, append/2, append/3, foldl/4, foldl/5, memberchk/2, reverse/2, length/2, maplist/2, maplist/3, maplist/4, maplist/5, maplist/6, - maplist/7, maplist/8, maplist/9, same_length/2, nth0/3, + maplist/7, maplist/8, maplist/9, same_length/2, nth0/3, nth0/4, nth1/3, nth1/4, sum_list/2, transpose/2, list_to_set/2, list_max/2, list_min/2, permutation/2]). @@ -243,27 +243,82 @@ unify_same(E-V, Prev-Var, E-V) :- ). -nth0(N, Es, E) :- - can_be(integer, N), - can_be(list, Es), - ( integer(N) -> - nth0_index(N, Es, E) - ; nth0_search(N, Es, E) - ). - -nth0_index(0, [E|_], E) :- !. -nth0_index(N, [_|Es], E) :- - N > 0, - N1 is N - 1, - nth0_index(N1, Es, E). - -nth0_search(N, Es, E) :- - nth0_search(0, N, Es, E). - -nth0_search(N, N, [E|_], E). -nth0_search(N0, N, [_|Es], E) :- - N1 is N0 + 1, - nth0_search(N1, N, Es, E). +nth0(N, Es0, E) :- + nonvar(N), + '$skip_max_list'(Skip, N, Es0,Es1), + !, + ( Skip == N + -> Es1 = [E|_] + ; ( var(Es1) ; Es1 = [_|_] ) % a partial or infinite list + -> R is N-Skip, + skipn(R,Es1,Es2), + Es2 = [E|_] + ). +nth0(N, Es0, E) :- + can_be(not_less_than_zero, N), + Es0 = [E0|Es1], + nth0_el(0,N, E0,E, Es1). + +skipn(N0, Es0,Es) :- + N0>0, + !, % should not be necessary #1028 + N1 is N0-1, + Es0 = [_|Es1], + skipn(N1, Es1,Es). +skipn(0, Es,Es). + +nth0_el(N0,N, E0,E, Es0) :- + Es0 == [], + !, % indexing + N0 = N, + E0 = E. +nth0_el(N,N, E,E, _). +nth0_el(N0,N, _,E, [E0|Es0]) :- + N1 is N0+1, + nth0_el(N1,N, E0,E, Es0). + +nth1(N, Es0, E) :- + N \== 0, + nth0(N, [_|Es0], E), + N \== 0. + +skipn(N0, Es0,Es, Xs0,Xs) :- + N0>0, + !, % should not be necessary #1028 + N1 is N0-1, + Es0 = [E|Es1], + Xs0 = [E|Xs1], + skipn(N1, Es1,Es, Xs1,Xs). +skipn(0, Es,Es, Xs,Xs). + +nth0(N, Es0, E, Es) :- + integer(N), + N >= 0, + !, + skipn(N, Es0,Es1, Es,Es2), + Es1 = [E|Es2]. +nth0(N, Es0, E, Es) :- + can_be(not_less_than_zero, N), + Es0 = [E0|Es1], + nth0_elx(0,N, E0,E, Es1, Es). + +nth0_elx(N0,N, E0,E, Es0, Es) :- + Es0 == [], + !, + N0 = N, + E0 = E, + Es0 = Es. +nth0_elx(N,N, E,E, Es, Es). +nth0_elx(N0,N, E0,E, [E1|Es0], [E0|Es]) :- + N1 is N0+1, + nth0_elx(N1,N, E1,E, Es0, Es). + +% p.p.8.5 + +nth1(N, Es0, E, Es) :- + N \== 0, + nth0(N, [_|Es0], E, [_|Es]), + N \== 0. list_max([N|Ns], Max) :- diff --git a/src/lib/pairs.pl b/src/lib/pairs.pl index d8023856..8ed74777 100644 --- a/src/lib/pairs.pl +++ b/src/lib/pairs.pl @@ -5,7 +5,7 @@ map_list_to_pairs/3]). -:- meta_predicate map_list_to_pairs(0, ?, ?). +:- meta_predicate map_list_to_pairs(2, ?, ?). pairs_keys_values([], [], []). pairs_keys_values([A-B|ABs], [A|As], [B|Bs]) :- diff --git a/src/lib/pio.pl b/src/lib/pio.pl index db609aa6..42f641db 100644 --- a/src/lib/pio.pl +++ b/src/lib/pio.pl @@ -4,9 +4,9 @@ Our goal is to encourage the use of definite clause grammars (DCGs) for describing strings. The predicates phrase_from_file/[2,3], - phrase_to_file/2 and phrase_to_stream/2 let us apply DCGs transparently - to files and streams, and therefore decouple side-effects from - declarative descriptions. + phrase_to_file/[2,3] and phrase_to_stream/2 let us apply DCGs + transparently to files and streams, and therefore decouple side-effects + from declarative descriptions. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ :- module(pio, [phrase_from_file/2, @@ -26,6 +26,7 @@ :- meta_predicate(phrase_from_file(2, ?)). :- meta_predicate(phrase_from_file(2, ?, ?)). :- meta_predicate(phrase_to_file(2, ?)). +:- meta_predicate(phrase_to_file(2, ?, ?)). :- meta_predicate(phrase_to_stream(2, ?)). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -90,7 +91,7 @@ phrase_to_stream(GRBody, Stream) :- must_be(chars, Cs), ( stream_property(Stream, type(binary)) -> ( '$first_non_octet'(Cs, N) -> - domain_error(byte_char, N, phrase_to_stream/2) + domain_error(octet_character, N, phrase_to_stream/2) ; true ) ; true diff --git a/src/lib/reif.pl b/src/lib/reif.pl index c0e14989..0e43a897 100644 --- a/src/lib/reif.pl +++ b/src/lib/reif.pl @@ -1,6 +1,6 @@ :- module(reif, [if_/3, (=)/3, (',')/3, (;)/3, cond_t/3, dif/3, - memberd_t/3, tfilter/3, tmember/2, tmember_t/3, - tpartition/4]). + memberd_t/3, tfilter/3, tmember/2, tmember_t/3, + tpartition/4]). :- use_module(library(dif)). @@ -30,13 +30,10 @@ non(false, true). :- meta_predicate(tfilter(2, ?, ?)). -tfilter(C_2, Es, Fs) :- - i_tfilter(Es, C_2, Fs). - -i_tfilter([], _, []). -i_tfilter([E|Es], C_2, Fs0) :- +tfilter(_, [], []). +tfilter(C_2, [E|Es], Fs0) :- if_(call(C_2, E), Fs0 = [E|Fs], Fs0 = Fs), - i_tfilter(Es, C_2, Fs). + tfilter(C_2, Es, Fs). :- meta_predicate(tpartition(2, ?, ?, ?)). diff --git a/src/lib/si.pl b/src/lib/si.pl index 173e2635..d697c8a8 100644 --- a/src/lib/si.pl +++ b/src/lib/si.pl @@ -27,7 +27,8 @@ :- module(si, [atom_si/1, integer_si/1, atomic_si/1, - list_si/1]). + list_si/1, + chars_si/1]). :- use_module(library(lists)). @@ -42,6 +43,16 @@ integer_si(I) :- atomic_si(AC) :- functor(AC,_,0). -list_si(L) :- - \+ \+ length(L, _), - sort(L, _). +% list_si(L) :- +% \+ \+ length(L, _), +% sort(L, _). + +list_si(L0) :- + '$skip_max_list'(_,_, L0,L), + ( nonvar(L) -> L = [] + ; throw(error(instantiation_error, list_si/1)) + ). + +chars_si(Cs) :- + list_si(Cs), + '$is_partial_string'(Cs). diff --git a/src/lib/simplex.pl b/src/lib/simplex.pl index 9522dab6..001571a8 100644 --- a/src/lib/simplex.pl +++ b/src/lib/simplex.pl @@ -1344,10 +1344,6 @@ print_row(R) :- maplist(print_row_, R), nl. print_row_(N) :- format("~w ", [N]). -nth1(N, Es, E) :- - N1 is N - 1, - nth0(N1, Es, E). - %?- transportation([1,1], [1,1], [[1,1],[1,1]], Ms). %?- transportation([12,7,14], [3,15,9,6], [[20,50,10,60],[70,40,60,30],[40,80,70,40]], Ms). diff --git a/src/lib/tabling.pl b/src/lib/tabling.pl index 2163c791..94dd4238 100644 --- a/src/lib/tabling.pl +++ b/src/lib/tabling.pl @@ -67,7 +67,7 @@ table_and_status_for_variant(V,T,S) :- tbd_table_status(T,S). -:- meta_predicate start_tabling(?, 0). +:- meta_predicate start_tabling(?, :). start_tabling(Wrapper,Worker) :- put_new_trie_table_link, diff --git a/src/lib/terms.pl b/src/lib/terms.pl index d9f41528..af817dff 100644 --- a/src/lib/terms.pl +++ b/src/lib/terms.pl @@ -4,8 +4,8 @@ numbervars(Term, N0, N) :- catch(internal_numbervars(Term, N0, N), - error(E,Ctx), - ( ( var(Ctx) -> Ctx = numbervars/3 ; true ), throw(error(E,Ctx) ) ) ). + error(E,Ctx), + ( ( var(Ctx) -> Ctx = numbervars/3 ; true ), throw(error(E,Ctx) ) ) ). internal_numbervars(Term, N0, N) :- must_be(integer, N0), diff --git a/src/lib/xpath.pl b/src/lib/xpath.pl index 1701e424..b4d74770 100644 --- a/src/lib/xpath.pl +++ b/src/lib/xpath.pl @@ -26,22 +26,22 @@ :- use_module(library(http/http_open)). :- use_module(library(sgml)). - :- use_module(library(lists)). :- use_module(library(xpath)). + :- use_module(library(dcgs)). 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). + phrase((...,".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" - %@ ; ... + %@ File = "/mthom/scryer-prolog/blob/master/src/lib/dcgs.pl" + %@ ; File = "/mthom/scryer-prolog/blob/master/src/lib/pio.pl" + %@ ; File = "/mthom/scryer-prolog/blob/master/src/lib/tabling.pl" + %@ ; ... . Parts of the original functionality may not yet work. Please consider such parts opportunities for improvements, and file diff --git a/src/loader.pl b/src/loader.pl index 0179bd7b..fe3d6fe2 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -16,7 +16,6 @@ :- use_module(library(lists)). :- use_module(library(pairs)). - write_error(Error) :- % '$fetch_global_var' is the core system call of bb_get/2, but % bb_get may not exist when write_error is first called, so fall @@ -33,9 +32,9 @@ write_error(Error) :- ), write('.'). -'$print_message_and_fail'(inference_limit_exceeded(B)) :- - integer(B), - throw(inference_limit_exceeded(B)). +% '$print_message_and_fail'(inference_limit_exceeded(B)) :- +% integer(B), +% throw(inference_limit_exceeded(B)). '$print_message_and_fail'(Error) :- write_error(Error), nl, @@ -43,9 +42,9 @@ write_error(Error) :- expand_term(Term, ExpandedTerm) :- ( '$predicate_defined'(user, term_expansion, 2), - catch('$call'(user:term_expansion(Term, ExpandedTerm0)), + catch(user:term_expansion(Term, ExpandedTerm0), E, - '$call'(loader:'$print_message_and_fail'(E))) -> + loader:'$print_message_and_fail'(E)) -> ( var(ExpandedTerm0) -> error:instantiation_error(term_expansion/2) ; ExpandedTerm0 = [_|_] -> @@ -73,7 +72,7 @@ goal_expansion(Goal, Module, ExpandedGoal) :- '$predicate_defined'(Module, goal_expansion, 2), catch('$call'(Module:goal_expansion(Goal, ExpandedGoal0)), E, - '$call'(loader:'$print_message_and_fail'(E))) -> + loader:'$print_message_and_fail'(E)) -> ( var(ExpandedGoal0) -> error:instantiation_error(goal_expansion/2) ; goal_expansion(ExpandedGoal0, Module, ExpandedGoal) @@ -97,13 +96,14 @@ unload_evacuable(Evacuable) :- run_initialization_goals(Module) :- ( predicate_property(Module:'$initialization_goals'(_), dynamic) -> - % FIXME: failing here. also, see add_module. - findall(Module:Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals), + findall(Module:Goal, builtins:retract(Module:'$initialization_goals'(Goal)), Goals), abolish(Module:'$initialization_goals'/1), maplist(loader:success_or_warning, Goals) ; true ). +:- meta_predicate success_or_warning(0). + success_or_warning(Goal) :- ( call(Goal) -> true @@ -126,29 +126,32 @@ file_load(Stream, Path) :- false. %% Clear the heap. file_load(_, _). +file_load_init(Stream, Evacuable) :- + load_loop(Stream, Evacuable), + run_initialization_goals. + +file_load_cleanup(Evacuable, Error) :- + unload_evacuable(Evacuable), + '$print_message_and_fail'(Error), + throw(Error). + file_load(Stream, Path, Evacuable) :- create_file_load_context(Stream, Path, Evacuable), % '$add_in_situ_filename_module' removes user level predicates, % local predicate clauses, etc. from a previous load of the file % at Path. '$add_in_situ_filename_module'(Evacuable), - catch((loader:load_loop(Stream, Evacuable), - loader:run_initialization_goals), + catch(loader:file_load_init(Stream, Evacuable), E, - builtins:(loader:unload_evacuable(Evacuable), - loader:'$print_message_and_fail'(E), - builtins:throw(E))), + loader:file_load_cleanup(Evacuable, E)), '$pop_load_context'. load(Stream) :- create_load_context(Stream, Evacuable), - catch((loader:load_loop(Stream, Evacuable), - loader:run_initialization_goals), + catch(loader:file_load_init(Stream, Evacuable), E, - builtins:(loader:unload_evacuable(Evacuable), - loader:'$print_message_and_fail'(E), - builtins:throw(E))), + loader:file_load_cleanup(Evacuable, E)), '$pop_load_context', false. %% Clear the heap. load(_). @@ -214,23 +217,23 @@ compile_term(Term, Evacuable) :- ; compile_dispatch_or_clause(Terms, Evacuable) ). +complete_partial_goal(N, HeadArg, InnerHeadArgs, SuppArgs, CompleteHeadArg) :- + integer(N), + N >= 0, + HeadArg =.. [Functor | InnerHeadArgs], + length(SuppArgs, N), + append(InnerHeadArgs, SuppArgs, InnerHeadArgs0), + CompleteHeadArg =.. [Functor | InnerHeadArgs0]. inner_meta_specs(0, HeadArg, InnerHeadArgs, InnerMetaSpecs) :- !, predicate_property(HeadArg, meta_predicate(InnerMetaSpecs0)), InnerMetaSpecs0 =.. [_ | InnerMetaSpecs], HeadArg =.. [_ | InnerHeadArgs]. - inner_meta_specs((:), _, [], []) :- !. - inner_meta_specs(N, HeadArg, InnerHeadArgs, InnerMetaSpecs) :- - integer(N), - N >= 0, - HeadArg =.. [Functor | InnerHeadArgs], - length(InnerHeadArgs1, N), - append(InnerHeadArgs, InnerHeadArgs1, InnerHeadArgs0), - CompleteHeadArg =.. [Functor | InnerHeadArgs0], + complete_partial_goal(N, HeadArg, InnerHeadArgs, _, CompleteHeadArg), predicate_property(CompleteHeadArg, meta_predicate(InnerMetaSpecs0)), InnerMetaSpecs0 =.. [_ | InnerMetaSpecs]. @@ -242,7 +245,7 @@ module_expanded_head_variables_([HeadArg | HeadArgs], [MetaSpec | MetaSpecs], He MetaSpec >= 0 ) -> ( var(HeadArg) -> - HeadVars = [HeadArg-HeadArg | HeadVars1], + HeadVars = [HeadArg-MetaSpec | HeadVars1], module_expanded_head_variables_(HeadArgs, MetaSpecs, HeadVars1, HeadVars0) ; inner_meta_specs(MetaSpec, HeadArg, InnerHeadArgs, InnerMetaSpecs) -> module_expanded_head_variables_(InnerHeadArgs, InnerMetaSpecs, HeadVars, HeadVars1), @@ -518,6 +521,11 @@ path_atom(Dir/File, Path) :- path_atom(Path, Path) :- must_be(atom, Path). + +open_file_cleanup(Path, Stream) :- + atom_concat(Path, '.pl', ExtendedPath), + open(ExtendedPath, read, Stream). + % Try to open the file with the Path name as given; if that fails, % append '.pl' and try again. open_file(Path, Stream) :- @@ -525,9 +533,7 @@ open_file(Path, Stream) :- open(Path, read, Stream) ; catch(open(Path, read, Stream), error(existence_error(source_sink, _), _), - ( atom_concat(Path, '.pl', ExtendedPath), - open(ExtendedPath, read, Stream) - ) + loader:open_file_cleanup(Path, Stream) ) ). @@ -609,30 +615,67 @@ predicate_property(Callable, Property) :- strip_module(Goal, M, G) :- '$strip_module'(Goal, M, G). -:- non_counted_backtracking expand_subgoal/5. -expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :- - ( var(UnexpandedGoals) -> - UnexpandedGoals = ExpandedGoals - ; ( MS == 0 -> - % only expand complete goals. call/N will take care of incomplete goals - % by calling goal expansion after it is supplied the remaining arguments. - ( goal_expansion(UnexpandedGoals, Module, UnexpandedGoals1), - ( Module \== user -> - goal_expansion(UnexpandedGoals1, user, Goals) - ; Goals = UnexpandedGoals1 - ) - ) - ; Goals = UnexpandedGoals - ), - ( inner_meta_specs(MS, Goals, _, MetaSpecs) -> - expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars) - ; Goals = ExpandedGoals +:- non_counted_backtracking strip_subst_module/4. + +strip_subst_module(Goal, M1, M2, G) :- + '$strip_module'(Goal, M2, G), + ( var(M2) -> + M2 = M1 + ; true + ). + +:- non_counted_backtracking subgoal_expansion/3. + +/* + * subgoal_expansion differs from goal_expansion only in that it fails + * unconditionally after catching an(y) exception, aborting the + * inlining process. It is expected that goal expansion will succeed + * when expand_goal is later invoked at runtime. + */ + +subgoal_expansion_fail(B) :- + builtins:set_cp(B), + fail. + +subgoal_expansion(Goal, Module, ExpandedGoal) :- + '$get_cp'(B), + ( atom(Module), + '$predicate_defined'(Module, goal_expansion, 2), + catch('$call'(Module:goal_expansion(Goal, ExpandedGoal0)), + _E, + '$call'(loader:subgoal_expansion_fail(B)) + ), + ( var(ExpandedGoal0) -> + error:instantiation_error(goal_expansion/2) + ; '$set_cp'(B), + subgoal_expansion(ExpandedGoal0, Module, ExpandedGoal) ) - ; UnexpandedGoals = ExpandedGoals + ; Goal = ExpandedGoal ). +:- non_counted_backtracking expand_subgoal/5. + +expand_subgoal(UnexpandedGoals, MS, M, ExpandedGoals, HeadVars) :- + strip_subst_module(UnexpandedGoals, M, Module, UnexpandedGoals0), + nonvar(UnexpandedGoals0), + complete_partial_goal(MS, UnexpandedGoals0, _, SuppArgs, UnexpandedGoals1), + ( subgoal_expansion(UnexpandedGoals1, Module, UnexpandedGoals2), + ( Module \== user -> + subgoal_expansion(UnexpandedGoals2, user, UnexpandedGoals3) + ; UnexpandedGoals3 = UnexpandedGoals2 + ) + ), + strip_subst_module(UnexpandedGoals3, Module, Module1, UnexpandedGoals4), + ( inner_meta_specs(0, UnexpandedGoals4, _, MetaSpecs) -> + expand_module_names(UnexpandedGoals4, MetaSpecs, Module1, ExpandedGoals0, HeadVars) + ; ExpandedGoals0 = UnexpandedGoals4 + ), + '$compile_inline_or_expanded_goal'(ExpandedGoals0, SuppArgs, ExpandedGoals1, Module1), + expand_module_name(ExpandedGoals1, MS, Module1, ExpandedGoals). + + :- non_counted_backtracking expand_module_name/4. expand_module_name(ESG0, MS, M, ESG) :- @@ -650,27 +693,45 @@ expand_module_name(ESG0, MS, M, ESG) :- ). +:- non_counted_backtracking eq_member/2. + +eq_member(V, [L-_|Ls]) :- + V == L. +eq_member(V, [_|Ls]) :- + eq_member(V, Ls). + +:- non_counted_backtracking qualified_spec/1. + +qualified_spec((:)). +qualified_spec(MS) :- integer(MS), MS >= 0. + + :- non_counted_backtracking expand_meta_predicate_subgoals/5. expand_meta_predicate_subgoals([SG | SGs], [MS | MSs], M, [ESG | ESGs], HeadVars) :- - ( ( integer(MS), - MS >= 0 - ; MS == (:) - ) -> - ( var(SG), - pairs:same_key(SG, HeadVars, [_|_], _) -> - expand_subgoal(SG, MS, M, ESG, HeadVars) - ; expand_subgoal(SG, MS, M, ESG0, HeadVars), - expand_module_name(ESG0, MS, M, ESG) - ), - expand_meta_predicate_subgoals(SGs, MSs, M, ESGs, HeadVars) - ; ESG = SG, - expand_meta_predicate_subgoals(SGs, MSs, M, ESGs, HeadVars) - ). + ( var(SG) -> + ( qualified_spec(MS) -> + ( eq_member(SG, HeadVars) -> + ESG = SG + ; expand_module_name(SG, MS, M, ESG) + ) + ; ESG = SG + ) + ; MS == (:) -> + expand_module_name(SG, MS, M, ESG) + ; '$is_expanded_or_inlined'(SG) -> + ESG = SG + ; expand_subgoal(SG, MS, M, ESG, HeadVars) -> + true + ; integer(MS), + MS >= 0 -> + expand_module_name(SG, MS, M, ESG) + ; SG = ESG + ), + expand_meta_predicate_subgoals(SGs, MSs, M, ESGs, HeadVars). expand_meta_predicate_subgoals([], _, _, [], _). - :- non_counted_backtracking expand_module_names/5. expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars) :- @@ -684,15 +745,16 @@ expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars) :- ). + :- non_counted_backtracking expand_goal/3. expand_goal(UnexpandedGoals, Module, ExpandedGoals) :- - % if a goal isn't callable, defer to call/N to report the error. - catch('$call'(loader:expand_goal(UnexpandedGoals, Module, ExpandedGoals, [])), + catch(loader:expand_goal(UnexpandedGoals, Module, ExpandedGoals, []), error(type_error(callable, _), _), - '$call'(UnexpandedGoals = ExpandedGoals)), + UnexpandedGoals = ExpandedGoals), !. + :- non_counted_backtracking expand_goal/4. expand_goal(UnexpandedGoals, Module, ExpandedGoals, HeadVars) :- @@ -713,6 +775,41 @@ expand_goal(UnexpandedGoals, Module, ExpandedGoals, HeadVars) :- ) ). + +/* + * private predicate for use in call/N. it doesn't specially consider + * control predicates as expand_goal does with expand_goal_cases. + * HeadVars is always []. + */ + +:- non_counted_backtracking expand_call_goal/3. + +expand_call_goal(UnexpandedGoals, Module, ExpandedGoals) :- + % if a goal isn't callable, defer to call/N to report the error. + catch(loader:expand_call_goal_(UnexpandedGoals, Module, ExpandedGoals), + error(type_error(callable, _), _), + UnexpandedGoals = ExpandedGoals), + !. + + +:- non_counted_backtracking expand_call_goal_/3. + +expand_call_goal_(UnexpandedGoals, Module, ExpandedGoals) :- + ( var(UnexpandedGoals) -> + expand_module_names(call(UnexpandedGoals), [0], Module, ExpandedGoals, []) + ; goal_expansion(UnexpandedGoals, Module, UnexpandedGoals1), + ( Module \== user -> + goal_expansion(UnexpandedGoals1, user, Goals) + ; Goals = UnexpandedGoals1 + ), + ( predicate_property(Module:Goals, meta_predicate(MetaSpecs0)), + MetaSpecs0 =.. [_ | MetaSpecs] -> + expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, []) + ; thread_goals(Goals, ExpandedGoals, (',')) + ; Goals = ExpandedGoals + ) + ). + :- non_counted_backtracking expand_goal_cases/4. expand_goal_cases((Goal0, Goals0), Module, ExpandedGoals, HeadVars) :- @@ -752,6 +849,7 @@ thread_goals(Goals0, Goals1, Functor) :- ; Goals1 = Goals0 ). + :- non_counted_backtracking thread_goals/4. thread_goals(Goals0, Goals1, Hole, Functor) :- @@ -772,819 +870,1278 @@ thread_goals(Goals0, Goals1, Hole, Functor) :- % % The program used to generate the call/N predicates: % -% -% % :- use_module(library(between)). % :- use_module(library(error)). % :- use_module(library(lists)). % :- use_module(library(format)). % -% n_call_clause(N, Clause) :- +% n_call_clause(N, Clauses) :- % length(Args, N), % Head =.. [call, G | Args], +% CallNHead =.. [call, '$call'(G) | Args], % N1 is N + 1, -% CallClause0 =.. ['$prepare_call_clause', G1, M, G0 | Args], -% CallClause =.. ['$prepare_call_clause', G1, M, G | Args], -% Clause = (Head :- ( var(G) -> -% instantiation_error(call/N1) -% ; G = '$call'(G0) -> -% CallClause0, -% '$call_with_inference_counting'('$call'(M:G1)) -% ; CallClause, -% expand_goal(call(M:G1), M, call(G2)), -% '$call_with_inference_counting'('$call'(G2)) -% ) -% ). +% InlineCall =.. ['$call_inline', G0 | Args], +% CallClause =.. ['$prepare_call_clause', G1, M1, G | Args], +% ModuleCallClause0 =.. ['$module_call', M1, G1], +% ModuleCallClause1 =.. ['$module_call', M2, G3], +% Clauses = [(Head :- var(G), +% instantiation_error(call/N1)), +% (Head :- '$strip_module'(G, _, G0), InlineCall), +% (CallNHead :- !, +% CallClause, +% '$call_with_inference_counting'(ModuleCallClause0)), +% (Head :- CallClause, +% ( '$call_inline'(G1) +% ; expand_call_goal(G1, M1, G2), +% strip_subst_module(G2, M1, M2, G3), +% '$call_with_inference_counting'(ModuleCallClause1) +% ))]. % % generate_call_forms :- % between(1, 64, N), -% n_call_clause(N, Clause), +% n_call_clause(N, Clauses), % N1 is N+1, % portray_clause((:- non_counted_backtracking call/N1)), -% portray_clause(Clause), +% maplist(portray_clause, Clauses), % nl, % false. +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The '$call' functor is an escape hatch from goal expansion. So far, -% it is used only to avoid infinite recursion into expand_goal/3. +% it is used only to avoid infinite recursion into expand_call_goal/3. -:- non_counted_backtracking call/1. +:-non_counted_backtracking call/1. +call(G) :- + var(G), + instantiation_error(call/1). +call(G) :- + '$strip_module'(G, _, G0), + '$call_inline'(G0). +call('$call'(G0)) :- + !, + '$prepare_call_clause'(G,M,G0), + '$call_with_inference_counting'('$module_call'(M, G)). call(G) :- - ( var(G) -> - instantiation_error(call/1) - ; G = '$call'(G0) -> - '$prepare_call_clause'(G1, M, G0), - '$call_with_inference_counting'('$call'(M:G1)) - ; '$prepare_call_clause'(G1, M, G), - expand_goal(call(M:G1), M, call(G2)), - '$call_with_inference_counting'('$call'(G2)) + '$prepare_call_clause'(G0,M1,G), + ( '$call_inline'(G0) %% '$call_inline' cuts (only) after succeeding. + ; expand_call_goal(G0, M1, G1), + strip_subst_module(G1, M1, M2, G2), + '$call_with_inference_counting'('$module_call'(M2, G2)) ). :-non_counted_backtracking call/2. call(A,B) :- - ( var(A) -> - instantiation_error(call/2) - ; A= '$call'(C) -> - '$prepare_call_clause'(D,E,C,B), - '$call_with_inference_counting'('$call'(E:D)) - ; '$prepare_call_clause'(D,E,A,B), - expand_goal(call(E:D),E,call(F)), - '$call_with_inference_counting'('$call'(F)) + var(A), + instantiation_error(call/2). +call(A,B) :- + '$strip_module'(A,C,D), + '$call_inline'(D,B). +call('$call'(A),B) :- + !, + '$prepare_call_clause'(C,D,A,B), + '$call_with_inference_counting'('$module_call'(D,C)). +call(A,B) :- + '$prepare_call_clause'(C,D,A,B), + ( '$call_inline'(C) + ; expand_call_goal(C,D,E), + strip_subst_module(E,D,F,G), + '$call_with_inference_counting'('$module_call'(F,G)) ). :-non_counted_backtracking call/3. call(A,B,C) :- - ( var(A) -> - instantiation_error(call/3) - ; A= '$call'(D) -> - '$prepare_call_clause'(E,F,D,B,C), - '$call_with_inference_counting'('$call'(F:E)) - ; '$prepare_call_clause'(E,F,A,B,C), - expand_goal(call(F:E),F,call(G)), - '$call_with_inference_counting'('$call'(G)) + var(A), + instantiation_error(call/3). +call(A,B,C) :- + '$strip_module'(A,D,E), + '$call_inline'(E,B,C). +call('$call'(A),B,C) :- + !, + '$prepare_call_clause'(D,E,A,B,C), + '$call_with_inference_counting'('$module_call'(E,D)). +call(A,B,C) :- + '$prepare_call_clause'(D,E,A,B,C), + ( '$call_inline'(D) + ; expand_call_goal(D,E,F), + strip_subst_module(F,E,G,H), + '$call_with_inference_counting'('$module_call'(G,H)) ). :-non_counted_backtracking call/4. call(A,B,C,D) :- - ( var(A) -> - instantiation_error(call/4) - ; A= '$call'(E) -> - '$prepare_call_clause'(F,G,E,B,C,D), - '$call_with_inference_counting'('$call'(G:F)) - ; '$prepare_call_clause'(F,G,A,B,C,D), - expand_goal(call(G:F),G,call(H)), - '$call_with_inference_counting'('$call'(H)) + var(A), + instantiation_error(call/4). +call(A,B,C,D) :- + '$strip_module'(A,E,F), + '$call_inline'(F,B,C,D). +call('$call'(A),B,C,D) :- + !, + '$prepare_call_clause'(E,F,A,B,C,D), + '$call_with_inference_counting'('$module_call'(F,E)). +call(A,B,C,D) :- + '$prepare_call_clause'(E,F,A,B,C,D), + ( '$call_inline'(E) + ; expand_call_goal(E,F,G), + strip_subst_module(G,F,H,I), + '$call_with_inference_counting'('$module_call'(H,I)) ). :-non_counted_backtracking call/5. call(A,B,C,D,E) :- - ( var(A) -> - instantiation_error(call/5) - ; A= '$call'(F) -> - '$prepare_call_clause'(G,H,F,B,C,D,E), - '$call_with_inference_counting'('$call'(H:G)) - ; '$prepare_call_clause'(G,H,A,B,C,D,E), - expand_goal(call(H:G),H,call(I)), - '$call_with_inference_counting'('$call'(I)) + var(A), + instantiation_error(call/5). +call(A,B,C,D,E) :- + '$strip_module'(A,F,G), + '$call_inline'(G,B,C,D,E). +call('$call'(A),B,C,D,E) :- + !, + '$prepare_call_clause'(F,G,A,B,C,D,E), + '$call_with_inference_counting'('$module_call'(G,F)). +call(A,B,C,D,E) :- + '$prepare_call_clause'(F,G,A,B,C,D,E), + ( '$call_inline'(F) + ; expand_call_goal(F,G,H), + strip_subst_module(H,G,I,J), + '$call_with_inference_counting'('$module_call'(I,J)) ). :-non_counted_backtracking call/6. call(A,B,C,D,E,F) :- - ( var(A) -> - instantiation_error(call/6) - ; A= '$call'(G) -> - '$prepare_call_clause'(H,I,G,B,C,D,E,F), - '$call_with_inference_counting'('$call'(I:H)) - ; '$prepare_call_clause'(H,I,A,B,C,D,E,F), - expand_goal(call(I:H),I,call(J)), - '$call_with_inference_counting'('$call'(J)) + var(A), + instantiation_error(call/6). +call(A,B,C,D,E,F) :- + '$strip_module'(A,G,H), + '$call_inline'(H,B,C,D,E,F). +call('$call'(A),B,C,D,E,F) :- + !, + '$prepare_call_clause'(G,H,A,B,C,D,E,F), + '$call_with_inference_counting'('$module_call'(H,G)). +call(A,B,C,D,E,F) :- + '$prepare_call_clause'(G,H,A,B,C,D,E,F), + ( '$call_inline'(G) + ; expand_call_goal(G,H,I), + strip_subst_module(I,H,J,K), + '$call_with_inference_counting'('$module_call'(J,K)) ). :-non_counted_backtracking call/7. call(A,B,C,D,E,F,G) :- - ( var(A) -> - instantiation_error(call/7) - ; A= '$call'(H) -> - '$prepare_call_clause'(I,J,H,B,C,D,E,F,G), - '$call_with_inference_counting'('$call'(J:I)) - ; '$prepare_call_clause'(I,J,A,B,C,D,E,F,G), - expand_goal(call(J:I),J,call(K)), - '$call_with_inference_counting'('$call'(K)) + var(A), + instantiation_error(call/7). +call(A,B,C,D,E,F,G) :- + '$strip_module'(A,H,I), + '$call_inline'(I,B,C,D,E,F,G). +call('$call'(A),B,C,D,E,F,G) :- + !, + '$prepare_call_clause'(H,I,A,B,C,D,E,F,G), + '$call_with_inference_counting'('$module_call'(I,H)). +call(A,B,C,D,E,F,G) :- + '$prepare_call_clause'(H,I,A,B,C,D,E,F,G), + ( '$call_inline'(H) + ; expand_call_goal(H,I,J), + strip_subst_module(J,I,K,L), + '$call_with_inference_counting'('$module_call'(K,L)) ). :-non_counted_backtracking call/8. call(A,B,C,D,E,F,G,H) :- - ( var(A) -> - instantiation_error(call/8) - ; A= '$call'(I) -> - '$prepare_call_clause'(J,K,I,B,C,D,E,F,G,H), - '$call_with_inference_counting'('$call'(K:J)) - ; '$prepare_call_clause'(J,K,A,B,C,D,E,F,G,H), - expand_goal(call(K:J),K,call(L)), - '$call_with_inference_counting'('$call'(L)) + var(A), + instantiation_error(call/8). +call(A,B,C,D,E,F,G,H) :- + '$strip_module'(A,I,J), + '$call_inline'(J,B,C,D,E,F,G,H). +call('$call'(A),B,C,D,E,F,G,H) :- + !, + '$prepare_call_clause'(I,J,A,B,C,D,E,F,G,H), + '$call_with_inference_counting'('$module_call'(J,I)). +call(A,B,C,D,E,F,G,H) :- + '$prepare_call_clause'(I,J,A,B,C,D,E,F,G,H), + ( '$call_inline'(I) + ; expand_call_goal(I,J,K), + strip_subst_module(K,J,L,M), + '$call_with_inference_counting'('$module_call'(L,M)) ). :-non_counted_backtracking call/9. call(A,B,C,D,E,F,G,H,I) :- - ( var(A) -> - instantiation_error(call/9) - ; A= '$call'(J) -> - '$prepare_call_clause'(K,L,J,B,C,D,E,F,G,H,I), - '$call_with_inference_counting'('$call'(L:K)) - ; '$prepare_call_clause'(K,L,A,B,C,D,E,F,G,H,I), - expand_goal(call(L:K),L,call(M)), - '$call_with_inference_counting'('$call'(M)) + var(A), + instantiation_error(call/9). +call(A,B,C,D,E,F,G,H,I) :- + '$strip_module'(A,J,K), + '$call_inline'(K,B,C,D,E,F,G,H,I). +call('$call'(A),B,C,D,E,F,G,H,I) :- + !, + '$prepare_call_clause'(J,K,A,B,C,D,E,F,G,H,I), + '$call_with_inference_counting'('$module_call'(K,J)). +call(A,B,C,D,E,F,G,H,I) :- + '$prepare_call_clause'(J,K,A,B,C,D,E,F,G,H,I), + ( '$call_inline'(J) + ; expand_call_goal(J,K,L), + strip_subst_module(L,K,M,N), + '$call_with_inference_counting'('$module_call'(M,N)) ). :-non_counted_backtracking call/10. call(A,B,C,D,E,F,G,H,I,J) :- - ( var(A) -> - instantiation_error(call/10) - ; A= '$call'(K) -> - '$prepare_call_clause'(L,M,K,B,C,D,E,F,G,H,I,J), - '$call_with_inference_counting'('$call'(M:L)) - ; '$prepare_call_clause'(L,M,A,B,C,D,E,F,G,H,I,J), - expand_goal(call(M:L),M,call(N)), - '$call_with_inference_counting'('$call'(N)) + var(A), + instantiation_error(call/10). +call(A,B,C,D,E,F,G,H,I,J) :- + '$strip_module'(A,K,L), + '$call_inline'(L,B,C,D,E,F,G,H,I,J). +call('$call'(A),B,C,D,E,F,G,H,I,J) :- + !, + '$prepare_call_clause'(K,L,A,B,C,D,E,F,G,H,I,J), + '$call_with_inference_counting'('$module_call'(L,K)). +call(A,B,C,D,E,F,G,H,I,J) :- + '$prepare_call_clause'(K,L,A,B,C,D,E,F,G,H,I,J), + ( '$call_inline'(K) + ; expand_call_goal(K,L,M), + strip_subst_module(M,L,N,O), + '$call_with_inference_counting'('$module_call'(N,O)) ). :-non_counted_backtracking call/11. call(A,B,C,D,E,F,G,H,I,J,K) :- - ( var(A) -> - instantiation_error(call/11) - ; A= '$call'(L) -> - '$prepare_call_clause'(M,N,L,B,C,D,E,F,G,H,I,J,K), - '$call_with_inference_counting'('$call'(N:M)) - ; '$prepare_call_clause'(M,N,A,B,C,D,E,F,G,H,I,J,K), - expand_goal(call(N:M),N,call(O)), - '$call_with_inference_counting'('$call'(O)) + var(A), + instantiation_error(call/11). +call(A,B,C,D,E,F,G,H,I,J,K) :- + '$strip_module'(A,L,M), + '$call_inline'(M,B,C,D,E,F,G,H,I,J,K). +call('$call'(A),B,C,D,E,F,G,H,I,J,K) :- + !, + '$prepare_call_clause'(L,M,A,B,C,D,E,F,G,H,I,J,K), + '$call_with_inference_counting'('$module_call'(M,L)). +call(A,B,C,D,E,F,G,H,I,J,K) :- + '$prepare_call_clause'(L,M,A,B,C,D,E,F,G,H,I,J,K), + ( '$call_inline'(L) + ; expand_call_goal(L,M,N), + strip_subst_module(N,M,O,P), + '$call_with_inference_counting'('$module_call'(O,P)) ). :-non_counted_backtracking call/12. call(A,B,C,D,E,F,G,H,I,J,K,L) :- - ( var(A) -> - instantiation_error(call/12) - ; A= '$call'(M) -> - '$prepare_call_clause'(N,O,M,B,C,D,E,F,G,H,I,J,K,L), - '$call_with_inference_counting'('$call'(O:N)) - ; '$prepare_call_clause'(N,O,A,B,C,D,E,F,G,H,I,J,K,L), - expand_goal(call(O:N),O,call(P)), - '$call_with_inference_counting'('$call'(P)) + var(A), + instantiation_error(call/12). +call(A,B,C,D,E,F,G,H,I,J,K,L) :- + '$strip_module'(A,M,N), + '$call_inline'(N,B,C,D,E,F,G,H,I,J,K,L). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L) :- + !, + '$prepare_call_clause'(M,N,A,B,C,D,E,F,G,H,I,J,K,L), + '$call_with_inference_counting'('$module_call'(N,M)). +call(A,B,C,D,E,F,G,H,I,J,K,L) :- + '$prepare_call_clause'(M,N,A,B,C,D,E,F,G,H,I,J,K,L), + ( '$call_inline'(M) + ; expand_call_goal(M,N,O), + strip_subst_module(O,N,P,Q), + '$call_with_inference_counting'('$module_call'(P,Q)) ). :-non_counted_backtracking call/13. call(A,B,C,D,E,F,G,H,I,J,K,L,M) :- - ( var(A) -> - instantiation_error(call/13) - ; A= '$call'(N) -> - '$prepare_call_clause'(O,P,N,B,C,D,E,F,G,H,I,J,K,L,M), - '$call_with_inference_counting'('$call'(P:O)) - ; '$prepare_call_clause'(O,P,A,B,C,D,E,F,G,H,I,J,K,L,M), - expand_goal(call(P:O),P,call(Q)), - '$call_with_inference_counting'('$call'(Q)) + var(A), + instantiation_error(call/13). +call(A,B,C,D,E,F,G,H,I,J,K,L,M) :- + '$strip_module'(A,N,O), + '$call_inline'(O,B,C,D,E,F,G,H,I,J,K,L,M). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M) :- + !, + '$prepare_call_clause'(N,O,A,B,C,D,E,F,G,H,I,J,K,L,M), + '$call_with_inference_counting'('$module_call'(O,N)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M) :- + '$prepare_call_clause'(N,O,A,B,C,D,E,F,G,H,I,J,K,L,M), + ( '$call_inline'(N) + ; expand_call_goal(N,O,P), + strip_subst_module(P,O,Q,R), + '$call_with_inference_counting'('$module_call'(Q,R)) ). :-non_counted_backtracking call/14. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :- - ( var(A) -> - instantiation_error(call/14) - ; A= '$call'(O) -> - '$prepare_call_clause'(P,Q,O,B,C,D,E,F,G,H,I,J,K,L,M,N), - '$call_with_inference_counting'('$call'(Q:P)) - ; '$prepare_call_clause'(P,Q,A,B,C,D,E,F,G,H,I,J,K,L,M,N), - expand_goal(call(Q:P),Q,call(R)), - '$call_with_inference_counting'('$call'(R)) + var(A), + instantiation_error(call/14). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :- + '$strip_module'(A,O,P), + '$call_inline'(P,B,C,D,E,F,G,H,I,J,K,L,M,N). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N) :- + !, + '$prepare_call_clause'(O,P,A,B,C,D,E,F,G,H,I,J,K,L,M,N), + '$call_with_inference_counting'('$module_call'(P,O)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :- + '$prepare_call_clause'(O,P,A,B,C,D,E,F,G,H,I,J,K,L,M,N), + ( '$call_inline'(O) + ; expand_call_goal(O,P,Q), + strip_subst_module(Q,P,R,S), + '$call_with_inference_counting'('$module_call'(R,S)) ). :-non_counted_backtracking call/15. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :- - ( var(A) -> - instantiation_error(call/15) - ; A= '$call'(P) -> - '$prepare_call_clause'(Q,R,P,B,C,D,E,F,G,H,I,J,K,L,M,N,O), - '$call_with_inference_counting'('$call'(R:Q)) - ; '$prepare_call_clause'(Q,R,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O), - expand_goal(call(R:Q),R,call(S)), - '$call_with_inference_counting'('$call'(S)) + var(A), + instantiation_error(call/15). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :- + '$strip_module'(A,P,Q), + '$call_inline'(Q,B,C,D,E,F,G,H,I,J,K,L,M,N,O). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O) :- + !, + '$prepare_call_clause'(P,Q,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O), + '$call_with_inference_counting'('$module_call'(Q,P)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :- + '$prepare_call_clause'(P,Q,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O), + ( '$call_inline'(P) + ; expand_call_goal(P,Q,R), + strip_subst_module(R,Q,S,T), + '$call_with_inference_counting'('$module_call'(S,T)) ). :-non_counted_backtracking call/16. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :- - ( var(A) -> - instantiation_error(call/16) - ; A= '$call'(Q) -> - '$prepare_call_clause'(R,S,Q,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), - '$call_with_inference_counting'('$call'(S:R)) - ; '$prepare_call_clause'(R,S,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), - expand_goal(call(S:R),S,call(T)), - '$call_with_inference_counting'('$call'(T)) + var(A), + instantiation_error(call/16). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :- + '$strip_module'(A,Q,R), + '$call_inline'(R,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :- + !, + '$prepare_call_clause'(Q,R,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), + '$call_with_inference_counting'('$module_call'(R,Q)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :- + '$prepare_call_clause'(Q,R,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), + ( '$call_inline'(Q) + ; expand_call_goal(Q,R,S), + strip_subst_module(S,R,T,U), + '$call_with_inference_counting'('$module_call'(T,U)) ). :-non_counted_backtracking call/17. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :- - ( var(A) -> - instantiation_error(call/17) - ; A= '$call'(R) -> - '$prepare_call_clause'(S,T,R,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q), - '$call_with_inference_counting'('$call'(T:S)) - ; '$prepare_call_clause'(S,T,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q), - expand_goal(call(T:S),T,call(U)), - '$call_with_inference_counting'('$call'(U)) + var(A), + instantiation_error(call/17). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :- + '$strip_module'(A,R,S), + '$call_inline'(S,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :- + !, + '$prepare_call_clause'(R,S,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q), + '$call_with_inference_counting'('$module_call'(S,R)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :- + '$prepare_call_clause'(R,S,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q), + ( '$call_inline'(R) + ; expand_call_goal(R,S,T), + strip_subst_module(T,S,U,V), + '$call_with_inference_counting'('$module_call'(U,V)) ). :-non_counted_backtracking call/18. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :- - ( var(A) -> - instantiation_error(call/18) - ; A= '$call'(S) -> - '$prepare_call_clause'(T,U,S,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R), - '$call_with_inference_counting'('$call'(U:T)) - ; '$prepare_call_clause'(T,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R), - expand_goal(call(U:T),U,call(V)), - '$call_with_inference_counting'('$call'(V)) + var(A), + instantiation_error(call/18). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :- + '$strip_module'(A,S,T), + '$call_inline'(T,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :- + !, + '$prepare_call_clause'(S,T,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R), + '$call_with_inference_counting'('$module_call'(T,S)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :- + '$prepare_call_clause'(S,T,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R), + ( '$call_inline'(S) + ; expand_call_goal(S,T,U), + strip_subst_module(U,T,V,W), + '$call_with_inference_counting'('$module_call'(V,W)) ). :-non_counted_backtracking call/19. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :- - ( var(A) -> - instantiation_error(call/19) - ; A= '$call'(T) -> - '$prepare_call_clause'(U,V,T,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S), - '$call_with_inference_counting'('$call'(V:U)) - ; '$prepare_call_clause'(U,V,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S), - expand_goal(call(V:U),V,call(W)), - '$call_with_inference_counting'('$call'(W)) + var(A), + instantiation_error(call/19). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :- + '$strip_module'(A,T,U), + '$call_inline'(U,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :- + !, + '$prepare_call_clause'(T,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S), + '$call_with_inference_counting'('$module_call'(U,T)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :- + '$prepare_call_clause'(T,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S), + ( '$call_inline'(T) + ; expand_call_goal(T,U,V), + strip_subst_module(V,U,W,X), + '$call_with_inference_counting'('$module_call'(W,X)) ). :-non_counted_backtracking call/20. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :- - ( var(A) -> - instantiation_error(call/20) - ; A= '$call'(U) -> - '$prepare_call_clause'(V,W,U,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T), - '$call_with_inference_counting'('$call'(W:V)) - ; '$prepare_call_clause'(V,W,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T), - expand_goal(call(W:V),W,call(X)), - '$call_with_inference_counting'('$call'(X)) + var(A), + instantiation_error(call/20). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :- + '$strip_module'(A,U,V), + '$call_inline'(V,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :- + !, + '$prepare_call_clause'(U,V,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T), + '$call_with_inference_counting'('$module_call'(V,U)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :- + '$prepare_call_clause'(U,V,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T), + ( '$call_inline'(U) + ; expand_call_goal(U,V,W), + strip_subst_module(W,V,X,Y), + '$call_with_inference_counting'('$module_call'(X,Y)) ). :-non_counted_backtracking call/21. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :- - ( var(A) -> - instantiation_error(call/21) - ; A= '$call'(V) -> - '$prepare_call_clause'(W,X,V,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U), - '$call_with_inference_counting'('$call'(X:W)) - ; '$prepare_call_clause'(W,X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U), - expand_goal(call(X:W),X,call(Y)), - '$call_with_inference_counting'('$call'(Y)) + var(A), + instantiation_error(call/21). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :- + '$strip_module'(A,V,W), + '$call_inline'(W,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :- + !, + '$prepare_call_clause'(V,W,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U), + '$call_with_inference_counting'('$module_call'(W,V)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :- + '$prepare_call_clause'(V,W,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U), + ( '$call_inline'(V) + ; expand_call_goal(V,W,X), + strip_subst_module(X,W,Y,Z), + '$call_with_inference_counting'('$module_call'(Y,Z)) ). :-non_counted_backtracking call/22. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :- - ( var(A) -> - instantiation_error(call/22) - ; A= '$call'(W) -> - '$prepare_call_clause'(X,Y,W,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V), - '$call_with_inference_counting'('$call'(Y:X)) - ; '$prepare_call_clause'(X,Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V), - expand_goal(call(Y:X),Y,call(Z)), - '$call_with_inference_counting'('$call'(Z)) + var(A), + instantiation_error(call/22). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :- + '$strip_module'(A,W,X), + '$call_inline'(X,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :- + !, + '$prepare_call_clause'(W,X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V), + '$call_with_inference_counting'('$module_call'(X,W)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :- + '$prepare_call_clause'(W,X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V), + ( '$call_inline'(W) + ; expand_call_goal(W,X,Y), + strip_subst_module(Y,X,Z,A1), + '$call_with_inference_counting'('$module_call'(Z,A1)) ). :-non_counted_backtracking call/23. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :- - ( var(A) -> - instantiation_error(call/23) - ; A= '$call'(X) -> - '$prepare_call_clause'(Y,Z,X,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W), - '$call_with_inference_counting'('$call'(Z:Y)) - ; '$prepare_call_clause'(Y,Z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W), - expand_goal(call(Z:Y),Z,call(A1)), - '$call_with_inference_counting'('$call'(A1)) + var(A), + instantiation_error(call/23). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :- + '$strip_module'(A,X,Y), + '$call_inline'(Y,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :- + !, + '$prepare_call_clause'(X,Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W), + '$call_with_inference_counting'('$module_call'(Y,X)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :- + '$prepare_call_clause'(X,Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W), + ( '$call_inline'(X) + ; expand_call_goal(X,Y,Z), + strip_subst_module(Z,Y,A1,B1), + '$call_with_inference_counting'('$module_call'(A1,B1)) ). :-non_counted_backtracking call/24. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :- - ( var(A) -> - instantiation_error(call/24) - ; A= '$call'(Y) -> - '$prepare_call_clause'(Z,A1,Y,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X), - '$call_with_inference_counting'('$call'(A1:Z)) - ; '$prepare_call_clause'(Z,A1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X), - expand_goal(call(A1:Z),A1,call(B1)), - '$call_with_inference_counting'('$call'(B1)) + var(A), + instantiation_error(call/24). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :- + '$strip_module'(A,Y,Z), + '$call_inline'(Z,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :- + !, + '$prepare_call_clause'(Y,Z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X), + '$call_with_inference_counting'('$module_call'(Z,Y)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :- + '$prepare_call_clause'(Y,Z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X), + ( '$call_inline'(Y) + ; expand_call_goal(Y,Z,A1), + strip_subst_module(A1,Z,B1,C1), + '$call_with_inference_counting'('$module_call'(B1,C1)) ). :-non_counted_backtracking call/25. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :- - ( var(A) -> - instantiation_error(call/25) - ; A= '$call'(Z) -> - '$prepare_call_clause'(A1,B1,Z,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y), - '$call_with_inference_counting'('$call'(B1:A1)) - ; '$prepare_call_clause'(A1,B1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y), - expand_goal(call(B1:A1),B1,call(C1)), - '$call_with_inference_counting'('$call'(C1)) + var(A), + instantiation_error(call/25). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :- + '$strip_module'(A,Z,A1), + '$call_inline'(A1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :- + !, + '$prepare_call_clause'(Z,A1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y), + '$call_with_inference_counting'('$module_call'(A1,Z)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :- + '$prepare_call_clause'(Z,A1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y), + ( '$call_inline'(Z) + ; expand_call_goal(Z,A1,B1), + strip_subst_module(B1,A1,C1,D1), + '$call_with_inference_counting'('$module_call'(C1,D1)) ). :-non_counted_backtracking call/26. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :- - ( var(A) -> - instantiation_error(call/26) - ; A= '$call'(A1) -> - '$prepare_call_clause'(B1,C1,A1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z), - '$call_with_inference_counting'('$call'(C1:B1)) - ; '$prepare_call_clause'(B1,C1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z), - expand_goal(call(C1:B1),C1,call(D1)), - '$call_with_inference_counting'('$call'(D1)) + var(A), + instantiation_error(call/26). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :- + '$strip_module'(A,A1,B1), + '$call_inline'(B1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :- + !, + '$prepare_call_clause'(A1,B1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z), + '$call_with_inference_counting'('$module_call'(B1,A1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :- + '$prepare_call_clause'(A1,B1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z), + ( '$call_inline'(A1) + ; expand_call_goal(A1,B1,C1), + strip_subst_module(C1,B1,D1,E1), + '$call_with_inference_counting'('$module_call'(D1,E1)) ). :-non_counted_backtracking call/27. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :- - ( var(A) -> - instantiation_error(call/27) - ; A= '$call'(B1) -> - '$prepare_call_clause'(C1,D1,B1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1), - '$call_with_inference_counting'('$call'(D1:C1)) - ; '$prepare_call_clause'(C1,D1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1), - expand_goal(call(D1:C1),D1,call(E1)), - '$call_with_inference_counting'('$call'(E1)) + var(A), + instantiation_error(call/27). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :- + '$strip_module'(A,B1,C1), + '$call_inline'(C1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :- + !, + '$prepare_call_clause'(B1,C1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1), + '$call_with_inference_counting'('$module_call'(C1,B1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :- + '$prepare_call_clause'(B1,C1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1), + ( '$call_inline'(B1) + ; expand_call_goal(B1,C1,D1), + strip_subst_module(D1,C1,E1,F1), + '$call_with_inference_counting'('$module_call'(E1,F1)) ). :-non_counted_backtracking call/28. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :- - ( var(A) -> - instantiation_error(call/28) - ; A= '$call'(C1) -> - '$prepare_call_clause'(D1,E1,C1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1), - '$call_with_inference_counting'('$call'(E1:D1)) - ; '$prepare_call_clause'(D1,E1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1), - expand_goal(call(E1:D1),E1,call(F1)), - '$call_with_inference_counting'('$call'(F1)) + var(A), + instantiation_error(call/28). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :- + '$strip_module'(A,C1,D1), + '$call_inline'(D1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :- + !, + '$prepare_call_clause'(C1,D1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1), + '$call_with_inference_counting'('$module_call'(D1,C1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :- + '$prepare_call_clause'(C1,D1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1), + ( '$call_inline'(C1) + ; expand_call_goal(C1,D1,E1), + strip_subst_module(E1,D1,F1,G1), + '$call_with_inference_counting'('$module_call'(F1,G1)) ). :-non_counted_backtracking call/29. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :- - ( var(A) -> - instantiation_error(call/29) - ; A= '$call'(D1) -> - '$prepare_call_clause'(E1,F1,D1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1), - '$call_with_inference_counting'('$call'(F1:E1)) - ; '$prepare_call_clause'(E1,F1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1), - expand_goal(call(F1:E1),F1,call(G1)), - '$call_with_inference_counting'('$call'(G1)) + var(A), + instantiation_error(call/29). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :- + '$strip_module'(A,D1,E1), + '$call_inline'(E1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :- + !, + '$prepare_call_clause'(D1,E1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1), + '$call_with_inference_counting'('$module_call'(E1,D1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :- + '$prepare_call_clause'(D1,E1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1), + ( '$call_inline'(D1) + ; expand_call_goal(D1,E1,F1), + strip_subst_module(F1,E1,G1,H1), + '$call_with_inference_counting'('$module_call'(G1,H1)) ). :-non_counted_backtracking call/30. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :- - ( var(A) -> - instantiation_error(call/30) - ; A= '$call'(E1) -> - '$prepare_call_clause'(F1,G1,E1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1), - '$call_with_inference_counting'('$call'(G1:F1)) - ; '$prepare_call_clause'(F1,G1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1), - expand_goal(call(G1:F1),G1,call(H1)), - '$call_with_inference_counting'('$call'(H1)) + var(A), + instantiation_error(call/30). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :- + '$strip_module'(A,E1,F1), + '$call_inline'(F1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :- + !, + '$prepare_call_clause'(E1,F1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1), + '$call_with_inference_counting'('$module_call'(F1,E1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :- + '$prepare_call_clause'(E1,F1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1), + ( '$call_inline'(E1) + ; expand_call_goal(E1,F1,G1), + strip_subst_module(G1,F1,H1,I1), + '$call_with_inference_counting'('$module_call'(H1,I1)) ). :-non_counted_backtracking call/31. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :- - ( var(A) -> - instantiation_error(call/31) - ; A= '$call'(F1) -> - '$prepare_call_clause'(G1,H1,F1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1), - '$call_with_inference_counting'('$call'(H1:G1)) - ; '$prepare_call_clause'(G1,H1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1), - expand_goal(call(H1:G1),H1,call(I1)), - '$call_with_inference_counting'('$call'(I1)) + var(A), + instantiation_error(call/31). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :- + '$strip_module'(A,F1,G1), + '$call_inline'(G1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :- + !, + '$prepare_call_clause'(F1,G1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1), + '$call_with_inference_counting'('$module_call'(G1,F1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :- + '$prepare_call_clause'(F1,G1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1), + ( '$call_inline'(F1) + ; expand_call_goal(F1,G1,H1), + strip_subst_module(H1,G1,I1,J1), + '$call_with_inference_counting'('$module_call'(I1,J1)) ). :-non_counted_backtracking call/32. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :- - ( var(A) -> - instantiation_error(call/32) - ; A= '$call'(G1) -> - '$prepare_call_clause'(H1,I1,G1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1), - '$call_with_inference_counting'('$call'(I1:H1)) - ; '$prepare_call_clause'(H1,I1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1), - expand_goal(call(I1:H1),I1,call(J1)), - '$call_with_inference_counting'('$call'(J1)) + var(A), + instantiation_error(call/32). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :- + '$strip_module'(A,G1,H1), + '$call_inline'(H1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :- + !, + '$prepare_call_clause'(G1,H1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1), + '$call_with_inference_counting'('$module_call'(H1,G1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :- + '$prepare_call_clause'(G1,H1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1), + ( '$call_inline'(G1) + ; expand_call_goal(G1,H1,I1), + strip_subst_module(I1,H1,J1,K1), + '$call_with_inference_counting'('$module_call'(J1,K1)) ). :-non_counted_backtracking call/33. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :- - ( var(A) -> - instantiation_error(call/33) - ; A= '$call'(H1) -> - '$prepare_call_clause'(I1,J1,H1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1), - '$call_with_inference_counting'('$call'(J1:I1)) - ; '$prepare_call_clause'(I1,J1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1), - expand_goal(call(J1:I1),J1,call(K1)), - '$call_with_inference_counting'('$call'(K1)) + var(A), + instantiation_error(call/33). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :- + '$strip_module'(A,H1,I1), + '$call_inline'(I1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :- + !, + '$prepare_call_clause'(H1,I1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1), + '$call_with_inference_counting'('$module_call'(I1,H1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :- + '$prepare_call_clause'(H1,I1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1), + ( '$call_inline'(H1) + ; expand_call_goal(H1,I1,J1), + strip_subst_module(J1,I1,K1,L1), + '$call_with_inference_counting'('$module_call'(K1,L1)) ). :-non_counted_backtracking call/34. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :- - ( var(A) -> - instantiation_error(call/34) - ; A= '$call'(I1) -> - '$prepare_call_clause'(J1,K1,I1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1), - '$call_with_inference_counting'('$call'(K1:J1)) - ; '$prepare_call_clause'(J1,K1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1), - expand_goal(call(K1:J1),K1,call(L1)), - '$call_with_inference_counting'('$call'(L1)) + var(A), + instantiation_error(call/34). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :- + '$strip_module'(A,I1,J1), + '$call_inline'(J1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :- + !, + '$prepare_call_clause'(I1,J1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1), + '$call_with_inference_counting'('$module_call'(J1,I1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :- + '$prepare_call_clause'(I1,J1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1), + ( '$call_inline'(I1) + ; expand_call_goal(I1,J1,K1), + strip_subst_module(K1,J1,L1,M1), + '$call_with_inference_counting'('$module_call'(L1,M1)) ). :-non_counted_backtracking call/35. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :- - ( var(A) -> - instantiation_error(call/35) - ; A= '$call'(J1) -> - '$prepare_call_clause'(K1,L1,J1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1), - '$call_with_inference_counting'('$call'(L1:K1)) - ; '$prepare_call_clause'(K1,L1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1), - expand_goal(call(L1:K1),L1,call(M1)), - '$call_with_inference_counting'('$call'(M1)) + var(A), + instantiation_error(call/35). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :- + '$strip_module'(A,J1,K1), + '$call_inline'(K1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :- + !, + '$prepare_call_clause'(J1,K1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1), + '$call_with_inference_counting'('$module_call'(K1,J1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :- + '$prepare_call_clause'(J1,K1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1), + ( '$call_inline'(J1) + ; expand_call_goal(J1,K1,L1), + strip_subst_module(L1,K1,M1,N1), + '$call_with_inference_counting'('$module_call'(M1,N1)) ). :-non_counted_backtracking call/36. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :- - ( var(A) -> - instantiation_error(call/36) - ; A= '$call'(K1) -> - '$prepare_call_clause'(L1,M1,K1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1), - '$call_with_inference_counting'('$call'(M1:L1)) - ; '$prepare_call_clause'(L1,M1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1), - expand_goal(call(M1:L1),M1,call(N1)), - '$call_with_inference_counting'('$call'(N1)) + var(A), + instantiation_error(call/36). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :- + '$strip_module'(A,K1,L1), + '$call_inline'(L1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :- + !, + '$prepare_call_clause'(K1,L1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1), + '$call_with_inference_counting'('$module_call'(L1,K1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :- + '$prepare_call_clause'(K1,L1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1), + ( '$call_inline'(K1) + ; expand_call_goal(K1,L1,M1), + strip_subst_module(M1,L1,N1,O1), + '$call_with_inference_counting'('$module_call'(N1,O1)) ). :-non_counted_backtracking call/37. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :- - ( var(A) -> - instantiation_error(call/37) - ; A= '$call'(L1) -> - '$prepare_call_clause'(M1,N1,L1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1), - '$call_with_inference_counting'('$call'(N1:M1)) - ; '$prepare_call_clause'(M1,N1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1), - expand_goal(call(N1:M1),N1,call(O1)), - '$call_with_inference_counting'('$call'(O1)) + var(A), + instantiation_error(call/37). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :- + '$strip_module'(A,L1,M1), + '$call_inline'(M1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :- + !, + '$prepare_call_clause'(L1,M1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1), + '$call_with_inference_counting'('$module_call'(M1,L1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :- + '$prepare_call_clause'(L1,M1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1), + ( '$call_inline'(L1) + ; expand_call_goal(L1,M1,N1), + strip_subst_module(N1,M1,O1,P1), + '$call_with_inference_counting'('$module_call'(O1,P1)) ). :-non_counted_backtracking call/38. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :- - ( var(A) -> - instantiation_error(call/38) - ; A= '$call'(M1) -> - '$prepare_call_clause'(N1,O1,M1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1), - '$call_with_inference_counting'('$call'(O1:N1)) - ; '$prepare_call_clause'(N1,O1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1), - expand_goal(call(O1:N1),O1,call(P1)), - '$call_with_inference_counting'('$call'(P1)) + var(A), + instantiation_error(call/38). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :- + '$strip_module'(A,M1,N1), + '$call_inline'(N1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :- + !, + '$prepare_call_clause'(M1,N1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1), + '$call_with_inference_counting'('$module_call'(N1,M1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :- + '$prepare_call_clause'(M1,N1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1), + ( '$call_inline'(M1) + ; expand_call_goal(M1,N1,O1), + strip_subst_module(O1,N1,P1,Q1), + '$call_with_inference_counting'('$module_call'(P1,Q1)) ). :-non_counted_backtracking call/39. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :- - ( var(A) -> - instantiation_error(call/39) - ; A= '$call'(N1) -> - '$prepare_call_clause'(O1,P1,N1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1), - '$call_with_inference_counting'('$call'(P1:O1)) - ; '$prepare_call_clause'(O1,P1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1), - expand_goal(call(P1:O1),P1,call(Q1)), - '$call_with_inference_counting'('$call'(Q1)) + var(A), + instantiation_error(call/39). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :- + '$strip_module'(A,N1,O1), + '$call_inline'(O1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :- + !, + '$prepare_call_clause'(N1,O1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1), + '$call_with_inference_counting'('$module_call'(O1,N1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :- + '$prepare_call_clause'(N1,O1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1), + ( '$call_inline'(N1) + ; expand_call_goal(N1,O1,P1), + strip_subst_module(P1,O1,Q1,R1), + '$call_with_inference_counting'('$module_call'(Q1,R1)) ). :-non_counted_backtracking call/40. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :- - ( var(A) -> - instantiation_error(call/40) - ; A= '$call'(O1) -> - '$prepare_call_clause'(P1,Q1,O1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1), - '$call_with_inference_counting'('$call'(Q1:P1)) - ; '$prepare_call_clause'(P1,Q1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1), - expand_goal(call(Q1:P1),Q1,call(R1)), - '$call_with_inference_counting'('$call'(R1)) + var(A), + instantiation_error(call/40). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :- + '$strip_module'(A,O1,P1), + '$call_inline'(P1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :- + !, + '$prepare_call_clause'(O1,P1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1), + '$call_with_inference_counting'('$module_call'(P1,O1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :- + '$prepare_call_clause'(O1,P1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1), + ( '$call_inline'(O1) + ; expand_call_goal(O1,P1,Q1), + strip_subst_module(Q1,P1,R1,S1), + '$call_with_inference_counting'('$module_call'(R1,S1)) ). :-non_counted_backtracking call/41. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :- - ( var(A) -> - instantiation_error(call/41) - ; A= '$call'(P1) -> - '$prepare_call_clause'(Q1,R1,P1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1), - '$call_with_inference_counting'('$call'(R1:Q1)) - ; '$prepare_call_clause'(Q1,R1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1), - expand_goal(call(R1:Q1),R1,call(S1)), - '$call_with_inference_counting'('$call'(S1)) + var(A), + instantiation_error(call/41). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :- + '$strip_module'(A,P1,Q1), + '$call_inline'(Q1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :- + !, + '$prepare_call_clause'(P1,Q1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1), + '$call_with_inference_counting'('$module_call'(Q1,P1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :- + '$prepare_call_clause'(P1,Q1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1), + ( '$call_inline'(P1) + ; expand_call_goal(P1,Q1,R1), + strip_subst_module(R1,Q1,S1,T1), + '$call_with_inference_counting'('$module_call'(S1,T1)) ). :-non_counted_backtracking call/42. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :- - ( var(A) -> - instantiation_error(call/42) - ; A= '$call'(Q1) -> - '$prepare_call_clause'(R1,S1,Q1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1), - '$call_with_inference_counting'('$call'(S1:R1)) - ; '$prepare_call_clause'(R1,S1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1), - expand_goal(call(S1:R1),S1,call(T1)), - '$call_with_inference_counting'('$call'(T1)) + var(A), + instantiation_error(call/42). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :- + '$strip_module'(A,Q1,R1), + '$call_inline'(R1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :- + !, + '$prepare_call_clause'(Q1,R1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1), + '$call_with_inference_counting'('$module_call'(R1,Q1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :- + '$prepare_call_clause'(Q1,R1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1), + ( '$call_inline'(Q1) + ; expand_call_goal(Q1,R1,S1), + strip_subst_module(S1,R1,T1,U1), + '$call_with_inference_counting'('$module_call'(T1,U1)) ). :-non_counted_backtracking call/43. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :- - ( var(A) -> - instantiation_error(call/43) - ; A= '$call'(R1) -> - '$prepare_call_clause'(S1,T1,R1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1), - '$call_with_inference_counting'('$call'(T1:S1)) - ; '$prepare_call_clause'(S1,T1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1), - expand_goal(call(T1:S1),T1,call(U1)), - '$call_with_inference_counting'('$call'(U1)) + var(A), + instantiation_error(call/43). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :- + '$strip_module'(A,R1,S1), + '$call_inline'(S1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :- + !, + '$prepare_call_clause'(R1,S1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1), + '$call_with_inference_counting'('$module_call'(S1,R1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :- + '$prepare_call_clause'(R1,S1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1), + ( '$call_inline'(R1) + ; expand_call_goal(R1,S1,T1), + strip_subst_module(T1,S1,U1,V1), + '$call_with_inference_counting'('$module_call'(U1,V1)) ). :-non_counted_backtracking call/44. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :- - ( var(A) -> - instantiation_error(call/44) - ; A= '$call'(S1) -> - '$prepare_call_clause'(T1,U1,S1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1), - '$call_with_inference_counting'('$call'(U1:T1)) - ; '$prepare_call_clause'(T1,U1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1), - expand_goal(call(U1:T1),U1,call(V1)), - '$call_with_inference_counting'('$call'(V1)) + var(A), + instantiation_error(call/44). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :- + '$strip_module'(A,S1,T1), + '$call_inline'(T1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :- + !, + '$prepare_call_clause'(S1,T1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1), + '$call_with_inference_counting'('$module_call'(T1,S1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :- + '$prepare_call_clause'(S1,T1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1), + ( '$call_inline'(S1) + ; expand_call_goal(S1,T1,U1), + strip_subst_module(U1,T1,V1,W1), + '$call_with_inference_counting'('$module_call'(V1,W1)) ). :-non_counted_backtracking call/45. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :- - ( var(A) -> - instantiation_error(call/45) - ; A= '$call'(T1) -> - '$prepare_call_clause'(U1,V1,T1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1), - '$call_with_inference_counting'('$call'(V1:U1)) - ; '$prepare_call_clause'(U1,V1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1), - expand_goal(call(V1:U1),V1,call(W1)), - '$call_with_inference_counting'('$call'(W1)) + var(A), + instantiation_error(call/45). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :- + '$strip_module'(A,T1,U1), + '$call_inline'(U1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :- + !, + '$prepare_call_clause'(T1,U1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1), + '$call_with_inference_counting'('$module_call'(U1,T1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :- + '$prepare_call_clause'(T1,U1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1), + ( '$call_inline'(T1) + ; expand_call_goal(T1,U1,V1), + strip_subst_module(V1,U1,W1,X1), + '$call_with_inference_counting'('$module_call'(W1,X1)) ). :-non_counted_backtracking call/46. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :- - ( var(A) -> - instantiation_error(call/46) - ; A= '$call'(U1) -> - '$prepare_call_clause'(V1,W1,U1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1), - '$call_with_inference_counting'('$call'(W1:V1)) - ; '$prepare_call_clause'(V1,W1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1), - expand_goal(call(W1:V1),W1,call(X1)), - '$call_with_inference_counting'('$call'(X1)) + var(A), + instantiation_error(call/46). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :- + '$strip_module'(A,U1,V1), + '$call_inline'(V1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :- + !, + '$prepare_call_clause'(U1,V1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1), + '$call_with_inference_counting'('$module_call'(V1,U1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :- + '$prepare_call_clause'(U1,V1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1), + ( '$call_inline'(U1) + ; expand_call_goal(U1,V1,W1), + strip_subst_module(W1,V1,X1,Y1), + '$call_with_inference_counting'('$module_call'(X1,Y1)) ). :-non_counted_backtracking call/47. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :- - ( var(A) -> - instantiation_error(call/47) - ; A= '$call'(V1) -> - '$prepare_call_clause'(W1,X1,V1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1), - '$call_with_inference_counting'('$call'(X1:W1)) - ; '$prepare_call_clause'(W1,X1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1), - expand_goal(call(X1:W1),X1,call(Y1)), - '$call_with_inference_counting'('$call'(Y1)) + var(A), + instantiation_error(call/47). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :- + '$strip_module'(A,V1,W1), + '$call_inline'(W1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :- + !, + '$prepare_call_clause'(V1,W1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1), + '$call_with_inference_counting'('$module_call'(W1,V1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :- + '$prepare_call_clause'(V1,W1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1), + ( '$call_inline'(V1) + ; expand_call_goal(V1,W1,X1), + strip_subst_module(X1,W1,Y1,Z1), + '$call_with_inference_counting'('$module_call'(Y1,Z1)) ). :-non_counted_backtracking call/48. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :- - ( var(A) -> - instantiation_error(call/48) - ; A= '$call'(W1) -> - '$prepare_call_clause'(X1,Y1,W1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1), - '$call_with_inference_counting'('$call'(Y1:X1)) - ; '$prepare_call_clause'(X1,Y1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1), - expand_goal(call(Y1:X1),Y1,call(Z1)), - '$call_with_inference_counting'('$call'(Z1)) + var(A), + instantiation_error(call/48). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :- + '$strip_module'(A,W1,X1), + '$call_inline'(X1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :- + !, + '$prepare_call_clause'(W1,X1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1), + '$call_with_inference_counting'('$module_call'(X1,W1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :- + '$prepare_call_clause'(W1,X1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1), + ( '$call_inline'(W1) + ; expand_call_goal(W1,X1,Y1), + strip_subst_module(Y1,X1,Z1,A2), + '$call_with_inference_counting'('$module_call'(Z1,A2)) ). :-non_counted_backtracking call/49. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :- - ( var(A) -> - instantiation_error(call/49) - ; A= '$call'(X1) -> - '$prepare_call_clause'(Y1,Z1,X1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1), - '$call_with_inference_counting'('$call'(Z1:Y1)) - ; '$prepare_call_clause'(Y1,Z1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1), - expand_goal(call(Z1:Y1),Z1,call(A2)), - '$call_with_inference_counting'('$call'(A2)) + var(A), + instantiation_error(call/49). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :- + '$strip_module'(A,X1,Y1), + '$call_inline'(Y1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :- + !, + '$prepare_call_clause'(X1,Y1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1), + '$call_with_inference_counting'('$module_call'(Y1,X1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :- + '$prepare_call_clause'(X1,Y1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1), + ( '$call_inline'(X1) + ; expand_call_goal(X1,Y1,Z1), + strip_subst_module(Z1,Y1,A2,B2), + '$call_with_inference_counting'('$module_call'(A2,B2)) ). :-non_counted_backtracking call/50. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :- - ( var(A) -> - instantiation_error(call/50) - ; A= '$call'(Y1) -> - '$prepare_call_clause'(Z1,A2,Y1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1), - '$call_with_inference_counting'('$call'(A2:Z1)) - ; '$prepare_call_clause'(Z1,A2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1), - expand_goal(call(A2:Z1),A2,call(B2)), - '$call_with_inference_counting'('$call'(B2)) + var(A), + instantiation_error(call/50). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :- + '$strip_module'(A,Y1,Z1), + '$call_inline'(Z1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :- + !, + '$prepare_call_clause'(Y1,Z1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1), + '$call_with_inference_counting'('$module_call'(Z1,Y1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :- + '$prepare_call_clause'(Y1,Z1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1), + ( '$call_inline'(Y1) + ; expand_call_goal(Y1,Z1,A2), + strip_subst_module(A2,Z1,B2,C2), + '$call_with_inference_counting'('$module_call'(B2,C2)) ). :-non_counted_backtracking call/51. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :- - ( var(A) -> - instantiation_error(call/51) - ; A= '$call'(Z1) -> - '$prepare_call_clause'(A2,B2,Z1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1), - '$call_with_inference_counting'('$call'(B2:A2)) - ; '$prepare_call_clause'(A2,B2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1), - expand_goal(call(B2:A2),B2,call(C2)), - '$call_with_inference_counting'('$call'(C2)) + var(A), + instantiation_error(call/51). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :- + '$strip_module'(A,Z1,A2), + '$call_inline'(A2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :- + !, + '$prepare_call_clause'(Z1,A2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1), + '$call_with_inference_counting'('$module_call'(A2,Z1)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :- + '$prepare_call_clause'(Z1,A2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1), + ( '$call_inline'(Z1) + ; expand_call_goal(Z1,A2,B2), + strip_subst_module(B2,A2,C2,D2), + '$call_with_inference_counting'('$module_call'(C2,D2)) ). :-non_counted_backtracking call/52. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :- - ( var(A) -> - instantiation_error(call/52) - ; A= '$call'(A2) -> - '$prepare_call_clause'(B2,C2,A2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1), - '$call_with_inference_counting'('$call'(C2:B2)) - ; '$prepare_call_clause'(B2,C2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1), - expand_goal(call(C2:B2),C2,call(D2)), - '$call_with_inference_counting'('$call'(D2)) + var(A), + instantiation_error(call/52). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :- + '$strip_module'(A,A2,B2), + '$call_inline'(B2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :- + !, + '$prepare_call_clause'(A2,B2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1), + '$call_with_inference_counting'('$module_call'(B2,A2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :- + '$prepare_call_clause'(A2,B2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1), + ( '$call_inline'(A2) + ; expand_call_goal(A2,B2,C2), + strip_subst_module(C2,B2,D2,E2), + '$call_with_inference_counting'('$module_call'(D2,E2)) ). :-non_counted_backtracking call/53. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :- - ( var(A) -> - instantiation_error(call/53) - ; A= '$call'(B2) -> - '$prepare_call_clause'(C2,D2,B2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2), - '$call_with_inference_counting'('$call'(D2:C2)) - ; '$prepare_call_clause'(C2,D2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2), - expand_goal(call(D2:C2),D2,call(E2)), - '$call_with_inference_counting'('$call'(E2)) + var(A), + instantiation_error(call/53). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :- + '$strip_module'(A,B2,C2), + '$call_inline'(C2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :- + !, + '$prepare_call_clause'(B2,C2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2), + '$call_with_inference_counting'('$module_call'(C2,B2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :- + '$prepare_call_clause'(B2,C2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2), + ( '$call_inline'(B2) + ; expand_call_goal(B2,C2,D2), + strip_subst_module(D2,C2,E2,F2), + '$call_with_inference_counting'('$module_call'(E2,F2)) ). :-non_counted_backtracking call/54. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :- - ( var(A) -> - instantiation_error(call/54) - ; A= '$call'(C2) -> - '$prepare_call_clause'(D2,E2,C2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2), - '$call_with_inference_counting'('$call'(E2:D2)) - ; '$prepare_call_clause'(D2,E2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2), - expand_goal(call(E2:D2),E2,call(F2)), - '$call_with_inference_counting'('$call'(F2)) + var(A), + instantiation_error(call/54). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :- + '$strip_module'(A,C2,D2), + '$call_inline'(D2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :- + !, + '$prepare_call_clause'(C2,D2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2), + '$call_with_inference_counting'('$module_call'(D2,C2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :- + '$prepare_call_clause'(C2,D2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2), + ( '$call_inline'(C2) + ; expand_call_goal(C2,D2,E2), + strip_subst_module(E2,D2,F2,G2), + '$call_with_inference_counting'('$module_call'(F2,G2)) ). :-non_counted_backtracking call/55. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :- - ( var(A) -> - instantiation_error(call/55) - ; A= '$call'(D2) -> - '$prepare_call_clause'(E2,F2,D2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2), - '$call_with_inference_counting'('$call'(F2:E2)) - ; '$prepare_call_clause'(E2,F2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2), - expand_goal(call(F2:E2),F2,call(G2)), - '$call_with_inference_counting'('$call'(G2)) + var(A), + instantiation_error(call/55). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :- + '$strip_module'(A,D2,E2), + '$call_inline'(E2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :- + !, + '$prepare_call_clause'(D2,E2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2), + '$call_with_inference_counting'('$module_call'(E2,D2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :- + '$prepare_call_clause'(D2,E2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2), + ( '$call_inline'(D2) + ; expand_call_goal(D2,E2,F2), + strip_subst_module(F2,E2,G2,H2), + '$call_with_inference_counting'('$module_call'(G2,H2)) ). :-non_counted_backtracking call/56. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :- - ( var(A) -> - instantiation_error(call/56) - ; A= '$call'(E2) -> - '$prepare_call_clause'(F2,G2,E2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2), - '$call_with_inference_counting'('$call'(G2:F2)) - ; '$prepare_call_clause'(F2,G2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2), - expand_goal(call(G2:F2),G2,call(H2)), - '$call_with_inference_counting'('$call'(H2)) + var(A), + instantiation_error(call/56). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :- + '$strip_module'(A,E2,F2), + '$call_inline'(F2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :- + !, + '$prepare_call_clause'(E2,F2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2), + '$call_with_inference_counting'('$module_call'(F2,E2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :- + '$prepare_call_clause'(E2,F2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2), + ( '$call_inline'(E2) + ; expand_call_goal(E2,F2,G2), + strip_subst_module(G2,F2,H2,I2), + '$call_with_inference_counting'('$module_call'(H2,I2)) ). :-non_counted_backtracking call/57. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :- - ( var(A) -> - instantiation_error(call/57) - ; A= '$call'(F2) -> - '$prepare_call_clause'(G2,H2,F2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2), - '$call_with_inference_counting'('$call'(H2:G2)) - ; '$prepare_call_clause'(G2,H2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2), - expand_goal(call(H2:G2),H2,call(I2)), - '$call_with_inference_counting'('$call'(I2)) + var(A), + instantiation_error(call/57). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :- + '$strip_module'(A,F2,G2), + '$call_inline'(G2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :- + !, + '$prepare_call_clause'(F2,G2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2), + '$call_with_inference_counting'('$module_call'(G2,F2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :- + '$prepare_call_clause'(F2,G2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2), + ( '$call_inline'(F2) + ; expand_call_goal(F2,G2,H2), + strip_subst_module(H2,G2,I2,J2), + '$call_with_inference_counting'('$module_call'(I2,J2)) ). :-non_counted_backtracking call/58. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :- - ( var(A) -> - instantiation_error(call/58) - ; A= '$call'(G2) -> - '$prepare_call_clause'(H2,I2,G2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2), - '$call_with_inference_counting'('$call'(I2:H2)) - ; '$prepare_call_clause'(H2,I2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2), - expand_goal(call(I2:H2),I2,call(J2)), - '$call_with_inference_counting'('$call'(J2)) + var(A), + instantiation_error(call/58). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :- + '$strip_module'(A,G2,H2), + '$call_inline'(H2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :- + !, + '$prepare_call_clause'(G2,H2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2), + '$call_with_inference_counting'('$module_call'(H2,G2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :- + '$prepare_call_clause'(G2,H2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2), + ( '$call_inline'(G2) + ; expand_call_goal(G2,H2,I2), + strip_subst_module(I2,H2,J2,K2), + '$call_with_inference_counting'('$module_call'(J2,K2)) ). :-non_counted_backtracking call/59. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :- - ( var(A) -> - instantiation_error(call/59) - ; A= '$call'(H2) -> - '$prepare_call_clause'(I2,J2,H2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2), - '$call_with_inference_counting'('$call'(J2:I2)) - ; '$prepare_call_clause'(I2,J2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2), - expand_goal(call(J2:I2),J2,call(K2)), - '$call_with_inference_counting'('$call'(K2)) + var(A), + instantiation_error(call/59). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :- + '$strip_module'(A,H2,I2), + '$call_inline'(I2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :- + !, + '$prepare_call_clause'(H2,I2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2), + '$call_with_inference_counting'('$module_call'(I2,H2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :- + '$prepare_call_clause'(H2,I2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2), + ( '$call_inline'(H2) + ; expand_call_goal(H2,I2,J2), + strip_subst_module(J2,I2,K2,L2), + '$call_with_inference_counting'('$module_call'(K2,L2)) ). :-non_counted_backtracking call/60. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :- - ( var(A) -> - instantiation_error(call/60) - ; A= '$call'(I2) -> - '$prepare_call_clause'(J2,K2,I2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2), - '$call_with_inference_counting'('$call'(K2:J2)) - ; '$prepare_call_clause'(J2,K2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2), - expand_goal(call(K2:J2),K2,call(L2)), - '$call_with_inference_counting'('$call'(L2)) + var(A), + instantiation_error(call/60). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :- + '$strip_module'(A,I2,J2), + '$call_inline'(J2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :- + !, + '$prepare_call_clause'(I2,J2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2), + '$call_with_inference_counting'('$module_call'(J2,I2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :- + '$prepare_call_clause'(I2,J2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2), + ( '$call_inline'(I2) + ; expand_call_goal(I2,J2,K2), + strip_subst_module(K2,J2,L2,M2), + '$call_with_inference_counting'('$module_call'(L2,M2)) ). :-non_counted_backtracking call/61. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :- - ( var(A) -> - instantiation_error(call/61) - ; A= '$call'(J2) -> - '$prepare_call_clause'(K2,L2,J2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2), - '$call_with_inference_counting'('$call'(L2:K2)) - ; '$prepare_call_clause'(K2,L2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2), - expand_goal(call(L2:K2),L2,call(M2)), - '$call_with_inference_counting'('$call'(M2)) + var(A), + instantiation_error(call/61). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :- + '$strip_module'(A,J2,K2), + '$call_inline'(K2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :- + !, + '$prepare_call_clause'(J2,K2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2), + '$call_with_inference_counting'('$module_call'(K2,J2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :- + '$prepare_call_clause'(J2,K2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2), + ( '$call_inline'(J2) + ; expand_call_goal(J2,K2,L2), + strip_subst_module(L2,K2,M2,N2), + '$call_with_inference_counting'('$module_call'(M2,N2)) ). :-non_counted_backtracking call/62. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :- - ( var(A) -> - instantiation_error(call/62) - ; A= '$call'(K2) -> - '$prepare_call_clause'(L2,M2,K2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2), - '$call_with_inference_counting'('$call'(M2:L2)) - ; '$prepare_call_clause'(L2,M2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2), - expand_goal(call(M2:L2),M2,call(N2)), - '$call_with_inference_counting'('$call'(N2)) + var(A), + instantiation_error(call/62). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :- + '$strip_module'(A,K2,L2), + '$call_inline'(L2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :- + !, + '$prepare_call_clause'(K2,L2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2), + '$call_with_inference_counting'('$module_call'(L2,K2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :- + '$prepare_call_clause'(K2,L2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2), + ( '$call_inline'(K2) + ; expand_call_goal(K2,L2,M2), + strip_subst_module(M2,L2,N2,O2), + '$call_with_inference_counting'('$module_call'(N2,O2)) ). :-non_counted_backtracking call/63. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :- - ( var(A) -> - instantiation_error(call/63) - ; A= '$call'(L2) -> - '$prepare_call_clause'(M2,N2,L2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2), - '$call_with_inference_counting'('$call'(N2:M2)) - ; '$prepare_call_clause'(M2,N2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2), - expand_goal(call(N2:M2),N2,call(O2)), - '$call_with_inference_counting'('$call'(O2)) + var(A), + instantiation_error(call/63). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :- + '$strip_module'(A,L2,M2), + '$call_inline'(M2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :- + !, + '$prepare_call_clause'(L2,M2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2), + '$call_with_inference_counting'('$module_call'(M2,L2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :- + '$prepare_call_clause'(L2,M2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2), + ( '$call_inline'(L2) + ; expand_call_goal(L2,M2,N2), + strip_subst_module(N2,M2,O2,P2), + '$call_with_inference_counting'('$module_call'(O2,P2)) ). :-non_counted_backtracking call/64. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :- - ( var(A) -> - instantiation_error(call/64) - ; A= '$call'(M2) -> - '$prepare_call_clause'(N2,O2,M2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2), - '$call_with_inference_counting'('$call'(O2:N2)) - ; '$prepare_call_clause'(N2,O2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2), - expand_goal(call(O2:N2),O2,call(P2)), - '$call_with_inference_counting'('$call'(P2)) + var(A), + instantiation_error(call/64). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :- + '$strip_module'(A,M2,N2), + '$call_inline'(N2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :- + !, + '$prepare_call_clause'(M2,N2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2), + '$call_with_inference_counting'('$module_call'(N2,M2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :- + '$prepare_call_clause'(M2,N2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2), + ( '$call_inline'(M2) + ; expand_call_goal(M2,N2,O2), + strip_subst_module(O2,N2,P2,Q2), + '$call_with_inference_counting'('$module_call'(P2,Q2)) ). :-non_counted_backtracking call/65. call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :- - ( var(A) -> - instantiation_error(call/65) - ; A= '$call'(N2) -> - '$prepare_call_clause'(O2,P2,N2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2), - '$call_with_inference_counting'('$call'(P2:O2)) - ; '$prepare_call_clause'(O2,P2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2), - expand_goal(call(P2:O2),P2,call(Q2)), - '$call_with_inference_counting'('$call'(Q2)) + var(A), + instantiation_error(call/65). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :- + '$strip_module'(A,N2,O2), + '$call_inline'(O2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2). +call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :- + !, + '$prepare_call_clause'(N2,O2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2), + '$call_with_inference_counting'('$module_call'(O2,N2)). +call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :- + '$prepare_call_clause'(N2,O2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2), + ( '$call_inline'(N2) + ; expand_call_goal(N2,O2,P2), + strip_subst_module(P2,O2,Q2,R2), + '$call_with_inference_counting'('$module_call'(Q2,R2)) ). diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 0a4eb6f4..6e12b8c6 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -390,7 +390,6 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result<Numbe pub(crate) fn pow(n1: Number, n2: Number, culprit: Atom) -> Result<Number, MachineStubGen> { if n2.is_negative() && n1.is_zero() { let stub_gen = move || functor_stub(culprit, 2); - return Err(undefined_eval_error(stub_gen)); } @@ -1183,7 +1182,7 @@ impl MachineState { let result = arena_alloc!( drop_iter_on_err!(self, iter, rdiv(r1, r2)), - self.arena + &mut self.arena ); self.interms.push(Number::Rational(result)); diff --git a/src/machine/attributed_variables.pl b/src/machine/attributed_variables.pl index 9756293e..8c656e31 100644 --- a/src/machine/attributed_variables.pl +++ b/src/machine/attributed_variables.pl @@ -28,11 +28,13 @@ call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :- sort(Modules0, Modules), verify_attrs(Modules, Var, Value, ListOfGoalLists). +error_handler(M, evaluation_error((M:verify_attributes)/3), []). +% error_handler(_, existence_error(procedure, verify_attributes/3), []). verify_attrs([Module|Modules], Var, Value, [Module-Goals|ListOfGoalLists]) :- catch(Module:verify_attributes(Var, Value, Goals), - error(evaluation_error((Module:verify_attributes)/3), verify_attributes/3), - Goals = []), + error(E, verify_attributes/3), + error_handler(Module, E, Goals)), verify_attrs(Modules, Var, Value, ListOfGoalLists). verify_attrs([], _, _, []). diff --git a/src/machine/compile.rs b/src/machine/compile.rs index f85a06e9..d7f2492c 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -406,7 +406,7 @@ fn merge_indexed_subsequences( *o = 0; - return Some(IndexPtr::Index(outer_threaded_choice_instr_loc + 1)); + return Some(IndexPtr::index(outer_threaded_choice_instr_loc + 1)); } _ => {} }, @@ -785,7 +785,7 @@ fn remove_non_leading_clause( *o = 0; - Some(IndexPtr::Index(preceding_choice_instr_loc + 1)) + Some(IndexPtr::index(preceding_choice_instr_loc + 1)) } _ => { unreachable!(); @@ -820,7 +820,7 @@ fn finalize_retract( retraction_info, &compilation_target, key, - &code_index, + code_index, index_ptr, ); } @@ -849,9 +849,9 @@ fn remove_leading_unindexed_clause( retraction_info, ); - Some(IndexPtr::Index(index_ptr)) + Some(IndexPtr::index(index_ptr)) } else { - Some(IndexPtr::DynamicUndefined) + Some(IndexPtr::dynamic_undefined()) } } _ => { @@ -1131,9 +1131,9 @@ fn prepend_compiled_clause( }; if skeleton.core.is_dynamic { - IndexPtr::DynamicIndex(clause_loc) + IndexPtr::dynamic_index(clause_loc) } else { - IndexPtr::Index(clause_loc) + IndexPtr::index(clause_loc) } } @@ -1268,9 +1268,9 @@ fn append_compiled_clause( code_ptr_opt.map(|p| { if skeleton.core.is_dynamic { - IndexPtr::DynamicIndex(p) + IndexPtr::dynamic_index(p) } else { - IndexPtr::Index(p) + IndexPtr::index(p) } }) } @@ -1306,8 +1306,8 @@ fn print_overwrite_warning( } } - match code_ptr { - IndexPtr::DynamicUndefined | IndexPtr::Undefined => return, + match code_ptr.tag() { + IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined => return, _ if is_dynamic => return, _ => {} } @@ -1471,16 +1471,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { ); let index_ptr = if settings.is_dynamic() { - IndexPtr::DynamicIndex(code_ptr) + IndexPtr::dynamic_index(code_ptr) } else { - IndexPtr::Index(code_ptr) + IndexPtr::index(code_ptr) }; set_code_index( &mut self.payload.retraction_info, &predicates.compilation_target, key, - &code_index, + code_index, index_ptr, ); @@ -1704,7 +1704,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { &mut self.payload.retraction_info, &compilation_target, key, - &code_index, + code_index, new_code_ptr, ); } @@ -1745,7 +1745,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { &mut self.payload.retraction_info, &compilation_target, key, - &code_index, + code_index, new_code_ptr, ); @@ -1870,7 +1870,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { skeleton.clauses[target_pos].clause_start; let index_ptr_opt = if target_pos == 0 { - Some(IndexPtr::Index(clause_loc)) + Some(IndexPtr::index(clause_loc)) } else { None }; @@ -2384,13 +2384,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { match self.wam_prelude.indices.modules.get_mut(&filename) { Some(ref mut module) => { let index_ptr = code_index.get(); - let code_index = module.code_dir.entry(key).or_insert(code_index); + let code_index = module.code_dir.entry(key) + .or_insert(code_index) + .clone(); set_code_index( &mut self.payload.retraction_info, &CompilationTarget::Module(filename), key, - &code_index, + code_index, index_ptr, ); } @@ -2418,3 +2420,54 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { Ok(()) } } + +// standalone functions for compiling auxiliary goals used by expand_goal. +impl Machine { + pub(crate) fn get_or_insert_qualified_code_index( + &mut self, + module_name: HeapCellValue, + key: PredicateKey, + ) -> CodeIndex { + let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new( + self, + InlineTermStream {}, + ); + + let module_name = if module_name.get_tag() == HeapCellValueTag::Atom { + cell_as_atom!(module_name) + } else { + atom!("user") + }; + + loader.get_or_insert_qualified_code_index(module_name, key) + } + + pub(crate) fn compile_standalone_clause( + &mut self, + term_loc: RegType, + vars: &[Term], + ) -> Result<(), SessionError> { + let mut compile = || { + let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new( + self, + InlineTermStream {}, + ); + + let term = loader.read_term_from_heap(term_loc)?; + let clause = build_rule_body(vars, term); + + let settings = CodeGenSettings { + global_clock_tick: None, + is_extensible: false, + non_counted_bt: true, + }; + + loader.compile_standalone_clause(clause, settings) + }; + + let StandaloneCompileResult { clause_code, .. } = compile()?; + self.code.extend(clause_code.into_iter()); + + Ok(()) + } +} diff --git a/src/machine/copier.rs b/src/machine/copier.rs index fd016fd6..53325332 100644 --- a/src/machine/copier.rs +++ b/src/machine/copier.rs @@ -1,4 +1,5 @@ use crate::atom_table::*; +use crate::machine::get_structure_index; use crate::machine::stack::*; use crate::types::*; @@ -248,6 +249,14 @@ impl<T: CopierTarget> CopyTermState<T> { let hcv = self.target[addr + 1 + i]; self.target.push(hcv); } + + let index_cell = self.target[addr + 1 + arity]; + + if get_structure_index(index_cell).is_some() { + // copy the index pointer trailing this + // inlined or expanded goal. + self.target.push(index_cell); + } } (HeapCellValueTag::Str, h) => { *self.value_at_scan() = str_loc_as_cell!(h); diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 47f67da0..ee57a83e 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -57,18 +57,28 @@ impl MachineState { let a2 = self.registers[2]; let a3 = self.registers[3]; + let check_atom = |machine_st: &mut MachineState, name: Atom, arity: usize| -> Result<(), MachineStub> { + match name { + atom!(">") | atom!("<") | atom!("=") if arity == 0 => { + Ok(()) + } + _ => { + let err = machine_st.domain_error(DomainErrorType::Order, a1); + Err(machine_st.error_form(err, stub_gen())) + } + } + }; + read_heap_cell!(a1, (HeapCellValueTag::Atom, (name, arity)) => { debug_assert_eq!(arity, 0); + check_atom(self, name, arity)?; + } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); - match name { - atom!(">") | atom!("<") | atom!("=") => { - } - _ => { - let err = self.domain_error(DomainErrorType::Order, a1); - return Err(self.error_form(err, stub_gen())); - } - } + check_atom(self, name, arity)?; } (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { } @@ -360,8 +370,15 @@ impl Machine { debug_assert!(arity == 0); c } - (HeapCellValueTag::Str) => { - s + (HeapCellValueTag::Str, st) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[st]) + .get_name_and_arity(); + + match (name, arity) { + (atom!("."), 2) => l, + (_, 0) => c, + _ => s, + } } (HeapCellValueTag::Cons, ptr) => { match ptr.get_tag() { @@ -421,6 +438,9 @@ impl Machine { debug_assert_eq!(arity, 0); Literal::Atom(atom) } + (HeapCellValueTag::Str, s) => { + Literal::Atom(cell_as_atom_cell!(self.machine_st.heap[s]).get_name()) + } (HeapCellValueTag::Cons, cons_ptr) => { match_untyped_arena_ptr!(cons_ptr, (ArenaHeaderTag::Rational, r) => { @@ -597,6 +617,7 @@ impl Machine { &mut self.machine_st, try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen) ); + self.machine_st.p += 1; } &Instruction::Mul(ref a1, ref a2, t) => { @@ -675,7 +696,7 @@ impl Machine { self.machine_st.interms[t - 1] = Number::Rational(arena_alloc!( try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)), - self.machine_st.arena + &mut self.machine_st.arena )); self.machine_st.p += 1; @@ -688,6 +709,7 @@ impl Machine { &mut self.machine_st, int_floor_div(n1, n2, &mut self.machine_st.arena) ); + self.machine_st.p += 1; } &Instruction::IDiv(ref a1, ref a2, t) => { @@ -698,6 +720,7 @@ impl Machine { &mut self.machine_st, idiv(n1, n2, &mut self.machine_st.arena) ); + self.machine_st.p += 1; } &Instruction::Abs(ref a1, t) => { @@ -1122,17 +1145,7 @@ impl Machine { ); } &Instruction::NeckCut => { - let b = self.machine_st.b; - let b0 = self.machine_st.b0; - - if b > b0 { - self.machine_st.b = b0; - - if b > self.machine_st.e { - self.machine_st.stack.truncate(b); - } - } - + self.machine_st.neck_cut(); self.machine_st.p += 1; } &Instruction::GetLevel(r) => { @@ -1298,7 +1311,6 @@ impl Machine { } &Instruction::DefaultCallRead(_) => { try_or_throw!(self.machine_st, self.read()); - step_or_fail!(self, self.machine_st.p += 1); } &Instruction::DefaultExecuteRead(_) => { @@ -2354,6 +2366,16 @@ impl Machine { self.machine_st.backtrack(); } } + (HeapCellValueTag::Str, s) => { + let arity = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_arity(); + + if arity == 0 { + self.machine_st.p += 1; + } else { + self.machine_st.backtrack(); + } + } (HeapCellValueTag::Char) => { self.machine_st.p += 1; } @@ -2373,6 +2395,16 @@ impl Machine { self.machine_st.backtrack(); } } + (HeapCellValueTag::Str, s) => { + let arity = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_arity(); + + if arity == 0 { + self.machine_st.p = self.machine_st.cp; + } else { + self.machine_st.backtrack(); + } + } (HeapCellValueTag::Char) => { self.machine_st.p = self.machine_st.cp; } @@ -2396,6 +2428,16 @@ impl Machine { self.machine_st.backtrack(); } } + (HeapCellValueTag::Str, s) => { + let arity = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_arity(); + + if arity == 0 { + self.machine_st.p += 1; + } else { + self.machine_st.backtrack(); + } + } _ => { self.machine_st.backtrack(); } @@ -2416,6 +2458,16 @@ impl Machine { self.machine_st.backtrack(); } } + (HeapCellValueTag::Str, s) => { + let arity = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_arity(); + + if arity == 0 { + self.machine_st.p = self.machine_st.cp; + } else { + self.machine_st.backtrack(); + } + } _ => { self.machine_st.backtrack(); } @@ -2425,10 +2477,21 @@ impl Machine { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, - (HeapCellValueTag::Str | HeapCellValueTag::Lis | - HeapCellValueTag::PStrLoc | HeapCellValueTag::CStr) => { + (HeapCellValueTag::Lis | + HeapCellValueTag::PStrLoc | + HeapCellValueTag::CStr) => { self.machine_st.p += 1; } + (HeapCellValueTag::Str, s) => { + let arity = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_arity(); + + if arity > 0 { + self.machine_st.p += 1; + } else { + self.machine_st.backtrack(); + } + } (HeapCellValueTag::Atom, (_name, arity)) => { if arity > 0 { self.machine_st.p += 1; @@ -2445,10 +2508,21 @@ impl Machine { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, - (HeapCellValueTag::Str | HeapCellValueTag::Lis | - HeapCellValueTag::PStrLoc | HeapCellValueTag::CStr) => { + (HeapCellValueTag::Lis | + HeapCellValueTag::PStrLoc | + HeapCellValueTag::CStr) => { self.machine_st.p = self.machine_st.cp; } + (HeapCellValueTag::Str, s) => { + let arity = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_arity(); + + if arity > 0 { + self.machine_st.p = self.machine_st.cp; + } else { + self.machine_st.backtrack(); + } + } (HeapCellValueTag::Atom, (_name, arity)) => { if arity > 0 { self.machine_st.p = self.machine_st.cp; @@ -2744,6 +2818,19 @@ impl Machine { self.machine_st.s_offset = 0; self.machine_st.mode = MachineMode::Read; } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + if name == atom!(".") && arity == 2 { + self.machine_st.s = HeapPtr::HeapCell(s+1); + self.machine_st.s_offset = 0; + self.machine_st.mode = MachineMode::Read; + } else { + self.machine_st.backtrack(); + continue; + } + } (HeapCellValueTag::Lis, l) => { self.machine_st.s = HeapPtr::HeapCell(l); self.machine_st.s_offset = 0; @@ -3500,7 +3587,10 @@ impl Machine { self.dynamic_module_resolution(arity - 2) ); - try_or_throw!(self.machine_st, self.call_clause(module_name, key)); + try_or_throw!( + self.machine_st, + self.call_clause(module_name, key) + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -3512,7 +3602,10 @@ impl Machine { self.dynamic_module_resolution(arity - 2) ); - try_or_throw!(self.machine_st, self.execute_clause(module_name, key)); + try_or_throw!( + self.machine_st, + self.execute_clause(module_name, key) + ); if self.machine_st.fail { self.machine_st.backtrack(); @@ -4032,14 +4125,6 @@ impl Machine { self.clean_up_block(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallEraseBall(_) => { - self.erase_ball(); - self.machine_st.p += 1; - } - &Instruction::ExecuteEraseBall(_) => { - self.erase_ball(); - self.machine_st.p = self.machine_st.cp; - } &Instruction::CallFail(_) | &Instruction::ExecuteFail(_) => { self.machine_st.backtrack(); } @@ -4123,6 +4208,30 @@ impl Machine { try_or_throw!(self.machine_st, self.http_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } + &Instruction::CallHttpListen(_) => { + try_or_throw!(self.machine_st, self.http_listen()); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteHttpListen(_) => { + try_or_throw!(self.machine_st, self.http_listen()); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } + &Instruction::CallHttpAccept(_) => { + try_or_throw!(self.machine_st, self.http_accept()); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteHttpAccept(_) => { + try_or_throw!(self.machine_st, self.http_accept()); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } + &Instruction::CallHttpAnswer(_) => { + try_or_throw!(self.machine_st, self.http_answer()); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteHttpAnswer(_) => { + try_or_throw!(self.machine_st, self.http_answer()); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } &Instruction::CallCurrentTime(_) => { self.current_time(); step_or_fail!(self, self.machine_st.p += 1); @@ -4167,6 +4276,30 @@ impl Machine { self.set_ball(); self.machine_st.p = self.machine_st.cp; } + &Instruction::CallPushBallStack(_) => { + self.push_ball_stack(); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecutePushBallStack(_) => { + self.push_ball_stack(); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } + &Instruction::CallPopBallStack(_) => { + self.pop_ball_stack(); + self.machine_st.p += 1; + } + &Instruction::ExecutePopBallStack(_) => { + self.pop_ball_stack(); + self.machine_st.p = self.machine_st.cp; + } + &Instruction::CallPopFromBallStack(_) => { + self.pop_from_ball_stack(); + self.machine_st.p += 1; + } + &Instruction::ExecutePopFromBallStack(_) => { + self.pop_from_ball_stack(); + self.machine_st.p = self.machine_st.cp; + } &Instruction::CallSetCutPointByDefault(r, _) => { self.set_cut_point_by_default(r); step_or_fail!(self, self.machine_st.p += 1); @@ -4853,11 +4986,11 @@ impl Machine { } &Instruction::CallPredicateDefined(_) => { self.machine_st.fail = !self.predicate_defined(); - self.machine_st.p += 1; + step_or_fail!(self, self.machine_st.p += 1); } &Instruction::ExecutePredicateDefined(_) => { self.machine_st.fail = !self.predicate_defined(); - self.machine_st.p = self.machine_st.cp; + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } &Instruction::CallStripModule(_) => { let (module_loc, qualified_goal) = self.machine_st.strip_module( @@ -4886,7 +5019,7 @@ impl Machine { &Instruction::ExecuteStripModule(_) => { let (module_loc, qualified_goal) = self.machine_st.strip_module( self.machine_st.registers[1], - self.machine_st.registers[2] + self.machine_st.registers[2], ); let target_module_loc = self.machine_st.registers[2]; @@ -4915,6 +5048,54 @@ impl Machine { try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } + &Instruction::CallCompileInlineOrExpandedGoal(_) => { + try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteCompileInlineOrExpandedGoal(_) => { + try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } + &Instruction::CallIsExpandedOrInlined(_) => { + self.machine_st.fail = !self.is_expanded_or_inlined(); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteIsExpandedOrInlined(_) => { + self.machine_st.fail = !self.is_expanded_or_inlined(); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } + &Instruction::CallInlineCallN(arity, _) => { + let call_at_index = |wam: &mut Machine, name, arity, ptr| { + wam.try_call(name, arity, ptr) + }; + + try_or_throw!(self.machine_st, self.call_inline(arity, call_at_index)); + + if self.machine_st.fail { + self.machine_st.backtrack(); + } else { + try_or_throw!( + self.machine_st, + (self.machine_st.increment_call_count_fn)(&mut self.machine_st) + ); + } + } + &Instruction::ExecuteInlineCallN(arity, _) => { + let call_at_index = |wam: &mut Machine, name, arity, ptr| { + wam.try_execute(name, arity, ptr) + }; + + try_or_throw!(self.machine_st, self.call_inline(arity, call_at_index)); + + if self.machine_st.fail { + self.machine_st.backtrack(); + } else { + try_or_throw!( + self.machine_st, + (self.machine_st.increment_call_count_fn)(&mut self.machine_st) + ); + } + } } } diff --git a/src/machine/gc.rs b/src/machine/gc.rs index 05bd70d6..8a884950 100644 --- a/src/machine/gc.rs +++ b/src/machine/gc.rs @@ -2,6 +2,9 @@ use crate::atom_table::*; use crate::machine::heap::*; use crate::types::*; +#[cfg(test)] +use crate::heap_iter::FocusedHeapIter; + use core::marker::PhantomData; pub(crate) trait UnmarkPolicy { @@ -69,6 +72,14 @@ pub(crate) struct StacklessPreOrderHeapIter<'a, UMP: UnmarkPolicy> { _marker: PhantomData<UMP>, } +#[cfg(test)] +impl<'a> FocusedHeapIter for StacklessPreOrderHeapIter<'a, IteratorUMP> { + #[inline] + fn focus(&self) -> usize { + self.current + } +} + impl<'a, UMP: UnmarkPolicy> Drop for StacklessPreOrderHeapIter<'a, UMP> { fn drop(&mut self) { if self.current == self.start { diff --git a/src/machine/heap.rs b/src/machine/heap.rs index 830a7cce..59e63009 100644 --- a/src/machine/heap.rs +++ b/src/machine/heap.rs @@ -1,6 +1,7 @@ use crate::arena::*; use crate::atom_table::*; use crate::forms::*; +use crate::machine::machine_indices::*; use crate::machine::partial_string::*; use crate::parser::ast::*; use crate::types::*; @@ -17,6 +18,9 @@ impl From<Literal> for HeapCellValue { match literal { Literal::Atom(name) => atom_as_cell!(name), Literal::Char(c) => char_as_cell!(c), + Literal::CodeIndex(ptr) => { + untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(ptr)) + } Literal::Fixnum(n) => fixnum_as_cell!(n), Literal::Integer(bigint_ptr) => { typed_arena_ptr_as_cell!(bigint_ptr) @@ -65,6 +69,9 @@ impl TryFrom<HeapCellValue> for Literal { (ArenaHeaderTag::Rational, n) => { Ok(Literal::Rational(n)) } + (ArenaHeaderTag::IndexPtr, _ip) => { + Ok(Literal::CodeIndex(CodeIndex::from(cons_ptr))) + } _ => { Err(()) } diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index e7f88095..802d51eb 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -21,12 +21,12 @@ pub(super) fn set_code_index( retraction_info: &mut RetractionInfo, compilation_target: &CompilationTarget, key: PredicateKey, - code_index: &CodeIndex, + mut code_index: CodeIndex, code_ptr: IndexPtr, ) { let record = match compilation_target { CompilationTarget::User => { - if IndexPtr::Undefined == code_index.get() { + if IndexPtrTag::Undefined == code_index.get().tag() { code_index.set(code_ptr); RetractionRecord::AddedUserPredicate(key) } else { @@ -35,7 +35,7 @@ pub(super) fn set_code_index( } } CompilationTarget::Module(ref module_name) => { - if IndexPtr::Undefined == code_index.get() { + if IndexPtrTag::Undefined == code_index.get().tag() { code_index.set(code_ptr); RetractionRecord::AddedModulePredicate(*module_name, key) } else { @@ -48,12 +48,10 @@ pub(super) fn set_code_index( retraction_info.push_record(record); } -fn add_op_decl_as_module_export( +fn add_op_decl_as_module_export<'a, LS: LoadState<'a>>( + payload: &mut LS::LoaderFieldType, module_op_dir: &mut OpDir, - compilation_target: &CompilationTarget, - retraction_info: &mut RetractionInfo, wam_op_dir: &mut OpDir, - module_op_exports: &mut ModuleOpExports, op_decl: &OpDecl, ) { /* @@ -65,20 +63,21 @@ fn add_op_decl_as_module_export( match op_decl.insert_into_op_dir(wam_op_dir) { Some(op_desc) => { - retraction_info.push_record(RetractionRecord::ReplacedUserOp( + payload.retraction_info.push_record(RetractionRecord::ReplacedUserOp( *op_decl, op_desc, )); - module_op_exports.push((*op_decl, Some(op_desc))); + payload.module_op_exports.push((*op_decl, Some(op_desc))); } None => { - retraction_info.push_record(RetractionRecord::AddedUserOp(*op_decl)); - module_op_exports.push((*op_decl, None)); + payload.retraction_info.push_record(RetractionRecord::AddedUserOp(*op_decl)); + payload.module_op_exports.push((*op_decl, None)); } } - add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl); + let compilation_target = payload.compilation_target; + add_op_decl(&mut payload.retraction_info, &compilation_target, module_op_dir, op_decl); } pub(super) fn add_op_decl( @@ -117,8 +116,8 @@ pub(super) fn add_op_decl( } } -pub(super) fn import_module_exports( - retraction_info: &mut RetractionInfo, +pub(super) fn import_module_exports<'a, LS: LoadState<'a>>( + payload: &mut LS::LoaderFieldType, compilation_target: &CompilationTarget, imported_module: &Module, code_dir: &mut CodeDir, @@ -135,16 +134,18 @@ pub(super) fn import_module_exports( } if let Some(src_code_index) = imported_module.code_dir.get(&key) { + let arena = &mut LS::machine_st(payload).arena; + let target_code_index = code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::default(arena)) .clone(); set_code_index( - retraction_info, + &mut payload.retraction_info, compilation_target, key, - &target_code_index, + target_code_index, src_code_index.get(), ); } else { @@ -155,7 +156,7 @@ pub(super) fn import_module_exports( } } ModuleExport::OpDecl(ref op_decl) => { - add_op_decl(retraction_info, compilation_target, op_dir, op_decl); + add_op_decl(&mut payload.retraction_info, compilation_target, op_dir, op_decl); } } } @@ -163,15 +164,14 @@ pub(super) fn import_module_exports( Ok(()) } -fn import_module_exports_into_module( - retraction_info: &mut RetractionInfo, +fn import_module_exports_into_module<'a, LS: LoadState<'a>>( + payload: &mut LS::LoaderFieldType, compilation_target: &CompilationTarget, imported_module: &Module, code_dir: &mut CodeDir, op_dir: &mut OpDir, meta_predicates: &mut MetaPredicateDir, wam_op_dir: &mut OpDir, - module_op_exports: &mut ModuleOpExports, ) -> Result<(), SessionError> { for export in imported_module.module_decl.exports.iter() { match export { @@ -183,16 +183,18 @@ fn import_module_exports_into_module( } if let Some(src_code_index) = imported_module.code_dir.get(&key) { + let arena = &mut LS::machine_st(payload).arena; + let target_code_index = code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::default(arena)) .clone(); set_code_index( - retraction_info, + &mut payload.retraction_info, compilation_target, key, - &target_code_index, + target_code_index, src_code_index.get(), ); } else { @@ -203,12 +205,10 @@ fn import_module_exports_into_module( } } ModuleExport::OpDecl(ref op_decl) => { - add_op_decl_as_module_export( + add_op_decl_as_module_export::<LS>( + payload, op_dir, - compilation_target, - retraction_info, wam_op_dir, - module_op_exports, op_decl, ); } @@ -218,14 +218,12 @@ fn import_module_exports_into_module( Ok(()) } -fn import_qualified_module_exports( - retraction_info: &mut RetractionInfo, +fn import_qualified_module_exports<'a, LS: LoadState<'a>>( + payload: &mut LS::LoaderFieldType, compilation_target: &CompilationTarget, imported_module: &Module, exports: &IndexSet<ModuleExport>, - code_dir: &mut CodeDir, - op_dir: &mut OpDir, - meta_predicates: &mut MetaPredicateDir, + wam_prelude: &mut MachinePreludeView, ) -> Result<(), SessionError> { for export in imported_module.module_decl.exports.iter() { if !exports.contains(export) { @@ -237,20 +235,22 @@ fn import_qualified_module_exports( let key = (*name, *arity); if let Some(meta_specs) = imported_module.meta_predicates.get(&key) { - meta_predicates.insert(key.clone(), meta_specs.clone()); + wam_prelude.indices.meta_predicates.insert(key.clone(), meta_specs.clone()); } if let Some(src_code_index) = imported_module.code_dir.get(&key) { - let target_code_index = code_dir + let arena = &mut LS::machine_st(payload).arena; + + let target_code_index = wam_prelude.indices.code_dir .entry(key.clone()) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)) .clone(); set_code_index( - retraction_info, + &mut payload.retraction_info, compilation_target, key, - &target_code_index, + target_code_index, src_code_index.get(), ); } else { @@ -261,7 +261,12 @@ fn import_qualified_module_exports( } } ModuleExport::OpDecl(ref op_decl) => { - add_op_decl(retraction_info, compilation_target, op_dir, op_decl); + add_op_decl( + &mut payload.retraction_info, + compilation_target, + &mut wam_prelude.indices.op_dir, + op_decl, + ); } } } @@ -269,17 +274,17 @@ fn import_qualified_module_exports( Ok(()) } -fn import_qualified_module_exports_into_module( - retraction_info: &mut RetractionInfo, - compilation_target: &CompilationTarget, +fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>( + payload: &mut LS::LoaderFieldType, imported_module: &Module, exports: &IndexSet<ModuleExport>, code_dir: &mut CodeDir, op_dir: &mut OpDir, meta_predicates: &mut MetaPredicateDir, wam_op_dir: &mut OpDir, - module_op_exports: &mut ModuleOpExports, ) -> Result<(), SessionError> { + let payload_compilation_target = payload.compilation_target; + for export in imported_module.module_decl.exports.iter() { if !exports.contains(export) { continue; @@ -294,16 +299,18 @@ fn import_qualified_module_exports_into_module( } if let Some(src_code_index) = imported_module.code_dir.get(&key) { + let arena = &mut LS::machine_st(payload).arena; + let target_code_index = code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)) .clone(); set_code_index( - retraction_info, - compilation_target, + &mut payload.retraction_info, + &payload_compilation_target, key, - &target_code_index, + target_code_index, src_code_index.get(), ); } else { @@ -314,12 +321,10 @@ fn import_qualified_module_exports_into_module( } } ModuleExport::OpDecl(ref op_decl) => { - add_op_decl_as_module_export( + add_op_decl_as_module_export::<LS>( + payload, op_dir, - compilation_target, - retraction_info, wam_op_dir, - module_op_exports, op_decl, ); } @@ -464,7 +469,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { None => return, }; - for (key, code_index) in &removed_module.code_dir { + for (key, code_index) in removed_module.code_dir.iter_mut() { match removed_module .local_extensible_predicates .get(&(CompilationTarget::User, *key)) @@ -473,7 +478,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { _ => {} } - let old_index_ptr = code_index.replace(IndexPtr::Undefined); + let old_index_ptr = code_index.replace(IndexPtr::undefined()); self.payload.retraction_info .push_record(RetractionRecord::ReplacedModulePredicate( @@ -512,11 +517,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { for export in removed_module.module_decl.exports.iter() { match export { ModuleExport::PredicateKey(ref key) => { - match (removed_module.code_dir.get(key), code_dir.get(key)) { + match (removed_module.code_dir.get(key), code_dir.get_mut(key)) { (Some(module_code_index), Some(target_code_index)) if module_code_index.get() == target_code_index.get() => { - let old_index_ptr = target_code_index.replace(IndexPtr::Undefined); + let old_index_ptr = target_code_index.replace(IndexPtr::undefined()); retraction_info.push_record(predicate_retractor(*key, old_index_ptr)); } _ => {} @@ -584,7 +589,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { Some(ref mut module) => module .code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::new( + IndexPtr::undefined(), + &mut LS::machine_st(&mut self.payload).arena, + )) .clone(), None => { self.add_dynamically_generated_module(module_name); @@ -593,7 +601,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { Some(ref mut module) => module .code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::new( + IndexPtr::undefined(), + &mut LS::machine_st(&mut self.payload).arena, + )) .clone(), None => { unreachable!() @@ -608,13 +619,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { key: PredicateKey, compilation_target: CompilationTarget, ) -> CodeIndex { + let arena = &mut LS::machine_st(&mut self.payload).arena; + match compilation_target { CompilationTarget::User => self .wam_prelude .indices .code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)) .clone(), CompilationTarget::Module(module_name) => { self.get_or_insert_local_code_index(module_name, key) @@ -627,13 +640,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { module_name: Atom, key: PredicateKey, ) -> CodeIndex { + let arena = &mut LS::machine_st(&mut self.payload).arena; + if module_name == atom!("user") { return self .wam_prelude .indices .code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) + .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)) .clone(); } else { self.get_or_insert_local_code_index(module_name, key) @@ -732,14 +747,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { CompilationTarget::Module(ref module_name) => { match self.wam_prelude.indices.modules.get_mut(module_name) { Some(ref mut module) => { - let payload: &mut LoadStatePayload<_> = &mut self.payload; - - add_op_decl_as_module_export( + add_op_decl_as_module_export::<LS>( + &mut self.payload, &mut module.op_dir, - &payload.compilation_target, - &mut payload.retraction_info, &mut self.wam_prelude.indices.op_dir, - &mut payload.module_op_exports, op_decl, ); } @@ -752,7 +763,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { } pub(super) fn get_clause_type(&mut self, name: Atom, arity: usize) -> ClauseType { - match ClauseType::from(name, arity) { + let arena = &mut LS::machine_st(&mut self.payload).arena; + + match ClauseType::from(name, arity, arena) { ClauseType::Named(arity, name, _) => { let payload_compilation_target = self.payload.compilation_target; @@ -773,7 +786,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { name: Atom, arity: usize, ) -> ClauseType { - match ClauseType::from(name, arity) { + let arena = &mut LS::machine_st(&mut self.payload).arena; + + match ClauseType::from(name, arity, arena) { ClauseType::Named(arity, name, _) => { let key = (name, arity); let idx = self.get_or_insert_qualified_code_index(module_name, key); @@ -784,6 +799,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { } } + pub(super) fn get_meta_specs(&self, name: Atom, arity: usize) -> Option<&Vec<MetaSpec>> { + self.wam_prelude + .indices + .get_meta_predicate_spec( + name, + arity, + &self.payload.compilation_target, + ) + } + pub(super) fn add_meta_predicate_record( &mut self, module_name: Atom, @@ -894,8 +919,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { return; } - import_module_exports( - &mut self.payload.retraction_info, + import_module_exports::<LS>( + &mut self.payload, &module_compilation_target, builtins, code_dir, @@ -992,14 +1017,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { for export in &module.module_decl.exports { if let ModuleExport::OpDecl(ref op_decl) = export { - let payload: &mut LoadStatePayload<_> = &mut self.payload; - - add_op_decl_as_module_export( + add_op_decl_as_module_export::<LS>( + &mut self.payload, &mut module.op_dir, - &payload.compilation_target, // this is a Module. - &mut payload.retraction_info, &mut self.wam_prelude.indices.op_dir, - &mut payload.module_op_exports, op_decl, ); } @@ -1018,8 +1039,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { match &payload_compilation_target { CompilationTarget::User => { - import_module_exports( - &mut self.payload.retraction_info, + import_module_exports::<LS>( + &mut self.payload, &payload_compilation_target, &module, &mut self.wam_prelude.indices.code_dir, @@ -1030,17 +1051,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { CompilationTarget::Module(ref defining_module_name) => { match self.wam_prelude.indices.modules.get_mut(defining_module_name) { Some(ref mut target_module) => { - let payload: &mut LoadStatePayload<_> = &mut self.payload; - - import_module_exports_into_module( - &mut payload.retraction_info, + import_module_exports_into_module::<LS>( + &mut self.payload, &payload_compilation_target, &module, &mut target_module.code_dir, &mut target_module.op_dir, &mut target_module.meta_predicates, &mut self.wam_prelude.indices.op_dir, - &mut payload.module_op_exports, )?; } None => { @@ -1070,47 +1088,38 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { if let Some(module) = self.wam_prelude.indices.modules.remove(&module_name) { let payload_compilation_target = self.payload.compilation_target; - match &payload_compilation_target { + let result = match &payload_compilation_target { CompilationTarget::User => { - import_qualified_module_exports( - &mut self.payload.retraction_info, + import_qualified_module_exports::<LS>( + &mut self.payload, &payload_compilation_target, &module, &exports, - &mut self.wam_prelude.indices.code_dir, - &mut self.wam_prelude.indices.op_dir, - &mut self.wam_prelude.indices.meta_predicates, - )?; + &mut self.wam_prelude, + ) } CompilationTarget::Module(ref defining_module_name) => { match self.wam_prelude.indices.modules.get_mut(defining_module_name) { Some(ref mut target_module) => { - let payload: &mut LoadStatePayload<_> = &mut self.payload; - - import_qualified_module_exports_into_module( - &mut payload.retraction_info, - &payload_compilation_target, + import_qualified_module_exports_into_module::<LS>( + &mut self.payload, &module, &exports, &mut target_module.code_dir, &mut target_module.op_dir, &mut target_module.meta_predicates, &mut self.wam_prelude.indices.op_dir, - &mut payload.module_op_exports, - )?; + ) } None => { - // we find ourselves here because we're trying to import - // a module into itself as it is being defined. - self.wam_prelude.indices.modules.insert(module_name, module); - return Err(SessionError::ModuleCannotImportSelf(module_name)); + Err(SessionError::ModuleCannotImportSelf(module_name)) } } } - } + }; self.wam_prelude.indices.modules.insert(module_name, module); - Ok(()) + result } else { Err(SessionError::ExistenceError(ExistenceError::Module(module_name))) } @@ -1168,7 +1177,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { indices: self.wam_prelude.indices, code: self.wam_prelude.code, load_contexts: self.wam_prelude.load_contexts, - } + }, }; subloader.load()? @@ -1231,7 +1240,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { indices: self.wam_prelude.indices, code: self.wam_prelude.code, load_contexts: self.wam_prelude.load_contexts, - } + }, }; subloader.load()? diff --git a/src/machine/loader.rs b/src/machine/loader.rs index c974540f..616fe7ee 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -390,6 +390,64 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> { } } +pub struct InlineLoadState<'a> { + machine_st: &'a mut MachineState, + pub payload: LoadStatePayload<InlineTermStream>, +} + +impl<'a> Deref for InlineLoadState<'a> { + type Target = LoadStatePayload<InlineTermStream>; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.payload + } +} + +impl<'a> DerefMut for InlineLoadState<'a> { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.payload + } +} + +impl<'a> LoadState<'a> for InlineLoadState<'a> { + type TS = InlineTermStream; + type LoaderFieldType = InlineLoadState<'a>; + type Evacuable = (); + + #[inline(always)] + fn new(machine_st: &'a mut MachineState, payload: LoadStatePayload<Self::TS>) -> Self::LoaderFieldType { + InlineLoadState { machine_st, payload } + } + + fn evacuate(_loader: Loader<'a, Self>) -> Result<Self::Evacuable, SessionError> { + Ok(()) + } + + #[inline(always)] + fn should_drop_load_state(_loader: &Loader<'a, Self>) -> bool { + false + } + + #[inline(always)] + fn reset_machine(_loader: &mut Loader<'a, Self>) { + } + + #[inline(always)] + fn machine_st(load_state: &mut Self::LoaderFieldType) -> &mut MachineState { + &mut load_state.machine_st + } + + #[inline(always)] + fn err_on_builtin_overwrite( + _loader: &Loader<'a, Self>, + _key: PredicateKey, + ) -> Result<(), SessionError> { + Ok(()) + } +} + pub struct Loader<'a, LS: LoadState<'a>> { pub(super) payload: LS::LoaderFieldType, pub(super) wam_prelude: MachinePreludeView<'a>, @@ -510,6 +568,27 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap())); } (HeapCellValueTag::Atom, (name, arity)) => { + let h = iter.focus(); + let mut arity = arity; + + if iter.heap.len() > h + arity + 1 { + let value = iter.heap[h + arity + 1]; + + if let Some(idx) = get_structure_index(value) { + // in the second condition, arity == 0, + // meaning idx cannot pertain to this atom + // if it is the direct subterm of a larger + // structure. + if arity > 0 || !iter.direct_subterm_of_str(h) { + term_stack.push( + Term::Literal(Cell::default(), Literal::CodeIndex(idx)) + ); + + arity += 1; + } + } + } + if arity == 0 { term_stack.push(Term::Literal(Cell::default(), Literal::Atom(name))); } else { @@ -708,7 +787,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { module .code_dir .get_mut(&key) - .map(|code_idx| code_idx.replace(old_code_idx)); + .map(|code_idx| code_idx.set(old_code_idx)); } None => {} } @@ -733,10 +812,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { .indices .code_dir .get_mut(&key) - .map(|code_idx| code_idx.replace(old_code_idx)); + .map(|code_idx| code_idx.set(old_code_idx)); } RetractionRecord::AddedIndex(index_key, clause_loc) => { - // WAS: inner_index_locs) => { if let Some(index_loc) = index_key.switch_on_term_loc() { let indexing_code = match &mut self.wam_prelude.code[index_loc] { Instruction::IndexingCode(indexing_code) => indexing_code, @@ -1271,13 +1349,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { let code_index = self.get_or_insert_code_index(key, compilation_target); - if let IndexPtr::Undefined = code_index.get() { + if code_index.is_undefined() { set_code_index( &mut self.payload.retraction_info, &compilation_target, key, - &code_index, - IndexPtr::DynamicUndefined, + code_index, + IndexPtr::dynamic_undefined(), ); } } @@ -1491,7 +1569,6 @@ impl Machine { let mut loader = self.loader_from_heap_evacuable(temp_v!(3)); let declare_module = || { - // let export_list = export_list?; let exports = loader.extract_module_export_list_from_heap(temp_v!(2))?; let module_decl = ModuleDecl { @@ -1885,13 +1962,10 @@ impl Machine { } } - pub(crate) fn compile_assert<'a>(&'a mut self, append_or_prepend: AppendOrPrepend) -> CallResult { - let key = self - .machine_st - .read_predicate_key(self.machine_st[temp_v!(3)], self.machine_st[temp_v!(4)]); - + pub(crate) fn compile_assert(&mut self, append_or_prepend: AppendOrPrepend) -> CallResult + { let module_name = cell_as_atom!( - self.machine_st.store(self.machine_st.deref(self.machine_st.registers[5])) + self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])) ); let compilation_target = match module_name { @@ -1899,14 +1973,62 @@ impl Machine { _ => CompilationTarget::Module(module_name), }; + let stub_gen = || { + match append_or_prepend { + AppendOrPrepend::Append => functor_stub(atom!("assertz"), 1), + AppendOrPrepend::Prepend => functor_stub(atom!("asserta"), 1), + } + }; + let mut compile_assert = || { let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new(self, LiveTermStream::new(ListingSource::User)); loader.payload.compilation_target = compilation_target; - let head = loader.read_term_from_heap(temp_v!(1))?; - let body = loader.read_term_from_heap(temp_v!(2))?; + let head = loader.read_term_from_heap(temp_v!(2))?; + + let name = if let Some(name) = head.name() { + name + } else { + return Err(SessionError::from(CompilationError::InvalidRuleHead)); + }; + + let arity = head.arity(); + + let is_dynamic_predicate = loader + .wam_prelude + .indices + .is_dynamic_predicate( + module_name, + (name, arity), + ); + + let no_such_predicate = + if !is_dynamic_predicate && !ClauseType::is_inbuilt(name, arity) { + let idx_tag = loader + .wam_prelude + .indices + .get_predicate_code_index( + name, + arity, + module_name, + ) + .map(|code_idx| code_idx.get_tag()) + .unwrap_or(IndexPtrTag::DynamicUndefined); + + idx_tag == IndexPtrTag::DynamicUndefined || + idx_tag == IndexPtrTag::Undefined + } else { + is_dynamic_predicate + }; + + if !no_such_predicate { + LiveLoadAndMachineState::machine_st(&mut loader.payload).fail = true; + return LiveLoadAndMachineState::evacuate(loader); + } + + let body = loader.read_term_from_heap(temp_v!(3))?; let asserted_clause = Term::Clause( Cell::default(), @@ -1915,10 +2037,10 @@ impl Machine { ); // if a new predicate was just created, make it dynamic. - loader.add_dynamic_predicate(compilation_target, key.0, key.1)?; + loader.add_dynamic_predicate(compilation_target, name, arity)?; loader.incremental_compile_clause( - key, + (name, arity), asserted_clause, compilation_target, false, @@ -1929,7 +2051,7 @@ impl Machine { LiveLoadAndMachineState::machine_st(&mut loader.payload).global_clock += 1; loader.compile_clause_clauses( - key, + (name, arity), compilation_target, std::iter::once((head, body)), append_or_prepend, @@ -1940,14 +2062,30 @@ impl Machine { match compile_assert() { Ok(_) => Ok(()), + Err(SessionError::CompilationError( + CompilationError::InvalidRuleHead | + CompilationError::InadmissibleFact + )) => { + let err = self.machine_st.type_error( + ValidType::Callable, + self.machine_st.registers[2], + ); + + Err(self.machine_st.error_form(err, stub_gen())) + } + Err(SessionError::CompilationError( + CompilationError::InadmissibleQueryTerm + )) => { + let err = self.machine_st.type_error( + ValidType::Callable, + self.machine_st.registers[3], + ); + + Err(self.machine_st.error_form(err, stub_gen())) + } Err(e) => { - let stub = match append_or_prepend { - AppendOrPrepend::Append => functor_stub(atom!("assertz"), 1), - AppendOrPrepend::Prepend => functor_stub(atom!("asserta"), 1), - }; let err = self.machine_st.session_error(e); - - Err(self.machine_st.error_form(err, stub)) + Err(self.machine_st.error_form(err, stub_gen())) } } } @@ -2019,10 +2157,10 @@ impl Machine { .indices .remove_predicate_skeleton(&compilation_target, &key); - let code_index = loader + let mut code_index = loader .get_or_insert_code_index(key, compilation_target); - code_index.set(IndexPtr::Undefined); + code_index.set(IndexPtr::undefined()); loader.payload.compilation_target = clause_clause_compilation_target; @@ -2187,7 +2325,7 @@ impl Machine { let (predicate_name, arity) = self .machine_st - .read_predicate_key(self.machine_st[temp_v!(2)], self.machine_st[temp_v!(3)]); + .read_predicate_key(self.machine_st.registers[2], self.machine_st.registers[3]); let compilation_target = match module_name { atom!("user") => CompilationTarget::User, @@ -2309,21 +2447,15 @@ impl Machine { } pub(crate) fn builtin_property(&mut self) { - let key = self + let (name, arity) = self .machine_st .read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]); - match ClauseType::from(key.0, key.1) { - ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN(_) => { + if !ClauseType::is_inbuilt(name, arity) { // ClauseType::from(key.0, key.1, &mut self.machine_st.arena) { + if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) { + self.machine_st.fail = !module.code_dir.contains_key(&(name, arity)); return; } - ClauseType::Named(arity, name, _) => { - if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) { - self.machine_st.fail = !module.code_dir.contains_key(&(name, arity)); - return; - } - } - _ => {} } self.machine_st.fail = true; @@ -2355,14 +2487,19 @@ impl<'a> Loader<'a, LiveLoadAndMachineState<'a>> { #[inline] pub(super) fn load_module( + machine_st: &mut MachineState, code_dir: &mut CodeDir, op_dir: &mut OpDir, meta_predicate_dir: &mut MetaPredicateDir, compilation_target: &CompilationTarget, module: &Module, ) { - import_module_exports( - &mut RetractionInfo::new(0), + let ts = LiveTermStream::new(ListingSource::User); + let payload = LoadStatePayload::new(0, ts); + let mut payload = LiveLoadAndMachineState::new(machine_st, payload); + + import_module_exports::<LiveLoadAndMachineState>( + &mut payload, &compilation_target, module, code_dir, diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 7ea75315..ca2af22e 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -639,10 +639,10 @@ impl CompilationError { &CompilationError::ExpectedRel => { functor!(atom!("expected_relation")) } - &CompilationError::InadmissibleFact => { + &CompilationError::InadmissibleFact => { // TODO: type_error(callable, _). functor!(atom!("inadmissible_fact")) } - &CompilationError::InadmissibleQueryTerm => { + &CompilationError::InadmissibleQueryTerm => { // TODO: type_error(callable, _). functor!(atom!("inadmissible_query_term")) } &CompilationError::InconsistentEntry => { @@ -661,7 +661,8 @@ impl CompilationError { functor!(atom!("no_such_module"), [atom(module_name)]) } &CompilationError::InvalidRuleHead => { - functor!(atom!("invalid_head_of_rule")) + + functor!(atom!("invalid_head_of_rule")) // TODO: type_error(callable, _). } &CompilationError::InvalidUseModuleDecl => { functor!(atom!("invalid_use_module_declaration")) diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index 794b09b1..1fcd41e4 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -4,18 +4,18 @@ use crate::arena::*; use crate::atom_table::*; use crate::fixtures::*; use crate::forms::*; -use crate::instructions::*; use crate::machine::loader::*; use crate::machine::machine_state::*; use crate::machine::streams::Stream; use fxhash::FxBuildHasher; use indexmap::IndexMap; +use modular_bitfield::{BitfieldSpecifier, bitfield}; +use modular_bitfield::specifiers::*; -use std::cell::Cell; use std::cmp::Ordering; use std::collections::BTreeSet; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use std::rc::Rc; use crate::types::*; @@ -59,9 +59,6 @@ impl PartialOrd<Ref> for HeapCellValue { } } (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h1) => { - // _ if self.is_ref() => { - // let h1 = self.get_value(); - match r.get_tag() { RefTag::StackCell => Some(Ordering::Less), _ => { @@ -77,52 +74,157 @@ impl PartialOrd<Ref> for HeapCellValue { } } +#[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq)] +#[bits = 7] +pub enum IndexPtrTag { + DynamicUndefined = 0b1000101, // a predicate, declared as dynamic, whose location in code is as yet undefined. + DynamicIndex = 0b1000110, + Index = 0b1000111, + Undefined = 0b1001000, +} + +#[bitfield] #[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub enum IndexPtr { - DynamicUndefined, // a predicate, declared as dynamic, whose location in code is as yet undefined. - DynamicIndex(usize), - Index(usize), - Undefined, +pub struct IndexPtr { + pub p: B56, + #[allow(unused)] m: bool, + pub tag: IndexPtrTag, } -#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub struct CodeIndex(pub(crate) Rc<Cell<IndexPtr>>); +impl IndexPtr { + #[inline(always)] + pub(crate) fn dynamic_undefined() -> Self { + IndexPtr::new() + .with_p(0) + .with_m(false) + .with_tag(IndexPtrTag::DynamicUndefined) + } + + #[inline(always)] + pub(crate) fn undefined() -> Self { + IndexPtr::new() + .with_p(0) + .with_m(false) + .with_tag(IndexPtrTag::Undefined) + } + + #[inline(always)] + pub(crate) fn dynamic_index(p: usize) -> Self { + IndexPtr::new() + .with_p(p as u64) + .with_m(false) + .with_tag(IndexPtrTag::DynamicIndex) + } + + #[inline(always)] + pub(crate) fn index(p: usize) -> Self { + IndexPtr::new() + .with_p(p as u64) + .with_m(false) + .with_tag(IndexPtrTag::Index) + } + + #[inline(always)] + pub(crate) fn is_undefined(&self) -> bool { + match self.tag() { + IndexPtrTag::Undefined => true, + _ => false, + } + } + + #[inline(always)] + pub(crate) fn is_dynamic_undefined(&self) -> bool { + match self.tag() { + IndexPtrTag::DynamicUndefined => true, + _ => false, + } + } +} + +#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)] +pub struct CodeIndex(TypedArenaPtr<IndexPtr>); + +const_assert!(std::mem::align_of::<CodeIndex>() == 8); impl Deref for CodeIndex { - type Target = Cell<IndexPtr>; + type Target = TypedArenaPtr<IndexPtr>; - #[inline] - fn deref(&self) -> &Self::Target { - self.0.deref() + #[inline(always)] + fn deref(&self) -> &TypedArenaPtr<IndexPtr> { + &self.0 + } +} + +impl DerefMut for CodeIndex { + #[inline(always)] + fn deref_mut(&mut self) -> &mut TypedArenaPtr<IndexPtr> { + &mut self.0 + } +} + +impl From<CodeIndex> for UntypedArenaPtr { + #[inline(always)] + fn from(ptr: CodeIndex) -> UntypedArenaPtr { + unsafe { std::mem::transmute(ptr.0.as_ptr()) } + } +} + +impl From<UntypedArenaPtr> for CodeIndex { + #[inline(always)] + fn from(ptr: UntypedArenaPtr) -> CodeIndex { + CodeIndex(TypedArenaPtr::new(ptr.get_ptr() as *mut IndexPtr)) + } +} + +impl From<TypedArenaPtr<IndexPtr>> for CodeIndex { + #[inline(always)] + fn from(ptr: TypedArenaPtr<IndexPtr>) -> CodeIndex { + CodeIndex(ptr) } } impl CodeIndex { #[inline] - pub(super) fn new(ptr: IndexPtr) -> Self { - CodeIndex(Rc::new(Cell::new(ptr))) + pub(crate) fn new(ptr: IndexPtr, arena: &mut Arena) -> Self { + CodeIndex(arena_alloc!(ptr, arena)) } - #[inline] - pub(crate) fn is_undefined(&self) -> bool { - match self.0.get() { - IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true, - _ => false, - } + #[inline(always)] + pub(crate) fn default(arena: &mut Arena) -> Self { + CodeIndex::new(IndexPtr::undefined(), arena) } pub(crate) fn local(&self) -> Option<usize> { - match self.0.get() { - IndexPtr::Index(i) => Some(i), - IndexPtr::DynamicIndex(i) => Some(i), + match self.0.tag() { + IndexPtrTag::Index => Some(self.0.p() as usize), + IndexPtrTag::DynamicIndex => Some(self.0.p() as usize), _ => None, } } -} -impl Default for CodeIndex { - fn default() -> Self { - CodeIndex(Rc::new(Cell::new(IndexPtr::Undefined))) + #[inline(always)] + pub(crate) fn get(&self) -> IndexPtr { + *self.0.deref() + } + + #[inline(always)] + pub(crate) fn set(&mut self, value: IndexPtr) { + *self.0.deref_mut() = value; + } + + #[inline(always)] + pub(crate) fn get_tag(self) -> IndexPtrTag { + self.0.tag() + } + + #[inline(always)] + pub(crate) fn replace(&mut self, value: IndexPtr) -> IndexPtr { + std::mem::replace(self.0.deref_mut(), value) + } + + #[inline(always)] + pub(crate) fn as_ptr(&self) -> *const IndexPtr { + self.0.as_ptr() } } @@ -269,19 +371,22 @@ impl IndexStore { module: Atom, ) -> Option<CodeIndex> { if module == atom!("user") { - match ClauseType::from(name, arity) { - ClauseType::Named(arity, name, _) => self.code_dir.get(&(name, arity)).cloned(), - _ => None, - } + /*match ClauseType::from(name, arity) { + ClauseType::Named(arity, name, _) => */ + self.code_dir.get(&(name, arity)).cloned() + /* _ => None, + }*/ } else { self.modules .get(&module) - .and_then(|module| match ClauseType::from(name, arity) { - ClauseType::Named(arity, name, _) => { + .and_then(|module|/* |module| match ClauseType::from(name, arity) { + ClauseType::Named(arity, name, _) => { */ module.code_dir.get(&(name, arity)).cloned() + /* } _ => None, - }) + } */ + ) } } diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 17b8eec5..6aa51916 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -75,6 +75,7 @@ pub struct MachineState { pub(super) hb: usize, pub(super) block: usize, // an offset into the OR stack. pub(super) ball: Ball, + pub(super) ball_stack: Vec<Ball>, // save current ball before jumping via, e.g., verify_attr interrupt. pub(super) lifted_heap: Heap, pub(super) interms: Vec<Number>, // intermediate numbers. // locations of cleaners, cut points, the previous block. for setup_call_cleanup. @@ -113,6 +114,7 @@ impl fmt::Debug for MachineState { .field("hb", &self.hb) .field("block", &self.block) .field("ball", &self.ball) + .field("ball_stack", &self.ball_stack) .field("lifted_heap", &self.lifted_heap) .field("interms", &self.interms) .field("flags", &self.flags) @@ -418,6 +420,17 @@ impl MachineState { } } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if arity == 0 { + if let Some(c) = name.as_char() { + chars.push(c); + continue; + } + } + } _ => { } ); @@ -454,6 +467,20 @@ impl MachineState { self.b0 = self.b; } + #[inline(always)] + pub fn neck_cut(&mut self) { + let b = self.b; + let b0 = self.b0; + + if b > b0 { + self.b = b0; + + if b > self.e { + self.stack.truncate(b); + } + } + } + // Safety: the atom_tbl lives for the lifetime of the machine, as does the helper, so the ptr // will always be valid. pub fn read_term_from_user_input(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult { @@ -511,7 +538,7 @@ impl MachineState { loop { match self.read(stream, &indices.op_dir) { - Ok(term_write_result) => { + Ok(mut term_write_result) => { let heap_loc = read_heap_cell!(self.heap[term_write_result.heap_loc], (HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => { pstr_loc_as_cell!(term_write_result.heap_loc) @@ -543,6 +570,10 @@ impl MachineState { } } + for var in term_write_result.var_dict.values_mut() { + *var = heap_bound_deref(&self.heap, *var); + } + let singleton_var_list = push_var_eq_functors( &mut self.heap, term_write_result.var_dict.iter().filter(|(_, binding)| { @@ -666,6 +697,13 @@ impl MachineState { debug_assert_eq!(_arity, 0); var_names.insert(var, Rc::new(name.as_str().to_owned())); } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + var_names.insert(var, Rc::new(name.as_str().to_owned())); + } _ => { unreachable!(); } @@ -677,34 +715,64 @@ impl MachineState { ); } + let ignore_ops = read_heap_cell!(ignore_ops, + (HeapCellValueTag::Atom, (name, _arity)) => { + name == atom!("true") + } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name == atom!("true") + } + _ => { + unreachable!() + } + ); + + let numbervars = read_heap_cell!(numbervars, + (HeapCellValueTag::Atom, (name, _arity)) => { + name == atom!("true") + } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name == atom!("true") + } + _ => { + unreachable!() + } + ); + + let quoted = read_heap_cell!(quoted, + (HeapCellValueTag::Atom, (name, _arity)) => { + name == atom!("true") + } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name == atom!("true") + } + _ => { + unreachable!() + } + ); + let mut printer = HCPrinter::new( &mut self.heap, - &mut self.arena, op_dir, PrinterOutputter::new(), term_to_be_printed, ); - if let HeapCellValueTag::Atom = ignore_ops.get_tag() { - let name = cell_as_atom!(ignore_ops); - printer.ignore_ops = name == atom!("true"); - } else { - unreachable!(); - } - - if let HeapCellValueTag::Atom = numbervars.get_tag() { - let name = cell_as_atom!(numbervars); - printer.numbervars = name == atom!("true"); - } else { - unreachable!(); - } - - if let HeapCellValueTag::Atom = quoted.get_tag() { - let name = cell_as_atom!(quoted); - printer.quoted = name == atom!("true"); - } else { - unreachable!(); - } + printer.ignore_ops = ignore_ops; + printer.numbervars = numbervars; + printer.quoted = quoted; match Number::try_from(max_depth) { Ok(Number::Fixnum(n)) => { diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 012c7d19..00e17649 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -47,6 +47,7 @@ impl MachineState { hb: 0, block: 0, ball: Ball::new(), + ball_stack: vec![], lifted_heap: Heap::new(), interms: vec![Number::default();256], cont_pts: Vec::with_capacity(256), @@ -347,10 +348,27 @@ impl MachineState { debug_assert_eq!(arity, 0); self.fail = cstr_atom != atom!("[]"); } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if arity == 0 { + self.fail = atom == atom!("") && name != atom!("[]"); + } else { + // this is intentionally the same policy for + // value.tag() == Lis and PStrLoc. they're not + // grouped together to allow for arity == 0. + self.unify_partial_string(atom_as_cstr_cell!(atom), value); + + if !self.pdl.is_empty() { + self.unify(); + } + } + } (HeapCellValueTag::CStr, cstr_atom) => { self.fail = atom != cstr_atom; } - (HeapCellValueTag::Str | HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => { + (HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => { self.unify_partial_string(atom_as_cstr_cell!(atom), value); if !self.pdl.is_empty() { @@ -553,6 +571,12 @@ impl MachineState { (HeapCellValueTag::Atom, (name, arity)) => { self.fail = !(arity == 0 && name == atom); } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + self.fail = !(arity == 0 && name == atom); + } (HeapCellValueTag::CStr, cstr_atom) if atom == atom!("[]") => { self.fail = cstr_atom != atom!(""); } @@ -587,6 +611,16 @@ impl MachineState { self.fail = true; } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if let Some(c2) = name.as_char() { + self.fail = !(c == c2 && arity == 0); + } else { + self.fail = true; + } + } (HeapCellValueTag::Char, c2) => { if c != c2 { self.fail = true; @@ -739,11 +773,6 @@ impl MachineState { self.unify_atom(name, d2); } (HeapCellValueTag::Str, s1) => { - if d2.is_constant() { - self.fail = true; - break; - } - if tabu_list.contains(&(d1, d2)) { continue; } @@ -969,9 +998,7 @@ impl MachineState { } } (HeapCellValueTag::Atom, (n2, a2)) => { - if !(a1 == 0 && a2 == 0 && n1 == n2) { - self.fail = true; - } + self.fail = !(a1 == 0 && a2 == 0 && n1 == n2); } (HeapCellValueTag::AttrVar, h) => { if self.bind_with_occurs_check(Ref::attr_var(h), str_loc_as_cell!(s1)) { @@ -1285,11 +1312,6 @@ impl MachineState { self.unify_atom(name, d2); } (HeapCellValueTag::Str, s1) => { - if d2.is_constant() { - self.fail = true; - break; - } - if tabu_list.contains(&(d1, d2)) { continue; } @@ -1492,8 +1514,8 @@ impl MachineState { let v1 = self.store(s1); let v2 = self.store(s2); - let order_cat_v1 = v1.order_category(); - let order_cat_v2 = v2.order_category(); + let order_cat_v1 = v1.order_category(&self.heap); + let order_cat_v2 = v2.order_category(&self.heap); if order_cat_v1 != order_cat_v2 { self.pdl.clear(); @@ -1552,6 +1574,15 @@ impl MachineState { ); } } + (HeapCellValueTag::Str, s) => { + let n2 = cell_as_atom_cell!(self.heap[s]) + .get_name(); + + if n1 != n2 { + self.pdl.clear(); + return Some(n1.cmp(&n2)); + } + } _ => { unreachable!(); } @@ -1579,11 +1610,67 @@ impl MachineState { return Some(c1.cmp(&c2)); } } + (HeapCellValueTag::Str, s) => { + let n2 = cell_as_atom_cell!(self.heap[s]) + .get_name(); + + if let Some(c2) = n2.as_char() { + if c1 != c2 { + self.pdl.clear(); + return Some(c1.cmp(&c2)); + } + } else { + self.pdl.clear(); + return Some( + Some(c1).cmp(&n2.chars().next()) + .then(Ordering::Less) + ); + } + } _ => { unreachable!() } ) } + (HeapCellValueTag::Str, s) => { + let n1 = cell_as_atom_cell!(self.heap[s]) + .get_name(); + + read_heap_cell!(v2, + (HeapCellValueTag::Atom, (n2, _a2)) => { + if n1 != n2 { + self.pdl.clear(); + return Some(n1.cmp(&n2)); + } + } + (HeapCellValueTag::Char, c2) => { + if let Some(c1) = n1.as_char() { + if c1 != c2 { + self.pdl.clear(); + return Some(c1.cmp(&c2)); + } + } else { + self.pdl.clear(); + return Some( + n1.chars().next().cmp(&Some(c2)) + .then(Ordering::Greater) + ); + } + } + (HeapCellValueTag::Str, s) => { + let n2 = cell_as_atom_cell!(self.heap[s]) + .get_name(); + + if n1 != n2 { + self.pdl.clear(); + return Some(n1.cmp(&n2)); + } + } + _ => { + unreachable!(); + } + ) + } _ => { unreachable!() } @@ -1597,8 +1684,8 @@ impl MachineState { ) -> Option<Ordering> { let compound = Some(TermOrderCategory::Compound); - if iter2.focus.order_category() != compound { - Some(compound.cmp(&iter2.focus.order_category())) + if iter2.focus.order_category(iter2.heap) != compound { + Some(compound.cmp(&iter2.focus.order_category(iter2.heap))) } else { let c1 = match iteratee { PStrIteratee::Char(_, c) => c, @@ -2116,7 +2203,7 @@ impl MachineState { heap_bound_deref(iter.heap, value), )); - if value.is_compound() { + if value.is_compound(iter.heap) { return true; } } @@ -2403,6 +2490,21 @@ impl MachineState { a1.as_var().unwrap(), ); } + (HeapCellValueTag::Str, s) => { + let (name, atom_arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if atom_arity == 0 { + self.try_functor_fabricate_struct( + name, + arity as usize, + a1.as_var().unwrap(), + ); + } else { + let err = self.type_error(ValidType::Atomic, store_name); + return Err(self.error_form(err, stub_gen())); + } + } (HeapCellValueTag::Char, c) => { let c = self.atom_tbl.build_with(&c.to_string()); @@ -2444,6 +2546,17 @@ impl MachineState { let err = self.instantiation_error(); Err(self.error_form(err, stub_gen())) } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if name == atom!("[]") && arity == 0 { + Ok(vec![]) + } else { + let err = self.type_error(ValidType::List, value); + Err(self.error_form(err, stub_gen())) + } + } (HeapCellValueTag::Atom, (name, arity)) => { if name == atom!("[]") && arity == 0 { Ok(vec![]) @@ -2484,6 +2597,17 @@ impl MachineState { (HeapCellValueTag::PStrLoc, l) => { return self.try_from_partial_string(result, l, stub_gen, a1); } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if name == atom!("[]") && arity == 0 { + break; + } else { + let err = self.type_error(ValidType::List, a1); + return Err(self.error_form(err, stub_gen())); + } + } (HeapCellValueTag::Atom, (name, arity)) => { if name == atom!("[]") && arity == 0 { break; diff --git a/src/machine/mock_wam.rs b/src/machine/mock_wam.rs index d647f756..f18d9575 100644 --- a/src/machine/mock_wam.rs +++ b/src/machine/mock_wam.rs @@ -61,7 +61,6 @@ impl MockWAM { let mut printer = HCPrinter::new( &mut self.machine_st.heap, - &mut self.machine_st.arena, &self.op_dir, PrinterOutputter::new(), heap_loc_as_cell!(term_write_result.heap_loc), @@ -272,6 +271,7 @@ impl Machine { if let Some(ref mut builtins) = wam.indices.modules.get_mut(&atom!("builtins")) { load_module( + &mut wam.machine_st, &mut wam.indices.code_dir, &mut wam.indices.op_dir, &mut wam.indices.meta_predicates, @@ -297,6 +297,7 @@ impl Machine { if let Some(loader) = wam.indices.modules.get(&atom!("loader")) { load_module( + &mut wam.machine_st, &mut wam.indices.code_dir, &mut wam.indices.op_dir, &mut wam.indices.meta_predicates, diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 074e8f42..4cd1fce8 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -22,6 +22,7 @@ pub mod streams; pub mod system_calls; pub mod term_stream; +use crate::arena::*; use crate::arithmetic::*; use crate::atom_table::*; use crate::forms::*; @@ -160,6 +161,24 @@ pub(crate) fn import_builtin_impls(code_dir: &CodeDir, builtins: &mut Module) { } } +#[inline] +pub(crate) fn get_structure_index(value: HeapCellValue) -> Option<CodeIndex> { + read_heap_cell!(value, + (HeapCellValueTag::Cons, cons_ptr) => { + match_untyped_arena_ptr!(cons_ptr, + (ArenaHeaderTag::IndexPtr, ip) => { + return Some(CodeIndex::from(ip)); + } + _ => {} + ); + } + _ => { + } + ); + + None +} + impl Machine { #[inline] pub fn prelude_view_and_machine_st(&mut self) -> (MachinePreludeView, &mut MachineState) { @@ -220,6 +239,7 @@ impl Machine { if let Some(toplevel) = self.indices.modules.get(&atom!("$toplevel")) { load_module( + &mut self.machine_st, &mut self.indices.code_dir, &mut self.indices.op_dir, &mut self.indices.meta_predicates, @@ -287,7 +307,7 @@ impl Machine { } pub(crate) fn configure_modules(&mut self) { - fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir) { + fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) { for arity in 1..66 { let key = (atom!("call"), arity); @@ -295,7 +315,7 @@ impl Machine { Some(src_code_index) => { let target_code_index = target_code_dir .entry(key) - .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)); + .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)); target_code_index.set(src_code_index.get()); } @@ -311,6 +331,7 @@ impl Machine { // Import loader's exports into the builtins module so they will be // implicitly included in every further module. load_module( + &mut self.machine_st, &mut builtins.code_dir, &mut builtins.op_dir, &mut builtins.meta_predicates, @@ -331,10 +352,10 @@ impl Machine { } for (_, target_module) in self.indices.modules.iter_mut() { - update_call_n_indices(&loader, &mut target_module.code_dir); + update_call_n_indices(&loader, &mut target_module.code_dir, &mut self.machine_st.arena); } - update_call_n_indices(&loader, &mut self.indices.code_dir); + update_call_n_indices(&loader, &mut self.indices.code_dir, &mut self.machine_st.arena); self.indices.modules.insert(atom!("loader"), loader); } else { @@ -393,7 +414,10 @@ impl Machine { for (p, instr) in self.code[impls_offset ..].iter().enumerate() { let key = instr.to_name_and_arity(); - self.indices.code_dir.insert(key, CodeIndex::new(IndexPtr::Index(p + impls_offset))); + self.indices.code_dir.insert( + key, + CodeIndex::new(IndexPtr::index(p + impls_offset), &mut self.machine_st.arena), + ); } } @@ -407,9 +431,7 @@ impl Machine { let user_output = Stream::stdout(&mut machine_st.arena); let user_error = Stream::stderr(&mut machine_st.arena); - let runtime = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() + let runtime = tokio::runtime::Runtime::new() .unwrap(); let mut wam = Machine { @@ -455,6 +477,7 @@ impl Machine { if let Some(builtins) = wam.indices.modules.get_mut(&atom!("builtins")) { load_module( + &mut wam.machine_st, &mut wam.indices.code_dir, &mut wam.indices.op_dir, &mut wam.indices.meta_predicates, @@ -480,6 +503,7 @@ impl Machine { if let Some(loader) = wam.indices.modules.get(&atom!("loader")) { load_module( + &mut wam.machine_st, &mut wam.indices.code_dir, &mut wam.indices.op_dir, &mut wam.indices.meta_predicates, @@ -666,18 +690,20 @@ impl Machine { #[inline(always)] fn try_call(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult { - match idx { - IndexPtr::DynamicUndefined => { + let compiled_tl_index = idx.p() as usize; + + match idx.tag() { + IndexPtrTag::DynamicUndefined => { self.machine_st.fail = true; } - IndexPtr::Undefined => { + IndexPtrTag::Undefined => { return Err(self.machine_st.throw_undefined_error(name, arity)); } - IndexPtr::DynamicIndex(compiled_tl_index) => { + IndexPtrTag::DynamicIndex => { self.machine_st.dynamic_mode = FirstOrNext::First; self.machine_st.call_at_index(arity, compiled_tl_index); } - IndexPtr::Index(compiled_tl_index) => { + IndexPtrTag::Index => { self.machine_st.call_at_index(arity, compiled_tl_index); } } @@ -687,18 +713,20 @@ impl Machine { #[inline(always)] fn try_execute(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult { - match idx { - IndexPtr::DynamicUndefined => { + let compiled_tl_index = idx.p() as usize; + + match idx.tag() { + IndexPtrTag::DynamicUndefined => { self.machine_st.fail = true; } - IndexPtr::Undefined => { + IndexPtrTag::Undefined => { return Err(self.machine_st.throw_undefined_error(name, arity)); } - IndexPtr::DynamicIndex(compiled_tl_index) => { + IndexPtrTag::DynamicIndex => { self.machine_st.dynamic_mode = FirstOrNext::First; self.machine_st.execute_at_index(arity, compiled_tl_index); } - IndexPtr::Index(compiled_tl_index) => { + IndexPtrTag::Index => { self.machine_st.execute_at_index(arity, compiled_tl_index) } } diff --git a/src/machine/partial_string.rs b/src/machine/partial_string.rs index cdc424dd..fce47204 100644 --- a/src/machine/partial_string.rs +++ b/src/machine/partial_string.rs @@ -179,6 +179,14 @@ impl<'a> HeapPStrIter<'a> { if self.at_string_terminator() { self.focus = empty_list_as_cell!(); self.brent_st.hare = result.focus; + } else { + read_heap_cell!(self.heap[result.focus], + (HeapCellValueTag::Lis | HeapCellValueTag::Str) => { + self.focus = self.heap[self.brent_st.hare]; + } + _ => { + } + ); } } @@ -330,7 +338,7 @@ impl<'a> HeapPStrIter<'a> { }) } else { None - } + }; } (HeapCellValueTag::Str, s) => { let (name, arity) = cell_as_atom_cell!(self.heap[s]) diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 6b925522..37871bb0 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -470,14 +470,141 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>( } } +fn build_meta_predicate_clause<'a, LS: LoadState<'a>>( + loader: &mut Loader<'a, LS>, + module_name: Atom, + terms: Vec<Term>, + meta_specs: Vec<MetaSpec>, +) -> Vec<Term> { + let mut arg_terms = Vec::with_capacity(terms.len()); + + for (term, meta_spec) in terms.into_iter().zip(meta_specs.iter()) { + if let MetaSpec::RequiresExpansionWithArgument(supp_args) = meta_spec { + if let Some(name) = term.name() { + if name == atom!("$call") { + arg_terms.push(term); + continue; + } + + let arity = term.arity(); + + fn get_qualified_name( + module_term: &Term, + qualified_term: &Term, + ) -> Option<(Atom, Atom)> { + if let Term::Literal(_, Literal::Atom(module_name)) = module_term { + if let Some(name) = qualified_term.name() { + return Some((*module_name, name)); + } + } + + None + } + + fn identity_fn(_module_name: Atom, term: Term) -> Term { + term + } + + fn tag_with_module_name(module_name: Atom, term: Term) -> Term { + Term::Clause(Cell::default(), atom!(":"), vec![ + Term::Literal(Cell::default(), Literal::Atom(module_name)), + term + ]) + } + + let process_term: fn(Atom, Term) -> Term; + + let (module_name, key, term) = match term { + Term::Clause(cell, atom!(":"), mut terms) if terms.len() == 2 => { + if let Some((module_name, name)) = get_qualified_name(&terms[0], &terms[1]) { + process_term = tag_with_module_name; + (module_name, (name, terms[1].arity() + supp_args), terms.pop().unwrap()) + } else { + arg_terms.push(Term::Clause(cell, atom!(":"), terms)); + continue; + } + } + term => { + process_term = identity_fn; + (module_name, (name, arity + supp_args), term) + } + }; + + let term = match term { + Term::Clause(cell, name, mut terms) => { + if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() { + arg_terms.push(process_term( + module_name, + Term::Clause(cell, name, terms), + )); + + continue; + } + + let idx = loader.get_or_insert_qualified_code_index(module_name, key); + + terms.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx))); + process_term(module_name, Term::Clause(cell, name, terms)) + } + Term::Literal(cell, Literal::Atom(name)) => { + let idx = loader.get_or_insert_qualified_code_index(module_name, key); + + process_term(module_name, Term::Clause( + cell, + name, + vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))], + )) + } + term => term, + }; + + arg_terms.push(term); + continue; + } + } + + arg_terms.push(term); + } + + arg_terms +} + #[inline] fn clause_to_query_term<'a, LS: LoadState<'a>>( loader: &mut Loader<'a, LS>, name: Atom, - terms: Vec<Term>, + mut terms: Vec<Term>, call_policy: CallPolicy, ) -> QueryTerm { - let ct = loader.get_clause_type(name, terms.len()); + if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() { + // supplementary code vector indices are unnecessary for + // root-level clauses. + terms.pop(); + } + + let mut ct = loader.get_clause_type(name, terms.len()); + + if let ClauseType::Named(arity, name, idx) = ct { + if let Some(meta_specs) = loader.get_meta_specs(name, arity).cloned() { + let module_name = loader.payload.compilation_target.module_name(); + let terms = build_meta_predicate_clause( + loader, + module_name, + terms, + meta_specs, + ); + + return QueryTerm::Clause( + Cell::default(), + ClauseType::Named(arity, name, idx), + terms, + call_policy, + ); + } + + ct = ClauseType::Named(arity, name, idx); + } + QueryTerm::Clause(Cell::default(), ct, terms, call_policy) } @@ -486,112 +613,139 @@ fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>( loader: &mut Loader<'a, LS>, module_name: Atom, name: Atom, - terms: Vec<Term>, + mut terms: Vec<Term>, call_policy: CallPolicy, ) -> QueryTerm { - let ct = loader.get_qualified_clause_type(module_name, name, terms.len()); - QueryTerm::Clause(Cell::default(), ct, terms, call_policy) -} + if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() { + // supplementary code vector indices are unnecessary for + // root-level clauses. + terms.pop(); + } -#[derive(Debug)] -pub(crate) struct Preprocessor { - queue: VecDeque<VecDeque<Term>>, - settings: CodeGenSettings, -} + let mut ct = loader.get_qualified_clause_type(module_name, name, terms.len()); -impl Preprocessor { - pub(super) fn new(settings: CodeGenSettings) -> Self { - Preprocessor { - queue: VecDeque::new(), - settings, + if let ClauseType::Named(arity, name, idx) = ct { + if let Some(meta_specs) = loader.get_meta_specs(name, arity).cloned() { + let terms = build_meta_predicate_clause( + loader, + module_name, + terms, + meta_specs, + ); + + return QueryTerm::Clause( + Cell::default(), + ClauseType::Named(arity, name, idx), + terms, + call_policy, + ); } + + ct = ClauseType::Named(arity, name, idx); } - fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> { - match term { - Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => Ok(term), - _ => Err(CompilationError::InadmissibleFact), + QueryTerm::Clause(Cell::default(), ct, terms, call_policy) +} + +fn compute_head(term: &Term) -> Vec<Term> { + let mut vars = IndexSet::new(); + + for term in post_order_iter(term) { + if let TermRef::Var(_, _, v) = term { + vars.insert(v.clone()); } } - fn compute_head(&self, term: &Term) -> Vec<Term> { - let mut vars = IndexSet::new(); + vars.insert(Rc::new(String::from("!"))); + vars.into_iter() + .map(|v| Term::Var(Cell::default(), v)) + .collect() +} - for term in post_order_iter(term) { - if let TermRef::Var(_, _, v) = term { - vars.insert(v.clone()); - } - } +pub(crate) fn build_rule_body(vars: &[Term], body_term: Term) -> Term { + let head_term = Term::Clause(Cell::default(), atom!(""), vars.iter().cloned().collect()); + let rule = vec![head_term, body_term]; - vars.insert(Rc::new(String::from("!"))); - vars.into_iter() - .map(|v| Term::Var(Cell::default(), v)) - .collect() - } + Term::Clause(Cell::default(), atom!(":-"), rule) +} - fn fabricate_rule_body(&self, vars: &Vec<Term>, body_term: Term) -> Term { - let head_term = Term::Clause(Cell::default(), atom!(""), vars.clone()); - let rule = vec![head_term, body_term]; +// the terms form the body of the rule. We create a head, by +// gathering variables from the body of terms and recording them +// in the head clause. +fn build_rule(body_term: Term) -> (JumpStub, VecDeque<Term>) { + // collect the vars of body_term into a head, return the num_vars + // (the arity) as well. + let vars = compute_head(&body_term); + let rule = build_rule_body(&vars, body_term); - Term::Clause(Cell::default(), atom!(":-"), rule) - } + (vars, VecDeque::from(vec![rule])) +} - // the terms form the body of the rule. We create a head, by - // gathering variables from the body of terms and recording them - // in the head clause. - fn fabricate_rule(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) { - // collect the vars of body_term into a head, return the num_vars - // (the arity) as well. - let vars = self.compute_head(&body_term); - let rule = self.fabricate_rule_body(&vars, body_term); +fn build_disjunct(body_term: Term) -> (JumpStub, VecDeque<Term>) { + let vars = compute_head(&body_term); + let results = unfold_by_str(body_term, atom!(";")) + .into_iter() + .map(|term| { + let mut subterms = unfold_by_str(term, atom!(",")); + mark_cut_variables(&mut subterms); - (vars, VecDeque::from(vec![rule])) - } + check_for_internal_if_then(&mut subterms); - fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) { - let vars = self.compute_head(&body_term); - let results = unfold_by_str(body_term, atom!(";")) - .into_iter() - .map(|term| { - let mut subterms = unfold_by_str(term, atom!(",")); - mark_cut_variables(&mut subterms); + let term = subterms.pop().unwrap(); + let clause = fold_by_str(subterms.into_iter(), term, atom!(",")); - check_for_internal_if_then(&mut subterms); + build_rule_body(&vars, clause) + }) + .collect(); - let term = subterms.pop().unwrap(); - let clause = fold_by_str(subterms.into_iter(), term, atom!(",")); + (vars, results) +} - self.fabricate_rule_body(&vars, clause) - }) - .collect(); +fn build_if_then(prec: Term, conq: Term) -> (JumpStub, VecDeque<Term>) { + let mut prec_seq = unfold_by_str(prec, atom!(",")); + let comma_sym = atom!(","); + let cut_sym = Literal::Atom(atom!("!")); - (vars, results) - } + prec_seq.push(Term::Literal(Cell::default(), cut_sym)); - fn fabricate_if_then(&self, prec: Term, conq: Term) -> (JumpStub, VecDeque<Term>) { - let mut prec_seq = unfold_by_str(prec, atom!(",")); - let comma_sym = atom!(","); - let cut_sym = Literal::Atom(atom!("!")); + mark_cut_variables_as(&mut prec_seq, atom!("blocked_!")); - prec_seq.push(Term::Literal(Cell::default(), cut_sym)); + let mut conq_seq = unfold_by_str(conq, atom!(",")); - mark_cut_variables_as(&mut prec_seq, atom!("blocked_!")); + mark_cut_variables(&mut conq_seq); + prec_seq.extend(conq_seq.into_iter()); - let mut conq_seq = unfold_by_str(conq, atom!(",")); + let back_term = prec_seq.pop().unwrap(); + let front_term = prec_seq.pop().unwrap(); - mark_cut_variables(&mut conq_seq); - prec_seq.extend(conq_seq.into_iter()); + let body_term = Term::Clause( + Cell::default(), + comma_sym, + vec![front_term, back_term], + ); - let back_term = prec_seq.pop().unwrap(); - let front_term = prec_seq.pop().unwrap(); + build_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym)) +} - let body_term = Term::Clause( - Cell::default(), - comma_sym, - vec![front_term, back_term], - ); +#[derive(Debug)] +pub(crate) struct Preprocessor { + queue: VecDeque<VecDeque<Term>>, + settings: CodeGenSettings, +} - self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym)) +impl Preprocessor { + pub(super) fn new(settings: CodeGenSettings) -> Self { + Preprocessor { + queue: VecDeque::new(), + settings, + } + } + + fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> { + match term { + Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => Ok(term), + _ => Err(CompilationError::InadmissibleFact), + } } fn to_query_term<'a, LS: LoadState<'a>>( @@ -605,7 +759,9 @@ impl Preprocessor { Ok(QueryTerm::BlockedCut) } else { Ok(clause_to_query_term( - loader, name, vec![], + loader, + name, + vec![], self.settings.default_call_policy(), )) } @@ -618,7 +774,7 @@ impl Preprocessor { (atom!(";"), 2) => { let term = Term::Clause(r, name, terms); - let (stub, clauses) = self.fabricate_disjunct(term); + let (stub, clauses) = build_disjunct(term); self.queue.push_back(clauses); Ok(QueryTerm::Jump(stub)) @@ -627,7 +783,7 @@ impl Preprocessor { let conq = terms.pop().unwrap(); let prec = terms.pop().unwrap(); - let (stub, clauses) = self.fabricate_if_then(prec, conq); + let (stub, clauses) = build_if_then(prec, conq); self.queue.push_back(clauses); Ok(QueryTerm::Jump(stub)) @@ -644,7 +800,7 @@ impl Preprocessor { let terms = vec![prec, conq]; let term = Term::Clause(Cell::default(), atom!(";"), terms); - let (stub, clauses) = self.fabricate_disjunct(term); + let (stub, clauses) = build_disjunct(term); debug_assert!(clauses.len() > 0); self.queue.push_back(clauses); @@ -689,8 +845,8 @@ impl Preprocessor { Ok(clause_to_query_term( loader, - name, - terms, + atom!("call"), + vec![Term::Clause(r, name, terms)], self.settings.default_call_policy(), )) } diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 73839087..9e558af5 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -26,6 +26,7 @@ use std::ops::{Deref, DerefMut}; use std::ptr; use native_tls::TlsStream; +use hyper::body::{Bytes, Sender}; #[derive(Debug, BitfieldSpecifier, Clone, Copy, PartialEq, Eq, Hash)] #[bits = 1] @@ -249,24 +250,51 @@ impl Write for NamedTlsStream { } } -pub struct NamedHttpClientStream { +pub struct HttpReadStream { url: Atom, body_reader: Box<dyn BufRead>, } -impl Debug for NamedHttpClientStream { +impl Debug for HttpReadStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Http Client Stream [{}]", self.url.as_str()) + write!(f, "Http Read Stream [{}]", self.url.as_str()) } } -impl Read for NamedHttpClientStream { +impl Read for HttpReadStream { #[inline] fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { self.body_reader.read(buf) } } +pub struct HttpWriteStream { + body_writer: Sender, +} + +impl Debug for HttpWriteStream { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Http Write Stream") + } +} + +impl Write for HttpWriteStream { + #[inline] + fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { + let bytes = Bytes::copy_from_slice(buf); + let len = bytes.len(); + match self.body_writer.try_send_data(bytes) { + Ok(()) => Ok(len), + Err(_) => Err(std::io::Error::from(ErrorKind::Interrupted)) + } + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + #[derive(Debug)] pub struct StandardOutputStream {} @@ -405,7 +433,8 @@ arena_allocated_impl_for_stream!(CharReader<InputFileStream>, InputFileStream); arena_allocated_impl_for_stream!(OutputFileStream, OutputFileStream); arena_allocated_impl_for_stream!(CharReader<NamedTcpStream>, NamedTcpStream); arena_allocated_impl_for_stream!(CharReader<NamedTlsStream>, NamedTlsStream); -arena_allocated_impl_for_stream!(CharReader<NamedHttpClientStream>, NamedHttpClientStream); +arena_allocated_impl_for_stream!(CharReader<HttpReadStream>, HttpReadStream); +arena_allocated_impl_for_stream!(CharReader<HttpWriteStream>, HttpWriteStream); arena_allocated_impl_for_stream!(ReadlineStream, ReadlineStream); arena_allocated_impl_for_stream!(StaticStringStream, StaticStringStream); arena_allocated_impl_for_stream!(StandardOutputStream, StandardOutputStream); @@ -419,7 +448,8 @@ pub enum Stream { StaticString(TypedArenaPtr<StreamLayout<StaticStringStream>>), NamedTcp(TypedArenaPtr<StreamLayout<CharReader<NamedTcpStream>>>), NamedTls(TypedArenaPtr<StreamLayout<CharReader<NamedTlsStream>>>), - NamedHttpClient(TypedArenaPtr<StreamLayout<CharReader<NamedHttpClientStream>>>), + HttpRead(TypedArenaPtr<StreamLayout<CharReader<HttpReadStream>>>), + HttpWrite(TypedArenaPtr<StreamLayout<CharReader<HttpWriteStream>>>), Null(StreamOptions), Readline(TypedArenaPtr<StreamLayout<ReadlineStream>>), StandardOutput(TypedArenaPtr<StreamLayout<StandardOutputStream>>), @@ -474,7 +504,8 @@ impl Stream { } ArenaHeaderTag::NamedTcpStream => Stream::NamedTcp(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::NamedTlsStream => Stream::NamedTls(TypedArenaPtr::new(ptr as *mut _)), - ArenaHeaderTag::NamedHttpClientStream => Stream::NamedHttpClient(TypedArenaPtr::new(ptr as *mut _)), + ArenaHeaderTag::HttpReadStream => Stream::HttpRead(TypedArenaPtr::new(ptr as *mut _)), + ArenaHeaderTag::HttpWriteStream => Stream::HttpWrite(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::ReadlineStream => Stream::Readline(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::StaticStringStream => { Stream::StaticString(TypedArenaPtr::new(ptr as *mut _)) @@ -527,7 +558,8 @@ impl Stream { Stream::StaticString(ptr) => ptr.header_ptr(), Stream::NamedTcp(ptr) => ptr.header_ptr(), Stream::NamedTls(ptr) => ptr.header_ptr(), - Stream::NamedHttpClient(ptr) => ptr.header_ptr(), + Stream::HttpRead(ptr) => ptr.header_ptr(), + Stream::HttpWrite(ptr) => ptr.header_ptr(), Stream::Null(_) => ptr::null(), Stream::Readline(ptr) => ptr.header_ptr(), Stream::StandardOutput(ptr) => ptr.header_ptr(), @@ -543,7 +575,8 @@ impl Stream { Stream::StaticString(ref ptr) => &ptr.options, Stream::NamedTcp(ref ptr) => &ptr.options, Stream::NamedTls(ref ptr) => &ptr.options, - Stream::NamedHttpClient(ref ptr) => &ptr.options, + Stream::HttpRead(ref ptr) => &ptr.options, + Stream::HttpWrite(ref ptr) => &ptr.options, Stream::Null(ref options) => options, Stream::Readline(ref ptr) => &ptr.options, Stream::StandardOutput(ref ptr) => &ptr.options, @@ -559,7 +592,8 @@ impl Stream { Stream::StaticString(ref mut ptr) => &mut ptr.options, Stream::NamedTcp(ref mut ptr) => &mut ptr.options, Stream::NamedTls(ref mut ptr) => &mut ptr.options, - Stream::NamedHttpClient(ref mut ptr) => &mut ptr.options, + Stream::HttpRead(ref mut ptr) => &mut ptr.options, + Stream::HttpWrite(ref mut ptr) => &mut ptr.options, Stream::Null(ref mut options) => options, Stream::Readline(ref mut ptr) => &mut ptr.options, Stream::StandardOutput(ref mut ptr) => &mut ptr.options, @@ -576,7 +610,8 @@ impl Stream { Stream::StaticString(ptr) => ptr.lines_read += incr_num_lines_read, Stream::NamedTcp(ptr) => ptr.lines_read += incr_num_lines_read, Stream::NamedTls(ptr) => ptr.lines_read += incr_num_lines_read, - Stream::NamedHttpClient(ptr) => ptr.lines_read += incr_num_lines_read, + Stream::HttpRead(ptr) => ptr.lines_read += incr_num_lines_read, + Stream::HttpWrite(_) => {} Stream::Null(_) => {} Stream::Readline(ptr) => ptr.lines_read += incr_num_lines_read, Stream::StandardOutput(ptr) => ptr.lines_read += incr_num_lines_read, @@ -593,7 +628,8 @@ impl Stream { Stream::StaticString(ptr) => ptr.lines_read = value, Stream::NamedTcp(ptr) => ptr.lines_read = value, Stream::NamedTls(ptr) => ptr.lines_read = value, - Stream::NamedHttpClient(ptr) => ptr.lines_read = value, + Stream::HttpRead(ptr) => ptr.lines_read = value, + Stream::HttpWrite(_) => {} Stream::Null(_) => {} Stream::Readline(ptr) => ptr.lines_read = value, Stream::StandardOutput(ptr) => ptr.lines_read = value, @@ -610,7 +646,8 @@ impl Stream { Stream::StaticString(ptr) => ptr.lines_read, Stream::NamedTcp(ptr) => ptr.lines_read, Stream::NamedTls(ptr) => ptr.lines_read, - Stream::NamedHttpClient(ptr) => ptr.lines_read, + Stream::HttpRead(ptr) => ptr.lines_read, + Stream::HttpWrite(_) => 0, Stream::Null(_) => 0, Stream::Readline(ptr) => ptr.lines_read, Stream::StandardOutput(ptr) => ptr.lines_read, @@ -625,13 +662,14 @@ impl CharRead for Stream { Stream::InputFile(file) => (*file).peek_char(), Stream::NamedTcp(tcp_stream) => (*tcp_stream).peek_char(), Stream::NamedTls(tls_stream) => (*tls_stream).peek_char(), - Stream::NamedHttpClient(http_stream) => (*http_stream).peek_char(), + Stream::HttpRead(http_stream) => (*http_stream).peek_char(), Stream::Readline(rl_stream) => (*rl_stream).peek_char(), Stream::StaticString(src) => (*src).peek_char(), Stream::Byte(cursor) => (*cursor).peek_char(), Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | + Stream::HttpWrite(_) | Stream::Null(_) => Some(Err(std::io::Error::new( ErrorKind::PermissionDenied, StreamError::ReadFromOutputStream, @@ -644,13 +682,14 @@ impl CharRead for Stream { Stream::InputFile(file) => (*file).read_char(), Stream::NamedTcp(tcp_stream) => (*tcp_stream).read_char(), Stream::NamedTls(tls_stream) => (*tls_stream).read_char(), - Stream::NamedHttpClient(http_stream) => (*http_stream).read_char(), + Stream::HttpRead(http_stream) => (*http_stream).read_char(), Stream::Readline(rl_stream) => (*rl_stream).read_char(), Stream::StaticString(src) => (*src).read_char(), Stream::Byte(cursor) => (*cursor).read_char(), Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | + Stream::HttpWrite(_) | Stream::Null(_) => Some(Err(std::io::Error::new( ErrorKind::PermissionDenied, StreamError::ReadFromOutputStream, @@ -663,13 +702,14 @@ impl CharRead for Stream { Stream::InputFile(file) => file.put_back_char(c), Stream::NamedTcp(tcp_stream) => tcp_stream.put_back_char(c), Stream::NamedTls(tls_stream) => tls_stream.put_back_char(c), - Stream::NamedHttpClient(http_stream) => http_stream.put_back_char(c), + Stream::HttpRead(http_stream) => http_stream.put_back_char(c), Stream::Readline(rl_stream) => rl_stream.put_back_char(c), Stream::StaticString(src) => src.put_back_char(c), Stream::Byte(cursor) => cursor.put_back_char(c), Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | + Stream::HttpWrite(_) | Stream::Null(_) => {} } } @@ -679,13 +719,14 @@ impl CharRead for Stream { Stream::InputFile(ref mut file) => file.consume(nread), Stream::NamedTcp(ref mut tcp_stream) => tcp_stream.consume(nread), Stream::NamedTls(ref mut tls_stream) => tls_stream.consume(nread), - Stream::NamedHttpClient(ref mut http_stream) => http_stream.consume(nread), + Stream::HttpRead(ref mut http_stream) => http_stream.consume(nread), Stream::Readline(ref mut rl_stream) => rl_stream.consume(nread), Stream::StaticString(ref mut src) => src.consume(nread), Stream::Byte(ref mut cursor) => cursor.consume(nread), Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | + Stream::HttpWrite(_) | Stream::Null(_) => {} } } @@ -698,13 +739,14 @@ impl Read for Stream { Stream::InputFile(file) => (*file).read(buf), Stream::NamedTcp(tcp_stream) => (*tcp_stream).read(buf), Stream::NamedTls(tls_stream) => (*tls_stream).read(buf), - Stream::NamedHttpClient(http_stream) => (*http_stream).read(buf), + Stream::HttpRead(http_stream) => (*http_stream).read(buf), Stream::Readline(rl_stream) => (*rl_stream).read(buf), Stream::StaticString(src) => (*src).read(buf), Stream::Byte(cursor) => (*cursor).read(buf), Stream::OutputFile(_) | Stream::StandardError(_) - | Stream::StandardOutput(_) + | Stream::StandardOutput(_) + | Stream::HttpWrite(_) | Stream::Null(_) => Err(std::io::Error::new( ErrorKind::PermissionDenied, StreamError::ReadFromOutputStream, @@ -724,7 +766,8 @@ impl Write for Stream { Stream::Byte(ref mut cursor) => cursor.get_mut().write(buf), Stream::StandardOutput(stream) => stream.write(buf), Stream::StandardError(stream) => stream.write(buf), - Stream::NamedHttpClient(_) | + Stream::HttpWrite(ref mut stream) => stream.get_mut().write(buf), + Stream::HttpRead(_) | Stream::StaticString(_) | Stream::Readline(_) | Stream::InputFile(..) | @@ -743,7 +786,8 @@ impl Write for Stream { Stream::Byte(ref mut cursor) => cursor.stream.get_mut().flush(), Stream::StandardError(stream) => stream.stream.flush(), Stream::StandardOutput(stream) => stream.stream.flush(), - Stream::NamedHttpClient(_) | + Stream::HttpWrite(ref mut stream) => stream.stream.get_mut().flush(), + Stream::HttpRead(_) | Stream::StaticString(_) | Stream::Readline(_) | Stream::InputFile(_) | @@ -868,7 +912,8 @@ impl Stream { Stream::StaticString(stream) => stream.past_end_of_stream, Stream::NamedTcp(stream) => stream.past_end_of_stream, Stream::NamedTls(stream) => stream.past_end_of_stream, - Stream::NamedHttpClient(stream) => stream.past_end_of_stream, + Stream::HttpRead(stream) => stream.past_end_of_stream, + Stream::HttpWrite(stream) => stream.past_end_of_stream, Stream::Null(_) => false, Stream::Readline(stream) => stream.past_end_of_stream, Stream::StandardOutput(stream) => stream.past_end_of_stream, @@ -890,7 +935,8 @@ impl Stream { Stream::StaticString(stream) => stream.past_end_of_stream = value, Stream::NamedTcp(stream) => stream.past_end_of_stream = value, Stream::NamedTls(stream) => stream.past_end_of_stream = value, - Stream::NamedHttpClient(stream) => stream.past_end_of_stream = value, + Stream::HttpRead(stream) => stream.past_end_of_stream = value, + Stream::HttpWrite(stream) => stream.past_end_of_stream = value, Stream::Null(_) => {} Stream::Readline(stream) => stream.past_end_of_stream = value, Stream::StandardOutput(stream) => stream.past_end_of_stream = value, @@ -956,11 +1002,11 @@ impl Stream { Stream::Byte(_) | Stream::Readline(_) | Stream::StaticString(_) - | Stream::NamedHttpClient(_) + | Stream::HttpRead(_) | Stream::InputFile(..) => atom!("read"), Stream::NamedTcp(..) | Stream::NamedTls(..) => atom!("read_append"), Stream::OutputFile(file) if file.is_append => atom!("append"), - Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) => atom!("write"), + Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | Stream::HttpWrite(_) => atom!("write"), Stream::Null(_) => atom!(""), } } @@ -1020,8 +1066,8 @@ impl Stream { http_stream: Box<dyn BufRead>, arena: &mut Arena, ) -> Self { - Stream::NamedHttpClient(arena_alloc!( - StreamLayout::new(CharReader::new(NamedHttpClientStream { + Stream::HttpRead(arena_alloc!( + StreamLayout::new(CharReader::new(HttpReadStream { url, body_reader: http_stream })), @@ -1030,6 +1076,19 @@ impl Stream { } #[inline] + pub(crate) fn from_http_sender( + body_writer: Sender, + arena: &mut Arena, + ) -> Self { + Stream::HttpWrite(arena_alloc!( + StreamLayout::new(CharReader::new(HttpWriteStream { + body_writer + })), + arena + )) + } + + #[inline] pub(crate) fn from_file_as_output( file_name: Atom, file: File, @@ -1065,7 +1124,7 @@ impl Stream { Stream::NamedTls(ref mut tls_stream) => { tls_stream.inner_mut().tls_stream.shutdown() } - Stream::NamedHttpClient(ref mut http_stream) => { + Stream::HttpRead(ref mut http_stream) => { unsafe { http_stream.set_tag(ArenaHeaderTag::Dropped); std::ptr::drop_in_place(&mut http_stream.inner_mut().body_reader as *mut _); @@ -1073,6 +1132,14 @@ impl Stream { Ok(()) } + Stream::HttpWrite(ref mut http_stream) => { + unsafe { + http_stream.set_tag(ArenaHeaderTag::Dropped); + std::ptr::drop_in_place(&mut http_stream.inner_mut().body_writer as *mut _); + } + + Ok(()) + } Stream::InputFile(mut file_stream) => { // close the stream by dropping the inner File. unsafe { @@ -1109,7 +1176,7 @@ impl Stream { match self { Stream::NamedTcp(..) | Stream::NamedTls(..) - | Stream::NamedHttpClient(..) + | Stream::HttpRead(..) | Stream::Byte(_) | Stream::Readline(_) | Stream::StaticString(_) @@ -1124,7 +1191,8 @@ impl Stream { Stream::StandardError(_) | Stream::StandardOutput(_) | Stream::NamedTcp(..) - | Stream::NamedTls(..) + | Stream::NamedTls(..) + | Stream::HttpWrite(..) | Stream::Byte(_) | Stream::OutputFile(..) => true, _ => false, @@ -1254,6 +1322,18 @@ impl MachineState { None } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + + if name != atom!("[]") { + Some(name) + } else { + None + } + } _ => { None } @@ -1270,6 +1350,19 @@ impl MachineState { _ => unreachable!(), } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + + match name { + atom!("eof_code") => EOFAction::EOFCode, + atom!("error") => EOFAction::Error, + atom!("reset") => EOFAction::Reset, + _ => unreachable!(), + } + } _ => { unreachable!() } @@ -1280,6 +1373,13 @@ impl MachineState { debug_assert_eq!(arity, 0); name == atom!("true") } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name == atom!("true") + } _ => { unreachable!() } @@ -1294,6 +1394,17 @@ impl MachineState { _ => unreachable!(), } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + match name { + atom!("text") => StreamType::Text, + atom!("binary") => StreamType::Binary, + _ => unreachable!(), + } + } _ => { unreachable!() } @@ -1334,6 +1445,24 @@ impl MachineState { } }; } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + + return match stream_aliases.get(&name) { + Some(stream) if !stream.is_null_stream() => Ok(*stream), + _ => { + let stub = functor_stub(caller, arity); + let addr = atom_as_cell!(name); + + let existence_error = self.existence_error(ExistenceError::Stream(addr)); + + Err(self.error_form(existence_error, stub)) + } + }; + } (HeapCellValueTag::Cons, ptr) => { match_untyped_arena_ptr!(ptr, (ArenaHeaderTag::Stream, stream) => { @@ -1402,9 +1531,9 @@ impl MachineState { arity: usize, ) -> MachineStub { let stub = functor_stub(caller, arity); - let err = self.permission_error(perm, err_atom, stream_as_cell!(stream)); + let err = self.permission_error(perm, err_atom, stream_as_cell!(stream)); - return self.error_form(err, stub); + self.error_form(err, stub) } #[inline] @@ -1430,9 +1559,9 @@ impl MachineState { stub_arity: usize, ) -> MachineStub { let stub = functor_stub(stub_name, stub_arity); - let err = self.permission_error(Permission::Open, atom!("source_sink"), culprit); + let err = self.permission_error(Permission::Open, atom!("source_sink"), culprit); - return self.error_form(err, stub); + self.error_form(err, stub) } pub(crate) fn occupied_alias_permission_error( @@ -1442,24 +1571,22 @@ impl MachineState { stub_arity: usize, ) -> MachineStub { let stub = functor_stub(stub_name, stub_arity); - let alias_name = atom!("alias"); let err = self.permission_error( Permission::Open, atom!("source_sink"), - functor!(alias_name, [atom(alias)]), + functor!(atom!("alias"), [atom(alias)]), ); - return self.error_form(err, stub); + self.error_form(err, stub) } pub(crate) fn reposition_error(&mut self, stub_name: Atom, stub_arity: usize) -> MachineStub { let stub = functor_stub(stub_name, stub_arity); - let rep_stub = functor!(atom!("reposition"), [atom(atom!("true"))]); let err = self.permission_error(Permission::Open, atom!("source_sink"), rep_stub); - return self.error_form(err, stub); + self.error_form(err, stub) } pub(crate) fn check_stream_properties( diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 7e3f5568..b154e266 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -8,9 +8,10 @@ use crate::atom_table::*; use crate::forms::*; use crate::heap_iter::*; use crate::heap_print::*; +use crate::http::{self, HttpListener, HttpResponse}; use crate::instructions::*; use crate::machine; -use crate::machine::{Machine, VERIFY_ATTR_INTERRUPT_LOC}; +use crate::machine::{Machine, VERIFY_ATTR_INTERRUPT_LOC, get_structure_index}; use crate::machine::code_walker::*; use crate::machine::copier::*; use crate::machine::heap::*; @@ -29,22 +30,28 @@ use crate::types::*; use ordered_float::OrderedFloat; +use fxhash::{FxBuildHasher, FxHasher}; use indexmap::IndexSet; use ref_thread_local::{RefThreadLocal, ref_thread_local}; +use std::cell::Cell; +use std::cmp::Ordering; use std::collections::BTreeSet; -use std::convert::TryFrom; +use std::convert::{TryFrom, Infallible}; use std::env; use std::fs; +use std::hash::{BuildHasher, BuildHasherDefault}; use std::io::{ErrorKind, Read, Write}; use std::iter::{once, FromIterator}; use std::mem; -use std::net::{TcpListener, TcpStream}; +use std::net::{TcpListener, TcpStream, SocketAddr, ToSocketAddrs}; use std::num::NonZeroU32; use std::ops::Sub; -use std::str::FromStr; use std::process; +use std::rc::Rc; +use std::str::FromStr; +use std::sync::Arc; use chrono::{offset::Local, DateTime}; use cpu_time::ProcessTime; @@ -62,9 +69,7 @@ use ring::{ use ripemd160::{Digest, Ripemd160}; use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512}; -use openssl::bn::{BigNum, BigNumContext}; -use openssl::ec::{EcGroup, EcPoint}; -use openssl::nid::Nid; +use crrl::secp256k1; use sodiumoxide::crypto::scalarmult::curve25519::*; @@ -74,10 +79,13 @@ use base64; use roxmltree; use select; -use hyper::{Body, Client, HeaderMap, Method, Request, Uri}; +use hyper::{Body, Server, Client, HeaderMap, Method, Request, Response, Uri}; use hyper::header::{HeaderName, HeaderValue}; use hyper::body::Buf; +use hyper::service::{make_service_fn, service_fn}; use hyper_tls::HttpsConnector; +use tokio::sync::Mutex; +use tokio::sync::mpsc::channel; ref_thread_local! { pub(crate) static managed RANDOM_STATE: RandState<'static> = RandState::new(); @@ -173,6 +181,16 @@ impl BrentAlgState { CycleSearchResult::NotList(self.num_steps(), heap[self.hare]) }; } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(heap[s]) + .get_name_and_arity(); + + return if name == atom!("[]") && arity == 0 { + CycleSearchResult::ProperList(self.num_steps()) + } else { + CycleSearchResult::NotList(self.num_steps(), heap[self.hare]) + }; + } (HeapCellValueTag::Lis, l) => { return CycleSearchResult::UntouchedList(self.num_steps(), l); } @@ -439,6 +457,30 @@ impl BrentAlgState { } impl MachineState { + #[inline] + pub(crate) fn variable_set<S: BuildHasher>( + &mut self, + seen_set: &mut IndexSet<HeapCellValue, S>, + value: HeapCellValue, + ) { + let mut iter = stackful_preorder_iter(&mut self.heap, value); + + while let Some(value) = iter.next() { + let value = unmark_cell_bits!(value); + + if value.is_var() { + let value = unmark_cell_bits!(heap_bound_store( + iter.heap, + heap_bound_deref(iter.heap, value) + )); + + if value.is_var() { + seen_set.insert(value); + } + } + } + } + fn skip_max_list_cycle(&mut self, lam: usize) { fn step(heap: &[HeapCellValue], mut value: HeapCellValue) -> usize { loop { @@ -535,7 +577,19 @@ impl MachineState { self.finalize_skip_max_list(n as i64, list_loc_as_cell!(l)); } CycleSearchResult::UntouchedCStr(cstr_atom, n) => { - self.finalize_skip_max_list(n as i64, string_as_cstr_cell!(cstr_atom)); + let cell = if n > 0 { + let h = self.heap.len(); + + self.heap.push(string_as_cstr_cell!(cstr_atom)); + self.heap.push(pstr_offset_as_cell!(h)); + self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64))); + + pstr_loc_as_cell!(h+1) + } else { + string_as_cstr_cell!(cstr_atom) + }; + + self.finalize_skip_max_list(n as i64, cell); } CycleSearchResult::EmptyList => { self.finalize_skip_max_list(0, empty_list_as_cell!()); @@ -820,6 +874,16 @@ impl MachineState { None } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.heap[s]) + .get_name_and_arity(); + + if arity == 0 { + Some(AtomOrString::Atom(name)) + } else { + None + } + } (HeapCellValueTag::Char, c) => { Some(AtomOrString::String(c.to_string())) } @@ -925,6 +989,289 @@ impl MachineState { impl Machine { #[inline(always)] + pub(crate) fn call_inline( + &mut self, + arity: usize, + call_at_index: impl Fn(&mut Machine, Atom, usize, IndexPtr) -> CallResult, + ) -> CallResult { + let arity = arity - 1; + let goal = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + + let load_registers = |machine_st: &mut MachineState, goal: HeapCellValue| -> Option<PredicateKey> { + read_heap_cell!(goal, + (HeapCellValueTag::Str, s) => { + let (name, goal_arity) = cell_as_atom_cell!(machine_st.heap[s]) + .get_name_and_arity(); + + if goal_arity > 0 { + for idx in (1 .. arity + 1).rev() { + machine_st.registers[idx + goal_arity] = machine_st.registers[idx + 1]; + } + } else { + for idx in 1 .. arity + 1 { + machine_st.registers[idx] = machine_st.registers[idx + 1]; + } + } + + for idx in 1 .. goal_arity + 1 { + machine_st.registers[idx] = machine_st.heap[s+idx]; + } + + Some((name, goal_arity)) + } + _ => { + unreachable!() + } + ) + }; + + read_heap_cell!(goal, + (HeapCellValueTag::Str, s) => { + let goal_arity = cell_as_atom_cell!(self.machine_st.heap[s]).get_arity(); + + if self.machine_st.heap.len() > s + goal_arity + 1 { + let index_cell = self.machine_st.heap[s+goal_arity+1]; + + if let Some(code_index) = get_structure_index(index_cell) { + if code_index.is_undefined() { + self.machine_st.fail = true; + return Ok(()); + } + + match load_registers(&mut self.machine_st, goal) { + Some((name, goal_arity)) => { + let arity = goal_arity + arity; + self.machine_st.neck_cut(); + return call_at_index(self, name, arity, code_index.get()); + } + None => { + } + } + } + } + } + _ => { + } + ); + + self.machine_st.fail = true; + Ok(()) + } + + #[inline(always)] + pub(crate) fn compile_inline_or_expanded_goal(&mut self) -> CallResult { + let goal = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + let module_name = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[4])); + + // supp_vars are the supplementary variables generated by + // complete_partial_goal prior to goal_expansion. + let mut supp_vars = IndexSet::with_hasher(FxBuildHasher::default()); + + self.machine_st.variable_set(&mut supp_vars, self.machine_st.registers[2]); + + struct GoalAnalysisResult { + is_simple_goal: bool, + goal: HeapCellValue, + key: PredicateKey, + expanded_vars: IndexSet<HeapCellValue, BuildHasherDefault<FxHasher>>, + supp_vars: IndexSet<HeapCellValue, BuildHasherDefault<FxHasher>>, + } + + let result = read_heap_cell!(goal, + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + let mut expanded_vars = IndexSet::with_hasher(FxBuildHasher::default()); + + // fill expanded_vars with variables of the partial + // goal pre-completion by complete_partial_goal. + for idx in s + 1 .. s + arity - supp_vars.len() + 1 { + self.machine_st.variable_set(&mut expanded_vars, self.machine_st.heap[idx]); + } + + let is_simple_goal = if arity >= supp_vars.len() { + // post_supp_args are the arguments to the + // post-expansion complete goal gathered from the + // final supp_vars.len() arguments. they must + // agree in supp_vars in order of entry of + // insertion as well as the previous + // supp_vars.len() argument's variables being + // disjoint from them. if they are not, the + // expanded goal are not simple. + + let post_supp_args = self.machine_st.heap[s+arity-supp_vars.len()+1 .. s+arity+1] + .iter() + .cloned(); + + post_supp_args + .zip(supp_vars.iter()) + .all(|(arg_term, supp_var)| { + let arg_term = self.machine_st.store(self.machine_st.deref(arg_term)); + + if arg_term.is_var() && supp_var.is_var() { + return arg_term == *supp_var; + } + + false + }) && expanded_vars.intersection(&supp_vars).next().is_none() + } else { + false + }; + + let goal = if is_simple_goal { + let h = self.machine_st.heap.len(); + let arity = arity - supp_vars.len(); + + for idx in 0 .. arity + 1 { + let value = self.machine_st.heap[s + idx]; + self.machine_st.heap.push(value); + } + + self.machine_st.heap[h] = atom_as_cell!(name, arity); + + str_loc_as_cell!(h) + } else { + goal + }; + + GoalAnalysisResult { + is_simple_goal, + goal, + key: (name, arity), + expanded_vars, + supp_vars + } + } + (HeapCellValueTag::Atom, (name, arity)) => { + debug_assert_eq!(arity, 0); + + let h = self.machine_st.heap.len(); + self.machine_st.heap.push(goal); + + GoalAnalysisResult { + is_simple_goal: true, + goal: str_loc_as_cell!(h), + key: (name, 0), + expanded_vars: IndexSet::with_hasher(FxBuildHasher::default()), + supp_vars, + } + } + (HeapCellValueTag::Char, c) => { + let name = self.machine_st.atom_tbl.build_with(&c.to_string()); + + let h = self.machine_st.heap.len(); + self.machine_st.heap.push(atom_as_cell!(name)); + + GoalAnalysisResult { + is_simple_goal: true, + goal: str_loc_as_cell!(h), + key: (name, 0), + expanded_vars: IndexSet::with_hasher(FxBuildHasher::default()), + supp_vars, + } + } + _ => { + self.machine_st.fail = true; + return Ok(()); + } + ); + + if result.key.0 == atom!(":") { + self.machine_st.fail = true; + return Ok(()); + } + + let expanded_term = if result.is_simple_goal { + let idx = self.get_or_insert_qualified_code_index(module_name, result.key); + self.machine_st.heap.push(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx))); + result.goal + } else { + // all supp_vars must appear later! + let vars = IndexSet::<HeapCellValue, BuildHasherDefault<FxHasher>>::from_iter( + result.expanded_vars.difference(&result.supp_vars).cloned() + ); + + let vars: Vec<_> = vars + .union(&result.supp_vars) // difference + union does not cancel. + .map(|v| Term::Var(Cell::default(), Rc::new(format!("_{}", v.get_value())))) + .collect(); + + let helper_clause_loc = self.code.len(); + + match self.compile_standalone_clause(temp_v!(1), &vars) { + Err(e) => { + let err = self.machine_st.session_error(e); + let stub = functor_stub(atom!("call"), result.key.1); + + return Err(self.machine_st.error_form(err, stub)); + } + Ok(()) => { + let h = self.machine_st.heap.len(); + + self.machine_st.heap.push(atom_as_cell!(atom!("$aux"), 0)); + + for value in result.expanded_vars.difference(&result.supp_vars).cloned() { + self.machine_st.heap.push(value); + } + + let anon_str_arity = self.machine_st.heap.len() - h - 1; + + self.machine_st.heap[h] = atom_as_cell!(atom!("$aux"), anon_str_arity); + + let idx = CodeIndex::new( + IndexPtr::index(helper_clause_loc), + &mut self.machine_st.arena, + ); + + self.machine_st.heap.push(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx))); + + str_loc_as_cell!(h) + } + } + }; + + let truncated_goal = self.machine_st.registers[3]; + unify!(&mut self.machine_st, expanded_term, truncated_goal); + + Ok(()) + } + + #[inline(always)] + pub(crate) fn is_expanded_or_inlined(&self) -> bool { + let (_module_loc, qualified_goal) = self.machine_st.strip_module( + self.machine_st.registers[1], + empty_list_as_cell!(), + ); + + if HeapCellValueTag::Str == qualified_goal.get_tag() { + let s = qualified_goal.get_value(); + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + if name == atom!("$call") { + return false; + } + + if self.machine_st.heap.len() > s + 1 + arity { + let idx_cell = self.machine_st.heap[s + 1 + arity]; + + if HeapCellValueTag::Cons == idx_cell.get_tag() { + match_untyped_arena_ptr!(cell_as_untyped_arena_ptr!(idx_cell), + (ArenaHeaderTag::IndexPtr, _ip) => { + return true; + } + _ => { + } + ); + } + } + } + + false + } + + #[inline(always)] pub(crate) fn prepare_call_clause(&mut self, arity: usize) -> CallResult { let (module_loc, qualified_goal) = self.machine_st.strip_module( self.machine_st.registers[3], @@ -969,11 +1316,12 @@ impl Machine { // assemble goal from pre-loaded (narity) and supplementary // (arity) arguments. - let h = self.machine_st.heap.len(); - - self.machine_st.heap.push(atom_as_cell!(name, narity + arity)); + let target_goal = if arity == 0 { + qualified_goal + } else { // if narity + arity > 0 { + let h = self.machine_st.heap.len(); + self.machine_st.heap.push(atom_as_cell!(name, narity + arity)); - let target_goal = if narity + arity > 0 { for idx in 1 .. narity + 1 { self.machine_st.heap.push(self.machine_st.heap[s + idx]); } @@ -982,9 +1330,16 @@ impl Machine { self.machine_st.heap.push(self.machine_st.registers[3 + idx]); } - str_loc_as_cell!(h) - } else { - heap_loc_as_cell!(h) + let index_cell = self.machine_st.heap[s + narity + 1]; + + if get_structure_index(index_cell).is_some() { + self.machine_st.heap.push(index_cell); + str_loc_as_cell!(h) + } else if narity + arity > 0 { + str_loc_as_cell!(h) + } else { + heap_loc_as_cell!(h) + } }; let target_qualified_goal = self.machine_st.registers[1]; @@ -1391,6 +1746,19 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[2], list_loc_as_cell!(h)); } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + if arity == 0 { + self.machine_st.unify_complete_string( + name, + self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])), + ); + } else { + self.machine_st.fail = true; + } + } (HeapCellValueTag::Atom, (name, arity)) => { if arity == 0 { self.machine_st.unify_complete_string( @@ -1454,6 +1822,20 @@ impl Machine { self.machine_st.fail = true; } } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + if arity == 0 { + let iter = name.chars() + .map(|c| fixnum_as_cell!(Fixnum::build_with(c as i64))); + + let h = iter_to_heap_list(&mut self.machine_st.heap, iter); + unify!(self.machine_st, heap_loc_as_cell!(h), self.machine_st.registers[2]); + } else { + self.machine_st.fail = true; + } + } (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => { let stub_gen = || functor_stub(atom!("atom_codes"), 2); @@ -1482,6 +1864,17 @@ impl Machine { let a1 = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); let len: i64 = read_heap_cell!(a1, + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + if arity == 0 { + name.chars().count() as i64 + } else { + self.machine_st.fail = true; + return; + } + } (HeapCellValueTag::Atom, (name, arity)) => { if arity == 0 { name.chars().count() as i64 @@ -2019,6 +2412,13 @@ impl Machine { (HeapCellValueTag::Atom, (name, _arity)) => { name.as_char().unwrap() } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name.as_char().unwrap() + } (HeapCellValueTag::Char, c) => { c } @@ -2080,6 +2480,13 @@ impl Machine { (HeapCellValueTag::Atom, (name, _arity)) => { name.as_char().unwrap() } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name.as_char().unwrap() + } _ => { unreachable!() } @@ -2985,7 +3392,7 @@ impl Machine { } #[inline(always)] - pub(crate) fn delete_head_attribute(&mut self) { + pub(crate) fn delete_head_attribute(&mut self) { let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); debug_assert_eq!(addr.get_tag(), HeapCellValueTag::AttrVar); @@ -3016,25 +3423,57 @@ impl Machine { &mut self, narity: usize, ) -> Result<(Atom, PredicateKey), MachineStub> { - let module_name = cell_as_atom!(self.machine_st.store(self.machine_st.deref( - self.machine_st.registers[1 + narity] - ))); + let module_name = self.machine_st.store(self.machine_st.deref( + self.machine_st.registers[1] + )); + + let module_name = read_heap_cell!(module_name, + (HeapCellValueTag::Atom, (name, _arity)) => { + debug_assert_eq!(_arity, 0); + name + } + (HeapCellValueTag::Str, s) => { + let (module_name, _arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(_arity, 0); + module_name + } + _ if module_name.is_var() => { + atom!("user") + } + _ => { + unreachable!() + } + ); let goal = self.machine_st.store(self.machine_st.deref( - self.machine_st.registers[2 + narity] + self.machine_st.registers[2] )); let (name, arity, s) = self.machine_st.setup_call_n_init_goal_info(goal, narity)?; - for i in (arity + 1..arity + narity + 1).rev() { - self.machine_st.registers[i] = self.machine_st.registers[i - arity]; + match arity.cmp(&2) { + Ordering::Less => { + for i in arity + 1..arity + narity + 1 { + self.machine_st.registers[i] = self.machine_st.registers[i + 2 - arity]; + } + } + Ordering::Greater => { + for i in (arity + 1..arity + narity + 1).rev() { + self.machine_st.registers[i] = self.machine_st.registers[i + 2 - arity]; + } + } + Ordering::Equal => {} } + let key = (name, arity + narity); + for i in 1..arity + 1 { self.machine_st.registers[i] = self.machine_st.heap[s + i]; } - Ok((module_name, (name, arity + narity))) + Ok((module_name, key)) } #[inline(always)] @@ -3122,6 +3561,9 @@ impl Machine { (HeapCellValueTag::Atom, (name, _arity)) => { name } + (HeapCellValueTag::Str, s) => { + cell_as_atom!(self.machine_st.heap[s]) + } (HeapCellValueTag::Char, c) => { self.machine_st.atom_tbl.build_with(&c.to_string()) } @@ -3151,6 +3593,12 @@ impl Machine { let (op_prec, op_spec) = (op_desc.get_prec(), op_desc.get_spec()); + if op_prec == 0 { + // 8.14.4, note 2 + self.machine_st.fail = true; + return; + } + let op_spec = match op_spec as u32 { XFX => atom!("xfx"), XFY => atom!("xfy"), @@ -3177,6 +3625,12 @@ impl Machine { for op_desc in op_descs { if let Some((key, op_desc)) = op_desc { let (prec, spec) = (op_desc.get_prec(), op_desc.get_spec()); + + if prec == 0 { + // 8.14.4, note 2 + continue; + } + unossified_op_dir.insert(*key, (prec as usize, spec as Specifier)); } } @@ -3193,6 +3647,7 @@ impl Machine { let name = key.0; if other_prec == 0 { + // 8.14.4, note 2 return None; } @@ -3475,6 +3930,203 @@ impl Machine { } #[inline(always)] + pub(crate) fn http_listen(&mut self) -> CallResult { + let address_sink = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + if let Some(address_str) = self.machine_st.value_to_str_like(address_sink) { + let address_string = address_str.as_str(); + let addr: SocketAddr = match address_string.to_socket_addrs().ok().and_then(|mut s| s.next()) { + Some(addr) => addr, + _ => { + self.machine_st.fail = true; + return Ok(()); + } + }; + + let (tx, rx) = channel(1); + let tx = Arc::new(Mutex::new(tx)); + + let _guard = self.runtime.enter(); + let server = match Server::try_bind(&addr) { + Ok(server) => server, + Err(_) => { + return Err(self.machine_st.open_permission_error(address_sink, atom!("http_listen"), 2)); + } + }; + + self.runtime.spawn(async move { + let make_svc = make_service_fn(move |_conn| { + let tx = tx.clone(); + async move { Ok::<_, Infallible>(service_fn(move |req| http::serve_req(req, tx.clone()))) } + }); + let server = server.serve(make_svc); + + if let Err(_) = server.await { + eprintln!("server error"); + } + }); + let http_listener = HttpListener { incoming: rx }; + let http_listener = arena_alloc!(http_listener, &mut self.machine_st.arena); + let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])); + self.machine_st.bind(addr.as_var().unwrap(), typed_arena_ptr_as_cell!(http_listener)); + } + Ok(()) + } + + #[inline(always)] + pub(crate) fn http_accept(&mut self) -> CallResult { + let culprit = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + let method = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])); + let path = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[3])); + let query = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[5])); + let stream_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[6])); + let handle_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[7])); + read_heap_cell!(culprit, + (HeapCellValueTag::Cons, cons_ptr) => { + match_untyped_arena_ptr!(cons_ptr, + (ArenaHeaderTag::HttpListener, http_listener) => { + match http_listener.incoming.blocking_recv() { + Some(request) => { + let method_atom = match *request.request.method() { + Method::GET => atom!("get"), + Method::POST => atom!("post"), + Method::PUT => atom!("put"), + Method::DELETE => atom!("delete"), + Method::PATCH => atom!("patch"), + Method::HEAD => atom!("head"), + _ => unreachable!(), + }; + let path_atom = self.machine_st.atom_tbl.build_with(request.request.uri().path()); + let path_cell = atom_as_cstr_cell!(path_atom); + let headers: Vec<HeapCellValue> = request.request.headers().iter().map(|(header_name, header_value)| { + let h = self.machine_st.heap.len(); + + let header_term = functor!( + self.machine_st.atom_tbl.build_with(header_name.as_str()), + [cell(string_as_cstr_cell!(self.machine_st.atom_tbl.build_with(header_value.to_str().unwrap())))] + ); + + self.machine_st.heap.extend(header_term.into_iter()); + str_loc_as_cell!(h) + }).collect(); + + let headers_list = iter_to_heap_list(&mut self.machine_st.heap, headers.into_iter()); + + let query_str = request.request.uri().query().unwrap_or(""); + let query_atom = self.machine_st.atom_tbl.build_with(query_str); + let query_cell = string_as_cstr_cell!(query_atom); + + let hyper_req = request.request; + let buf = self.runtime.block_on(async {hyper::body::aggregate(hyper_req).await.unwrap()}); + let reader = buf.reader(); + + let mut stream = Stream::from_http_stream( + path_atom, + Box::new(reader), + &mut self.machine_st.arena + ); + *stream.options_mut() = StreamOptions::default(); + stream.options_mut().set_stream_type(StreamType::Binary); + self.indices.streams.insert(stream); + let stream = stream_as_cell!(stream); + + let handle = arena_alloc!(request.response, &mut self.machine_st.arena); + + self.machine_st.bind(method.as_var().unwrap(), atom_as_cell!(method_atom)); + self.machine_st.bind(path.as_var().unwrap(), path_cell); + unify!(self.machine_st, heap_loc_as_cell!(headers_list), self.machine_st.registers[4]); + self.machine_st.bind(query.as_var().unwrap(), query_cell); + self.machine_st.bind(stream_addr.as_var().unwrap(), stream); + self.machine_st.bind(handle_addr.as_var().unwrap(), typed_arena_ptr_as_cell!(handle)); + } + None => { + self.machine_st.fail = true; + } + } + } + _ => { + unreachable!(); + } + ); + } + _ => { + unreachable!(); + } + ); + Ok(()) + } + + #[inline(always)] + pub(crate) fn http_answer(&mut self) -> CallResult { + let culprit = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + let status_code = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])); + let status_code: u16 = match Number::try_from(status_code) { + Ok(Number::Fixnum(n)) => n.get_num() as u16, + Ok(Number::Integer(n)) => match n.to_u16() { + Some(u) => u, + _ => { + self.machine_st.fail = true; + return Ok(()); + } + } + _ => unreachable!() + }; + let stub_gen = || functor_stub(atom!("http_listen"), 2); + let headers = match self.machine_st.try_from_list(self.machine_st.registers[3], stub_gen) { + Ok(addrs) => { + let mut header_map = HeaderMap::new(); + for heap_cell in addrs{ + read_heap_cell!(heap_cell, + (HeapCellValueTag::Str, s) => { + let name = cell_as_atom_cell!(self.machine_st.heap[s]).get_name(); + let value = self.machine_st.value_to_str_like(self.machine_st.heap[s + 1]).unwrap(); + header_map.insert(HeaderName::from_str(name.as_str()).unwrap(), HeaderValue::from_str(value.as_str()).unwrap()); + } + _ => { + unreachable!() + } + ) + } + header_map + }, + Err(e) => return Err(e) + }; + let stream_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[4])); + + read_heap_cell!(culprit, + (HeapCellValueTag::Cons, cons_ptr) => { + match_untyped_arena_ptr!(cons_ptr, + (ArenaHeaderTag::HttpResponse, http_response) => { + let mut response = Response::builder() + .status(status_code); + *response.headers_mut().unwrap() = headers; + let (sender, body) = Body::channel(); + let response = response.body(body).unwrap(); + http_response.blocking_send(response).unwrap(); + + let mut stream = Stream::from_http_sender( + sender, + &mut self.machine_st.arena + ); + *stream.options_mut() = StreamOptions::default(); + stream.options_mut().set_stream_type(StreamType::Binary); + self.indices.streams.insert(stream); + let stream = stream_as_cell!(stream); + self.machine_st.bind(stream_addr.as_var().unwrap(), stream); + } + _ => { + unreachable!(); + } + ); + } + _ => { + unreachable!(); + } + ); + + Ok(()) + } + + #[inline(always)] pub(crate) fn current_time(&mut self) { let timestamp = self.systemtime_to_timestamp(SystemTime::now()); self.machine_st.unify_complete_string(timestamp, self.machine_st.registers[1]); @@ -3544,6 +4196,9 @@ impl Machine { (HeapCellValueTag::Atom, (name, _arity)) => { name } + (HeapCellValueTag::Str, s) => { + cell_as_atom!(self.machine_st.heap[s]) + } _ => { unreachable!() } @@ -3906,9 +4561,7 @@ impl Machine { let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) .get_name_and_arity(); - let ct = ClauseType::from(name, arity); - - if ct.is_inlined() || ct.is_builtin() { + if ClauseType::is_inbuilt(name, arity) { true } else { let index = self.indices.get_predicate_code_index( @@ -3917,10 +4570,10 @@ impl Machine { module_name, ) .map(|index| index.get()) - .unwrap_or(IndexPtr::DynamicUndefined); + .unwrap_or(IndexPtr::dynamic_undefined()); - match index { - IndexPtr::DynamicUndefined | IndexPtr::Undefined => false, + match index.tag() { + IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined => false, _ => true, } } @@ -3928,9 +4581,7 @@ impl Machine { (HeapCellValueTag::Atom, (name, arity)) => { debug_assert_eq!(arity, 0); - let ct = ClauseType::from(name, 0); - - if ct.is_inlined() || ct.is_builtin() { + if ClauseType::is_inbuilt(name, 0) { true } else { let index = self.indices.get_predicate_code_index( @@ -3939,10 +4590,10 @@ impl Machine { module_name, ) .map(|index| index.get()) - .unwrap_or(IndexPtr::DynamicUndefined); + .unwrap_or(IndexPtr::dynamic_undefined()); - match index { - IndexPtr::DynamicUndefined => false, + match index.tag() { + IndexPtrTag::DynamicUndefined => false, _ => true, } } @@ -4154,11 +4805,6 @@ impl Machine { } #[inline(always)] - pub(crate) fn erase_ball(&mut self) { - self.machine_st.ball.reset(); - } - - #[inline(always)] pub(crate) fn get_ball(&mut self) { let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); let h = self.machine_st.heap.len(); @@ -4178,6 +4824,29 @@ impl Machine { } #[inline(always)] + pub(crate) fn push_ball_stack(&mut self) { + if self.machine_st.ball.stub.len() > 0 { + self.machine_st.ball_stack.push( + mem::replace(&mut self.machine_st.ball, Ball::new()) + ); + } else { + self.machine_st.fail = true; + } + } + + #[inline(always)] + pub(crate) fn pop_ball_stack(&mut self) { + self.machine_st.ball_stack.pop(); + } + + #[inline(always)] + pub(crate) fn pop_from_ball_stack(&mut self) { + if let Some(ball) = self.machine_st.ball_stack.pop() { + self.machine_st.ball = ball; + } + } + + #[inline(always)] pub(crate) fn get_current_block(&mut self) { let n = Fixnum::build_with(i64::try_from(self.machine_st.block).unwrap()); self.machine_st.unify_fixnum(n, self.machine_st.registers[1]); @@ -4208,7 +4877,9 @@ impl Machine { LOC_INIT.call_once(|| { if let Some(builtins) = self.indices.modules.get(&atom!("builtins")) { match builtins.code_dir.get(&(atom!("staggered_sc"), 2)).map(|cell| cell.get()) { - Some(IndexPtr::Index(p)) => { + Some(ip) if ip.tag() == IndexPtrTag::Index => { + let p = ip.p() as usize; + match &self.code[p] { &Instruction::TryMeElse(o) => { SEMICOLON_SECOND_BRANCH_LOC = p + o; @@ -4253,30 +4924,40 @@ impl Machine { pub(crate) fn next_ep(&mut self) { let first_arg = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); - read_heap_cell!(first_arg, - (HeapCellValueTag::Atom, (name, arity)) => { - debug_assert_eq!(name, atom!("first")); - debug_assert_eq!(arity, 0); + let next_ep_atom = |machine_st: &mut MachineState, name, arity| { + debug_assert_eq!(name, atom!("first")); + debug_assert_eq!(arity, 0); - if self.machine_st.e == 0 { - self.machine_st.fail = true; - return; - } + if machine_st.e == 0 { + machine_st.fail = true; + return; + } - let and_frame = self.machine_st.stack.index_and_frame(self.machine_st.e); - let cp = and_frame.prelude.cp - 1; + let and_frame = machine_st.stack.index_and_frame(machine_st.e); + let cp = and_frame.prelude.cp - 1; - let e = and_frame.prelude.e; - let e = Fixnum::build_with(i64::try_from(e).unwrap()); + let e = and_frame.prelude.e; + let e = Fixnum::build_with(i64::try_from(e).unwrap()); - let p = str_loc_as_cell!(self.machine_st.heap.len()); + let p = str_loc_as_cell!(machine_st.heap.len()); - self.machine_st.heap.extend(functor!(atom!("dir_entry"), [fixnum(cp)])); - self.machine_st.unify_fixnum(e, self.machine_st.registers[2]); + machine_st.heap.extend(functor!(atom!("dir_entry"), [fixnum(cp)])); + machine_st.unify_fixnum(e, machine_st.registers[2]); - if !self.machine_st.fail { - unify!(self.machine_st, p, self.machine_st.registers[3]); - } + if !machine_st.fail { + unify!(machine_st, p, machine_st.registers[3]); + } + }; + + read_heap_cell!(first_arg, + (HeapCellValueTag::Atom, (name, arity)) => { + next_ep_atom(&mut self.machine_st, name, arity); + } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + next_ep_atom(&mut self.machine_st, name, arity); } (HeapCellValueTag::Fixnum, n) => { let e = n.get_num() as usize; @@ -4346,6 +5027,13 @@ impl Machine { debug_assert_eq!(arity, 0); self.machine_st.fail = non_quoted_token(name.as_str().chars()); } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + self.machine_st.fail = non_quoted_token(name.as_str().chars()); + } _ => { self.machine_st.fail = true; } @@ -4480,6 +5168,13 @@ impl Machine { debug_assert_eq!(arity, 0); name } + (HeapCellValueTag::Str, s) => { + let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) + .get_name_and_arity(); + + debug_assert_eq!(arity, 0); + name + } _ => { self.machine_st.atom_tbl.build_with(&match Number::try_from(port) { Ok(Number::Fixnum(n)) => n.get_num().to_string(), @@ -5011,26 +5706,9 @@ impl Machine { return; } - let mut seen_set = IndexSet::new(); - - { - let mut iter = stackful_preorder_iter(&mut self.machine_st.heap, stored_v); - - while let Some(value) = iter.next() { - let value = unmark_cell_bits!(value); - - if value.is_var() { - let value = unmark_cell_bits!(heap_bound_store( - iter.heap, - heap_bound_deref(iter.heap, value) - )); + let mut seen_set = IndexSet::with_hasher(FxBuildHasher::default()); - if value.is_var() { - seen_set.insert(value); - } - } - } - } + self.machine_st.variable_set(&mut seen_set, stored_v); let outcome = heap_loc_as_cell!( iter_to_heap_list(&mut self.machine_st.heap, seen_set.into_iter()) @@ -5271,9 +5949,15 @@ impl Machine { }; let result = printer.print().result(); - let chars = put_complete_string(&mut self.machine_st.heap, &result, &mut self.machine_st.atom_tbl); + let chars = put_complete_string( + &mut self.machine_st.heap, + &result, + &mut self.machine_st.atom_tbl, + ); - let result_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + let result_addr = self.machine_st.store(self.machine_st.deref( + self.machine_st.registers[1] + )); if let Some(var) = result_addr.as_var() { self.machine_st.bind(var, chars); @@ -5612,15 +6296,7 @@ impl Machine { ) ); - let complete_string = { - let buffer = String::from_iter(in_out.iter().map(|b| *b as char)); - - if buffer.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&buffer)) - } - }; + let complete_string = self.u8s_to_string(&in_out); unify!(self.machine_st, self.machine_st.registers[6], tag_list); unify!(self.machine_st, self.machine_st.registers[7], complete_string); @@ -5680,74 +6356,24 @@ impl Machine { #[inline(always)] pub(crate) fn crypto_curve_scalar_mult(&mut self) { - let curve = cell_as_atom!(self.machine_st.registers[1]); - let curve_id = match curve { - atom!("secp112r1") => Nid::SECP112R1, - atom!("secp256k1") => Nid::SECP256K1, - _ => { - unreachable!() - } - }; + let stub_gen = || functor_stub(atom!("crypto_curve_scalar_mult"), 4); + let scalar_bytes = self.machine_st.integers_to_bytevec(self.machine_st.registers[2], stub_gen); + let point_bytes = self.machine_st.integers_to_bytevec(self.machine_st.registers[3], stub_gen); - let scalar = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])); + let mut point = secp256k1::Point::decode(&point_bytes).unwrap(); + let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes); + point *= scalar; - let scalar = match Number::try_from(scalar) { - Ok(Number::Fixnum(n)) => Integer::from(n.get_num()), - Ok(Number::Integer(n)) => Integer::from(&*n), - _ => { - unreachable!() - } - }; - - let stub_gen = || functor_stub(atom!("crypto_curve_scalar_mult"), 5); - let qbytes = self.machine_st.integers_to_bytevec(self.machine_st.registers[3], stub_gen); - - let mut bnctx = BigNumContext::new().unwrap(); - let group = EcGroup::from_curve_name(curve_id).unwrap(); - let mut point = EcPoint::from_bytes(&group, &qbytes, &mut bnctx).unwrap(); - let scalar_bn = BigNum::from_dec_str(&scalar.to_string()).unwrap(); - let mut result = EcPoint::new(&group).unwrap(); - - result.mul(&group, &mut point, &scalar_bn, &mut bnctx).ok(); - - let mut rx = BigNum::new().unwrap(); - let mut ry = BigNum::new().unwrap(); - - result - .affine_coordinates_gfp(&group, &mut rx, &mut ry, &mut bnctx) - .ok(); - - let sx = rx.to_dec_str().unwrap(); - let sx = if sx.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&sx)) - }; - - let sy = ry.to_dec_str().unwrap(); - let sy = if sy.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&sy)) - }; + let uncompressed = self.u8s_to_string(&point.encode_uncompressed()); - unify!(self.machine_st, self.machine_st.registers[4], sx); - unify!(self.machine_st, self.machine_st.registers[5], sy); + unify!(self.machine_st, self.machine_st.registers[4], uncompressed); } #[inline(always)] pub(crate) fn ed25519_new_key_pair(&mut self) { let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(rng()).unwrap(); - let complete_string = { - let buffer = String::from_iter(pkcs8_bytes.as_ref().iter().map(|b| *b as char)); - - if buffer.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&buffer)) - } - }; + let complete_string = self.u8s_to_string(pkcs8_bytes.as_ref()); unify!(self.machine_st, self.machine_st.registers[1], complete_string) } @@ -5764,17 +6390,7 @@ impl Machine { } }; - let complete_string = { - let buffer = String::from_iter( - key_pair.public_key().as_ref().iter().map(|b| *b as char), - ); - - if buffer.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&buffer)) - } - }; + let complete_string = self.u8s_to_string(key_pair.public_key().as_ref()); unify!(self.machine_st, self.machine_st.registers[2], complete_string); } @@ -5837,14 +6453,9 @@ impl Machine { let result = scalarmult(&scalar, &point).unwrap(); - let string = String::from_iter(result[..].iter().map(|b| *b as char)); - let cstr = if string.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&string)) - }; + let string = self.u8s_to_string(&result[..]); - unify!(self.machine_st, self.machine_st.registers[3], cstr); + unify!(self.machine_st, self.machine_st.registers[3], string); } #[inline(always)] @@ -6026,14 +6637,9 @@ impl Machine { match bytes { Ok(bs) => { - let string = String::from_iter(bs.iter().map(|b| *b as char)); - let cstr = if string.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&string)) - }; + let string = self.u8s_to_string(&bs); - unify!(self.machine_st, self.machine_st.registers[1], cstr); + unify!(self.machine_st, self.machine_st.registers[1], string); } _ => { self.machine_st.fail = true; @@ -6043,28 +6649,13 @@ impl Machine { } else { let mut bytes = vec![]; for c in self.machine_st.value_to_str_like(self.machine_st.registers[1]).unwrap().as_str().chars() { - if c as u32 > 255 { - let stub = functor_stub(atom!("chars_base64"), 3); - - let err = self.machine_st.type_error( - ValidType::Byte, - char_as_cell!(c), - ); - - return Err(self.machine_st.error_form(err, stub)); - } - bytes.push(c as u8); } let b64 = base64::encode_config(bytes, config); - let cstr = if b64.len() == 0 { - empty_list_as_cell!() - } else { - atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&b64)) - }; + let string = self.u8s_to_string(&b64.as_bytes()); - unify!(self.machine_st, self.machine_st.registers[2], cstr); + unify!(self.machine_st, self.machine_st.registers[2], string); } Ok(()) @@ -6340,6 +6931,16 @@ impl Machine { } } } + + pub(super) fn u8s_to_string(&mut self, data: &[u8]) -> HeapCellValue { + let buffer = String::from_iter(data.iter().map(|b| *b as char)); + + if buffer.len() == 0 { + empty_list_as_cell!() + } else { + atom_as_cstr_cell!(self.machine_st.atom_tbl.build_with(&buffer)) + } + } } fn rng() -> &'static dyn SecureRandom { diff --git a/src/machine/term_stream.rs b/src/machine/term_stream.rs index a1d38271..bb92c8d4 100644 --- a/src/machine/term_stream.rs +++ b/src/machine/term_stream.rs @@ -119,3 +119,21 @@ impl TermStream for LiveTermStream { &self.listing_src } } + +pub struct InlineTermStream { +} + +impl TermStream for InlineTermStream { + fn next(&mut self, _: &CompositeOpDir) -> Result<Term, CompilationError> { + Err(CompilationError::from(ParserError::UnexpectedEOF)) + } + + fn eof(&mut self) -> Result<bool, CompilationError> { + Ok(true) + } + + fn listing_src(&self) -> &ListingSource { + &ListingSource::User + } +} + diff --git a/src/macros.rs b/src/macros.rs index e341647b..85e2e086 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -272,6 +272,26 @@ macro_rules! match_untyped_arena_ptr_pat_body { #[allow(unused_braces)] $code }}; + ($ptr:ident, HttpListener, $listener:ident, $code:expr) => {{ + let payload_ptr = unsafe { std::mem::transmute::<_, *mut HttpListener>($ptr.payload_offset()) }; + #[allow(unused_mut)] + let mut $listener = TypedArenaPtr::new(payload_ptr); + #[allow(unused_braces)] + $code + }}; + ($ptr:ident, HttpResponse, $listener:ident, $code:expr) => {{ + let payload_ptr = unsafe { std::mem::transmute::<_, *mut HttpResponse>($ptr.payload_offset()) }; + #[allow(unused_mut)] + let mut $listener = TypedArenaPtr::new(payload_ptr); + #[allow(unused_braces)] + $code + }}; + ($ptr:ident, IndexPtr, $ip:ident, $code:expr) => {{ + #[allow(unused_mut)] + let mut $ip = TypedArenaPtr::new(unsafe { std::mem::transmute::<_, *mut IndexPtr>($ptr.get_ptr()) }); + #[allow(unused_braces)] + $code + }}; ($ptr:ident, $($tags:tt)|+, $s:ident, $code:expr) => {{ let $s = Stream::from_tag($ptr.get_tag(), $ptr.payload_offset()); #[allow(unused_braces)] @@ -285,13 +305,20 @@ macro_rules! match_untyped_arena_ptr_pat { | ArenaHeaderTag::OutputFileStream | ArenaHeaderTag::NamedTcpStream | ArenaHeaderTag::NamedTlsStream - | ArenaHeaderTag::NamedHttpClientStream + | ArenaHeaderTag::HttpReadStream + | ArenaHeaderTag::HttpWriteStream | ArenaHeaderTag::ReadlineStream | ArenaHeaderTag::StaticStringStream | ArenaHeaderTag::ByteStream | ArenaHeaderTag::StandardOutputStream | ArenaHeaderTag::StandardErrorStream }; + (IndexPtr) => { + ArenaHeaderTag::IndexPtrUndefined | + ArenaHeaderTag::IndexPtrDynamicUndefined | + ArenaHeaderTag::IndexPtrDynamicIndex | + ArenaHeaderTag::IndexPtrIndex + }; ($tag:ident) => { ArenaHeaderTag::$tag }; diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 6c70df8b..b1c0f5d9 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -1,5 +1,6 @@ use crate::arena::*; use crate::atom_table::*; +use crate::machine::machine_indices::*; use crate::parser::char_reader::*; use crate::types::HeapCellValueTag; @@ -530,6 +531,7 @@ impl Neg for Fixnum { pub enum Literal { Atom(Atom), Char(char), + CodeIndex(CodeIndex), Fixnum(Fixnum), Integer(TypedArenaPtr<Integer>), Rational(TypedArenaPtr<Rational>), @@ -551,6 +553,7 @@ impl fmt::Display for Literal { write!(f, "{}", atom.flat_index()) } Literal::Char(c) => write!(f, "'{}'", *c as u32), + Literal::CodeIndex(i) => write!(f, "{:x}", i.as_ptr() as u64), Literal::Fixnum(n) => write!(f, "{}", n.get_num()), Literal::Integer(ref n) => write!(f, "{}", n), Literal::Rational(ref n) => write!(f, "{}", n), diff --git a/src/parser/lexer.rs b/src/parser/lexer.rs index 887a3562..9aeacd82 100644 --- a/src/parser/lexer.rs +++ b/src/parser/lexer.rs @@ -1,5 +1,6 @@ use lexical::parse_lossy; +use crate::arena::ArenaAllocated; use crate::atom_table::*; pub use crate::machine::machine_state::*; use crate::parser::ast::*; diff --git a/src/read.rs b/src/read.rs index 3f8282c0..c8743c2f 100644 --- a/src/read.rs +++ b/src/read.rs @@ -336,7 +336,7 @@ impl<'a, 'b> TermWriter<'a, 'b> { self.push_stub_addr(); self.push_stub_addr(); } - &TermRef::Clause(Level::Root, _, ref ct, subterms) => { + &TermRef::Clause(Level::Root, _, name, subterms) => { if subterms.len() > MAX_ARITY { return Err(CompilationError::ExceededMaxArity); } @@ -348,7 +348,7 @@ impl<'a, 'b> TermWriter<'a, 'b> { }); self.queue.push_back((subterms.len(), h + 2)); - let named = atom_as_cell!(ct.name(), subterms.len()); + let named = atom_as_cell!(name, subterms.len()); self.heap.push(named); @@ -358,9 +358,9 @@ impl<'a, 'b> TermWriter<'a, 'b> { continue; } - &TermRef::Clause(_, _, ref ct, subterms) => { + &TermRef::Clause(_, _, name, subterms) => { self.queue.push_back((subterms.len(), h + 1)); - let named = atom_as_cell!(ct.name(), subterms.len()); + let named = atom_as_cell!(name, subterms.len()); self.heap.push(named); @@ -390,6 +390,12 @@ impl<'a, 'b> TermWriter<'a, 'b> { put_complete_string(self.heap, src.as_str(), self.atom_tbl); } &TermRef::PartialString(lvl, _, ref src, _) => { + if let Level::Root = lvl { + // Var tags can't refer directly to partial strings, + // so a PStrLoc cell must be pushed. + self.heap.push(pstr_loc_as_cell!(heap_loc + 1)); + } + allocate_pstr(self.heap, src.as_str(), self.atom_tbl); let h = self.heap.len(); diff --git a/src/toplevel.pl b/src/toplevel.pl index 4b3e0b34..8caea7ba 100644 --- a/src/toplevel.pl +++ b/src/toplevel.pl @@ -172,7 +172,7 @@ instruction_match(Term, VarList) :- ; Term = end_of_file -> halt ; - submit_query_and_print_results(Term, VarList) + submit_query_and_print_results(Term, VarList) ). @@ -180,7 +180,7 @@ submit_query_and_print_results_(Term, VarList) :- '$get_b_value'(B), bb_put('$report_all', false), bb_put('$report_n_more', 0), - '$call'(Term), + call(user:Term), write_eqs_and_read_input(B, VarList), !. submit_query_and_print_results_(_, _) :- @@ -192,12 +192,12 @@ submit_query_and_print_results_(_, _) :- nl. -submit_query_and_print_results(Term0, VarList) :- - ( functor(Term0, call, _) -> - Term = Term0 % prevent pre-mature expansion of incomplete goal - % in the first argument, which is done by call/N - ; expand_goal(Term0, user, Term) - ), +submit_query_and_print_results(Term, VarList) :- + % ( functor(Term0, call, _) -> + % Term = Term0 % prevent pre-mature expansion of incomplete goal + % % in the first argument, which is done by call/N + % ; expand_goal(Term0, user, Term) + % ), bb_put('$answer_count', 0), submit_query_and_print_results_(Term, VarList). @@ -301,6 +301,7 @@ write_eqs_and_read_input(B, VarList) :- append(Equations, AttrGoals, Goals), % one layer of depth added for (=/2) functor maplist(\Term^Vs^term_variables_under_max_depth(Term, 22, Vs), Equations, EquationVars), + % maplist(term_variables_under_max_depth(22), Equations, EquationVars), append([AttrGoalVars | EquationVars], Vars1), term_variables(Vars1, Vars2), % deduplicate vars of Vars1 but preserve their order. charsio:extend_var_list(Vars2, VarList, NewVarList0, fabricated), diff --git a/src/types.rs b/src/types.rs index be940a54..168f0e84 100644 --- a/src/types.rs +++ b/src/types.rs @@ -301,7 +301,7 @@ impl fmt::Debug for HeapCellValue { } } -impl<T> From<TypedArenaPtr<T>> for HeapCellValue { +impl<T: ArenaAllocated> From<TypedArenaPtr<T>> for HeapCellValue { #[inline] fn from(arena_ptr: TypedArenaPtr<T>) -> HeapCellValue { HeapCellValue::from(arena_ptr.header_ptr() as u64) @@ -441,20 +441,22 @@ impl HeapCellValue { } #[inline] - pub fn is_compound(self) -> bool { + pub fn is_compound(self, heap: &[HeapCellValue]) -> bool { match self.get_tag() { - HeapCellValueTag::Str - | HeapCellValueTag::Lis - | HeapCellValueTag::CStr - | HeapCellValueTag::PStr - | HeapCellValueTag::PStrLoc - | HeapCellValueTag::PStrOffset => { + HeapCellValueTag::Str => { + cell_as_atom_cell!(heap[self.get_value()]).get_arity() > 0 + } + HeapCellValueTag::Lis | + HeapCellValueTag::CStr | + HeapCellValueTag::PStr | + HeapCellValueTag::PStrLoc | + HeapCellValueTag::PStrOffset => { true - } - HeapCellValueTag::Atom => { - cell_as_atom_cell!(self).get_arity() > 0 - } - _ => { false } + } + HeapCellValueTag::Atom => { + cell_as_atom_cell!(self).get_arity() > 0 + } + _ => { false } } } @@ -582,7 +584,7 @@ impl HeapCellValue { } } - pub fn order_category(self) -> Option<TermOrderCategory> { + pub fn order_category(self, heap: &[HeapCellValue]) -> Option<TermOrderCategory> { match Number::try_from(self).ok() { Some(Number::Integer(_)) | Some(Number::Fixnum(_)) | Some(Number::Rational(_)) => { Some(TermOrderCategory::Integer) @@ -601,9 +603,19 @@ impl HeapCellValue { }) } HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc | - HeapCellValueTag::CStr | HeapCellValueTag::Str => { + HeapCellValueTag::CStr => { Some(TermOrderCategory::Compound) } + HeapCellValueTag::Str => { + let value = heap[self.get_value()]; + let arity = cell_as_atom_cell!(value).get_arity(); + + if arity == 0 { + Some(TermOrderCategory::Atom) + } else { + Some(TermOrderCategory::Compound) + } + } _ => { None } @@ -628,7 +640,7 @@ const_assert!(mem::size_of::<HeapCellValue>() == 8); #[bitfield] #[repr(u64)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct UntypedArenaPtr { ptr: B61, m: bool, @@ -644,6 +656,13 @@ impl From<*const ArenaHeader> for UntypedArenaPtr { } } +impl From<*const IndexPtr> for UntypedArenaPtr { + #[inline] + fn from(ptr: *const IndexPtr) -> UntypedArenaPtr { + unsafe { mem::transmute(ptr) } + } +} + impl From<UntypedArenaPtr> for *const ArenaHeader { #[inline] fn from(ptr: UntypedArenaPtr) -> *const ArenaHeader { |