Compare commits

..

366 Commits

Author SHA1 Message Date
Alex Auvolat 8670140358 [rel-0.9.3] Bump version to 0.9.3 2024-03-04 14:00:55 +01:00
Alex 5bb69a1257 Merge pull request 'Add API test + fix presigned requests' (#756) from test-presigned into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/756
2024-03-04 12:56:02 +00:00
Alex Auvolat c8e416aaa5 [test-presigned] Use a HeaderMap type for QueryMap 2024-03-04 13:33:14 +01:00
asonix c94bf45cba Store original-cased query keys alongside query values 2024-03-04 13:03:27 +01:00
asonix 7c4f3473af Lowercase query parameter keys when parsing 2024-03-04 13:03:16 +01:00
Alex Auvolat b6a91e549b [test-presigned] Add API test for presigned requests 2024-03-04 13:02:07 +01:00
Alex 32d6b4def8 Merge pull request 'Add talk on 2024-02-09 at capitoul.org' (#755) from talk-capitoul into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/755
2024-03-04 11:08:23 +00:00
Alex c4de471de1 Merge pull request 'doc: fix typo in connect/backup.md' (#749) from Armael/garage:doc-typo into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/749
2024-03-03 13:51:38 +00:00
Armaël Guéneau 16e17375c5 doc: fix typo in connect/backup.md 2024-03-03 13:02:56 +01:00
Alex 95ab36aae7 Merge pull request 'Bump version to v0.9.2' (#747) from rel-0.9.2 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/747
2024-03-01 16:20:28 +00:00
Alex Auvolat 6a7623e90d [rel-0.9.2] Bump version to v0.9.2 2024-03-01 16:54:39 +01:00
Alex 70b9904e91 Merge pull request 'AWS signatures v4: don't actually check Content-Type is signed' (#745) from fix-signed-headers into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/745
2024-03-01 12:50:15 +00:00
Alex Auvolat a36248a169 [fix-signed-headers] aws signatures v4: don't actually check Content-Type is signed
This page of the AWS docs indicate that Content-Type should be part of
the CanonicalHeaders (and therefore SignedHeaders) strings in signature
calculation:

https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

However, testing with Minio Client revealed that it did not sign the
Content-Type header, and therefore we broke CI by expecting it to be
signed. With this commit, we don't mandate Content-Type to be signed
anymore, for better compatibility with the ecosystem. Testing against
the official behavior of S3 on AWS has not been done.
2024-03-01 13:12:18 +01:00
Alex b8c7a560ef Merge pull request 'Fix potential timing side-channels in authentication mechanisms' (#737) from fix-auth-ct-eq into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/737
2024-02-29 14:04:38 +00:00
Alex d3cf560e5c Merge pull request 'Docs: add default metrics_token in quick start + uniformize use of base64' (#739) from doc-default-token into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/739
2024-02-29 12:20:24 +00:00
Alex Auvolat 73b11eb17c [doc-default-token] add default metrics_token in quick start + uniformize use of base64 2024-02-29 13:17:36 +01:00
Alex Auvolat 6d33e721c4 [fix-auth-ct-eq] use consant time comparison for awsv4 signature verification 2024-02-29 13:07:18 +01:00
Alex Auvolat eaac4924ef [fix-auth-ct-eq] use argon2 hashing and verification for admin/metrics token checking 2024-02-29 13:07:15 +01:00
Alex 02005055ae Merge pull request 'Mention deduplication and compression in features page' (#736) from doc-dedup into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/736
2024-02-28 12:49:26 +00:00
Alex Auvolat a294dd9473 [doc-dedup] reorder features, move no-RAFT down 2024-02-28 13:48:45 +01:00
Alex Auvolat 947973982d [doc-dedup] fix #rpc_bind_outgoing anchor in config page 2024-02-28 13:45:30 +01:00
Alex Auvolat dc995059aa [doc-dedup] mention deduplication and compression in features page 2024-02-28 13:43:30 +01:00
Alex 10031a3a91 Merge pull request 'Split presigned signature verification + fix conditions' (#735) from fix-presigned into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/735
2024-02-28 11:38:00 +00:00
Alex Auvolat 90cab5b8f2 [fix-presigned] add comments and reorganize 2024-02-28 12:24:21 +01:00
Alex Auvolat e9f759d4cb [fix-presigned] presigned requests: allow x-amz-* query parameters to stand in for equivalent headers 2024-02-28 12:24:21 +01:00
Alex Auvolat a5e4bfeae9 [fix-presigned] write comments 2024-02-28 12:24:21 +01:00
Alex Auvolat 4c1d42cc5f [fix-presigned] add back anonymous request code path + refactoring 2024-02-28 12:24:21 +01:00
Alex Auvolat 2efa9c5a1a [fix-presigned] PostObject: verify X-Amz-Algorithm 2024-02-28 12:24:20 +01:00
Alex Auvolat a8cb8e8a8b [fix-presigned] split presigned/normal signature verification 2024-02-28 12:24:13 +01:00
Alex 911a83ea7d Merge pull request 'rewrite read_and_put_block as a series of steps with channels' (#734) from refactor-put into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/734
2024-02-26 17:52:45 +00:00
Alex Auvolat b76c0c102e [refactor-put] add ordering tag to blocks being sent to storage nodes 2024-02-26 18:35:11 +01:00
Alex Auvolat babccd2ad3 [refactor-put] send several blocks in parallel to storage nodes 2024-02-26 18:22:37 +01:00
Alex Auvolat 3fe94cc14f [refactor-put] rewrite read_and_put_block as a series of steps with channels 2024-02-26 17:55:37 +01:00
Alex Auvolat ee2b0c8dda [talk-capitoul] Add talk on 2024-02-09 at capitoul.org 2024-02-26 13:42:47 +01:00
Alex 17b55205aa Merge pull request 'doc: reverse-proxy.md: Added section on caddy-fs-s3' (#733) from jpds/garage:caddy-fileserver-browse-s3 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/733
2024-02-26 09:56:09 +00:00
Jonathan Davies 3813e6c71d doc: reverse-proxy.md: Added section on caddy-fs-s3. 2024-02-26 00:54:33 +00:00
Alex e399b60e25 Merge pull request 'GetObject: split out handle_get_full (small refactoring)' (#732) from split_getobject into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/732
2024-02-23 17:26:53 +00:00
Alex Auvolat d640102b76 [split_getobject] GetObject: split out handle_get_full 2024-02-23 18:14:50 +01:00
Alex 61758ce0f9 Merge pull request 'some refactoring on data read/write path' (#729) from refactor-block into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/729
2024-02-23 15:49:43 +00:00
Alex Auvolat 6ee691e65f [refactor-block] simplify some more 2024-02-23 12:50:10 +01:00
Alex Auvolat e9c42bca34 [refactor-block] add DataBlockStream type 2024-02-23 12:22:29 +01:00
Alex Auvolat cd1069c1d4 [refactor-block] refactor DataBlock and DataBlockPath 2024-02-23 12:15:52 +01:00
Alex Auvolat 07c7895948 [refactor-block] simplify rpc_get_block 2024-02-23 11:54:40 +01:00
Alex Auvolat 9b41f4ff20 [refactor-block] move read_stream_to_end to garage_net 2024-02-23 11:46:57 +01:00
Alex Auvolat 93552b9275 [refactor-block] Remove redundant BlockStream type 2024-02-23 11:33:38 +01:00
Alex 74d0c47f21 Merge pull request 'Add node-global lock for bucket/key operations (fix #723)' (#728) from lock-createbucket into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/728
2024-02-22 12:05:19 +00:00
Alex Auvolat cff702a951 [lock-createbucket] Add node-global lock for bucket/key operations (fix #723) 2024-02-22 12:28:21 +01:00
Alex 7e212e20e0 Merge pull request 'Minor typos & grammar fixes in docs' (#727) from hartraft/garage:docs-typo-fix into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/727
2024-02-22 09:26:08 +00:00
hartraft 00a5f14a7b Align admin endpoint port 2024-02-20 21:19:00 +01:00
hartraft 1a07c8dd54 Minor typos and grammar 2024-02-20 21:03:39 +01:00
hartraft 292f4ff9cb Typo
Fix small typo on the getting started guide
2024-02-20 18:35:56 +00:00
Alex 885405d944 Merge pull request 'system metrics improvements' (#726) from peer-metrics into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/726
2024-02-20 15:35:12 +00:00
Alex Auvolat bcd571ef57 [peer-metrics] add documentation for new cluster status metrics 2024-02-20 14:59:04 +01:00
Alex Auvolat b868493da9 [peer-metrics] add basic cluster node status metrics (fix #545) 2024-02-20 14:50:24 +01:00
Alex Auvolat 182a23cc12 [peer-metrics] refactor SystemMetrics to hold a reference to System 2024-02-20 14:20:58 +01:00
Alex Auvolat 3cdf69f079 [peer-metrics] Add metrics for cluster health, like GetClusterHealth admin API 2024-02-20 13:50:45 +01:00
Alex Auvolat 00d479358d [peer-metrics] refactor/simplify SystemMetrics 2024-02-20 13:50:45 +01:00
Alex 203bb10035 Merge pull request 'Filter nodes Garage tries to connect to' (#719) from reconnect-only-current into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/719
2024-02-20 10:37:11 +00:00
Alex Auvolat e91576677e [reconnect-only-current] filter nodes to reconnect to
do not try reconnecting to nodes received from consul/kubernetes
discovery if they are not currently in the layout
2024-02-20 11:07:10 +01:00
Alex 0b9859befa Merge pull request 'garage_net: retry connecting when new IP is learned' (#724) from networking-fixes into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/724
2024-02-19 17:37:01 +00:00
Alex Auvolat 95e3a39b4d [networking-fixes] small refactoring in garage_net peering 2024-02-19 18:12:21 +01:00
Alex Auvolat 66fe893023 [networking-fixes] garage_net: retry connecting when new IP is learned 2024-02-19 18:12:21 +01:00
Alex 6bb34899f2 Merge pull request 'fixes to RPC networking' (#721) from networking-fixes into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/721
2024-02-19 11:44:05 +00:00
Alex Auvolat eab54b3798 [networking-fixes] add doc for rpc_bind_outgoing 2024-02-19 11:45:44 +01:00
Alex Auvolat b96f84b894 [networking-fixes] add option to bind outgoing RPC sockets (fix #638)
Thanks to yuka for the original patch.
2024-02-19 11:45:44 +01:00
Alex Auvolat f0bbad2db9 [networking-fixes] use rpc_public_addr in netapp's HelloMessage 2024-02-19 11:45:44 +01:00
Alex b8217361c0 Merge pull request 'doc: fixes to index of configuration options' (#722) from doc-fixes into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/722
2024-02-19 10:45:14 +00:00
Alex Auvolat e73cb79e1e [doc-fixes] configuration reference: fix typo and set block size in M 2024-02-19 11:42:06 +01:00
Alex Auvolat e54effec45 [doc-fixes] fixes to index of configuration options 2024-02-19 11:36:22 +01:00
Alex 7be3f15e45 Merge pull request 'import Netapp code into Garage codebase' (#717) from import-netapp into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/717
2024-02-15 12:51:52 +00:00
Alex Auvolat 125c662860 [import-netapp] move and rename FullMeshPeeringSrategy to PeeringManager 2024-02-15 12:15:35 +01:00
Alex Auvolat 5766befb24 [import-netapp] fix tests 2024-02-15 12:15:33 +01:00
Alex Auvolat 5ea24254a9 [import-netapp] import Netapp code into Garage codebase 2024-02-15 12:15:07 +01:00
Alex a2ab275da8 Merge pull request 'Fix cargo warnings in Cargo.toml files' (#718) from fix-cargo-toml into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/718
2024-02-15 11:14:01 +00:00
Alex Auvolat 1b0f167d2f [fix-cargo-toml] fix cargo warnings in Cargo.toml files 2024-02-15 10:54:58 +01:00
Alex 823078b4cd Merge pull request 'small fixes to config/secrets handling' (#715) from fix-secrets-695 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/715
2024-02-13 10:04:49 +00:00
Alex ea09b483fe Merge pull request 'doc: mention warn and error as available log levels' (#716) from emilylange/garage:doc/mention-warn-error-log-levels into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/716
2024-02-13 08:13:23 +00:00
emilylange c86ac264cb doc: mention warn and error as available log levels
For some users, this might be their first time being interacting with
the `env_logger` crate.
As such, they might not be aware that less verbose log levels exist.
Some might not want to log every incoming request, for example.

This commit also adds syntax hints to the code-fence for bash for better
syntax highlighting of that section, and repeats itself multiple times,
that `info` is, in fact, the default.

No changes to the recommendation of log levels were made.
2024-02-12 18:00:51 +01:00
Alex Auvolat bf283c9924 [fix-secrets-695] config: replace String by PathBuf for *_file 2024-02-12 15:36:43 +01:00
Alex Auvolat 25e5738568 [fix-secrets-695] take into account rpc secret from file for cli commands (fix #695) 2024-02-12 10:42:17 +01:00
Alex 198188017c Merge pull request 'Implement header overriding in GetObject (fix #650)' (#713) from header-override-650 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/713
2024-02-09 15:40:18 +00:00
Alex Auvolat 02e98e2d10 [header-override-650] implement header overriding in GetObject (fix #650) 2024-02-09 15:58:46 +01:00
Alex fe175fa8e2 Merge pull request 'garage block info: find blocks by prefix (fix #682)' (#712) from block-info-short-682 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/712
2024-02-09 14:07:29 +00:00
Alex 3865080c35 Merge pull request 'Allow multi-character delimiters in List* (fix #692)' (#711) from multi-char-delimiter-692 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/711
2024-02-09 13:38:17 +00:00
Alex Auvolat 8da67b3aa2 [block-info-short-682] garage block info: find blocks by prefix (fix #682) 2024-02-09 14:35:53 +01:00
Alex Auvolat 10bc2ead60 [multi-char-delimiter-692] allow multi-character delimiters in List* (fix #692) 2024-02-09 14:15:29 +01:00
Alex 0c7ce001c9 Merge pull request 'Fix & simplify CI using Woodpecker' (#706) from nix-improvements into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/706
2024-02-09 12:11:23 +00:00
Alex Auvolat f7ae966ed3 [nix-improvements] special case for Docker's "386" architecture 2024-02-09 12:49:17 +01:00
Alex Auvolat 561fad0b44 [nix-improvements] get rid of Drone 2024-02-09 12:19:16 +01:00
Alex Auvolat 1be75fbf4e [nix-improvements] fix kaniko and manifest-tool 2024-02-09 11:46:46 +01:00
Alex Auvolat 555ed75548 [nix-improvements] ci: check static as separate step 2024-02-09 11:36:51 +01:00
Alex Auvolat 1c85e5e428 [nix-improvements] adapt woodpecker pipelines 2024-02-09 11:19:32 +01:00
Alex Auvolat d35d4599de [nix-improvements] use kaniko and manifest-tools from nixpkgs, simplify 2024-02-09 11:15:52 +01:00
Alex Auvolat 9900368380 [nix-improvements] modernize Nix infrastructure 2024-02-09 11:10:13 +01:00
Alex e4a43bfd59 Merge pull request 'Upgrade toml, kube, k8s-openapi + code fixes' (#709) from dep-upgrade-202402 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/709
2024-02-09 09:32:54 +00:00
Alex Auvolat 5c63193d1d [dep-upgrade-202402] fix shutdown issue introduced when upgrading hyper 2024-02-08 23:43:59 +01:00
Alex Auvolat bcbd15da84 [dep-upgrade-202402] cargo clippy fixes 2024-02-08 23:29:57 +01:00
Alex Auvolat ad5ce968d2 [dep-upgrade-202402] remove useless mut 2024-02-08 23:29:57 +01:00
Alex Auvolat c2e1e172d4 [dep-upgrade-202402] update toml, kube and k8s-openapi 2024-02-08 23:29:56 +01:00
Alex 8061bf5e1c Merge pull request 'Use only oxalica/rust-overlay toolchain and not nixpkgs' (#710) from oxalica-toolchain-only into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/710
2024-02-08 22:29:25 +00:00
Alex Auvolat 8724aabdf5 [oxalica-toolchain-only] remove obsolete comment on toolchains 2024-02-08 23:23:27 +01:00
Alex Auvolat 57024a2129 [oxalica-toolchain-only] remove custom toolchains from toolchains.nix 2024-02-08 23:21:00 +01:00
Alex Auvolat 9e0b1dcf1c [oxalica-toolchain-only] remove use of nixos rust toolchain 2024-02-08 19:10:26 +01:00
Alex 304a89c57b Merge pull request 'convert drone pipelines to woodpecker' (#708) from woodpecker into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/708
2024-02-08 17:46:00 +00:00
Alex Auvolat 25c2f37667 [woodpecker] remove upgrade test on i386 2024-02-08 18:42:26 +01:00
Alex Auvolat 4e62e86644 [woodpecker] disable docker image generation as auth is broken for now 2024-02-08 18:27:33 +01:00
Alex Auvolat 8b6a44a53d [woodpecker] convert drone pipelines to woodpecker 2024-02-08 18:24:52 +01:00
Alex 710680da15 Merge pull request 'update toolchain' (#705) from dep-upgrade-202402 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/705
2024-02-08 14:58:18 +00:00
Alex Auvolat 33e6db8b72 [dep-upgrade-202402] update rustc to 1.73 2024-02-08 12:33:09 +01:00
Alex 3a49f86073 Merge pull request 'Enable LTO for release builds using Nix' (#707) from lto-nix into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/707
2024-02-08 10:36:49 +00:00
Alex Auvolat 2b92e8d7c6 [lto-nix] enable LTO for release builds using Nix 2024-02-08 10:22:23 +01:00
Alex 59930977e0 Merge pull request 'Cargo.toml: Enable full LTO in release builds and thin in dev builds.' (#704) from jpds/garage:release-build-lto into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/704
2024-02-07 16:37:02 +00:00
Jonathan Davies 620664ee9c Cargo.toml: Enable full LTO in release builds and thin in dev builds. 2024-02-07 16:11:27 +00:00
Alex 5d941e0100 Merge pull request 'Dependency upgrades: http, hyper, aws-sdk, smaller deps' (#703) from dep-upgrade-202402 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/703
2024-02-07 14:59:40 +00:00
Alex Auvolat e011941964 [dep-upgrade-202402] refactor use of BodyStream 2024-02-07 15:32:51 +01:00
Alex Auvolat 53746b59e5 [dep-upgrade-202402] slightly more explicit error management 2024-02-07 14:53:13 +01:00
Alex Auvolat a31d1bd496 [dep-upgrade-202402] fix obsolete DateTime::from_utc calls 2024-02-07 14:48:27 +01:00
Alex Auvolat e524e7a30d [dep-upgrade-202402] rename BytesBody into ErrorBody for clarity 2024-02-07 14:45:52 +01:00
Alex Auvolat fe48d60d2b [dep-upgrade-202402] refactor http listener code 2024-02-07 14:34:40 +01:00
Alex Auvolat 22332e6c35 [dep-upgrade-202402] simplify/refactor GetObject 2024-02-05 20:26:33 +01:00
Alex Auvolat 81ccd4586e [dep-upgrade-202402] upgrade to http/hyper 1.x for tests 2024-02-05 19:57:35 +01:00
Alex Auvolat a22bd31920 [dep-upgrade-202402] migration to http/hyper 1.0 for k2v api 2024-02-05 19:27:12 +01:00
Alex Auvolat 0bb5b77530 [dep-upgrade-202402] wip: port to http/hyper crates v1 2024-02-05 18:49:54 +01:00
Alex Auvolat 6e69a1fffc [dep-upgrade-202402] prepare migration to http/hyper 1.0 2024-02-05 14:44:12 +01:00
Alex Auvolat 6e4229e29c [dep-upgrade-202402] update aws-sdk dependencies 2024-02-05 14:02:45 +01:00
Alex Auvolat c0a7552015 [dep-upgrade-202402] upgrade easy dependencies 2024-02-05 13:58:23 +01:00
Alex Auvolat fe1af5d98b [dep-upgrade-202402] refactor dependencies: move all as workspace deps 2024-02-05 13:02:02 +01:00
Alex Auvolat f65da26ae2 [dep-upgrade-202402] update dependency minor versions using cargo update 2024-02-05 12:26:31 +01:00
Alex feeb076b7f Merge pull request 'Add FOSDEM'24 talk' (#702) from talk-fosdem-24 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/702
2024-02-05 11:17:15 +00:00
Alex Auvolat fe37202f8f [talk-fosdem-24] remove abstract.md 2024-02-05 12:16:09 +01:00
Alex Auvolat 76e09c0472 [talk-fosdem-24] small change in talk 2024-02-01 11:43:21 +01:00
Alex Auvolat 1d30cf36c8 [talk-fosdem-24] improve fosdem 24 talk 2024-01-30 14:27:39 +01:00
Alex d45189e7b8 Merge pull request 'doc: fix some typos' (#696) from Armael/garage:typos into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/696
2024-01-28 14:15:47 +00:00
Armaël Guéneau 91a51dd3e8 doc: fix some typos 2024-01-27 14:51:15 +01:00
Alex 08a871390e Merge pull request 'convert_db: allow LMDB map size override' (#691) from zdenek.crha/garage:convert_db_lmdb_map_size into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/691
2024-01-24 08:19:45 +00:00
Alex Auvolat c7dad980b7 [talk-fosdem-24] remove geodistrib paper shot 2024-01-23 17:25:45 +01:00
Alex Auvolat c2541f280c [talk-fosdem-24] WIP, write talk, modify lots of assets 2024-01-23 16:50:30 +01:00
Zdenek Crha 0eef8a69f0 make all garage_db::Engine variants un-conditional
Having all Engine enum variants conditional causes compilation errors
when *none* of the DB engine features is enabled. This is not an issue
for full garage build, but affects crates that use garage_db as
dependency.

Change all variants to be present at all times. It solves compilation
errors and also allows us to better differentiate between invalid DB
engine name and engine with support not compiled in current binary.
2024-01-22 21:12:02 +01:00
Alex Auvolat 4de7ac6023 FOSDEM'24 talk WIP 2024-01-22 18:52:14 +01:00
Zdenek Crha 74e72fc996 convert_db: cleanup naming and comments for open overrides 2024-01-22 17:52:39 +01:00
Alex 7a3b863150 Merge pull request 'doc: add presentation at seed webinar 2024-01-12' (#693) from prez-seed-webinar-202401 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/693
2024-01-22 13:49:08 +00:00
Alex Auvolat d2c40b12e8 doc/talks: refactor assets 2024-01-22 14:43:46 +01:00
Alex Auvolat cf0abbfe42 rm abstract 2024-01-22 14:33:48 +01:00
Zdenek Crha 4b54e053df convert_db: prevent conversion between same input/output engine
Use optional DB open overrides for both input and output database.

Duplicating the same override flag for input/output would result in too
many, too long flags. It would be too costly for very rare edge-case
where converting between same DB engine, just with different flags.

Because overrides flags for different engines are disjoint and we are
preventing conversion between same input/ouput DB engine, we can have
only one set.

The override flag will be passed either to input or output, based on
engine type it belongs to. It will never be passed to both of them and
cause unwelcome surprise to user.
2024-01-18 17:57:56 +01:00
Zdenek Crha 8527dd87cc convert_db: allow LMDB map size override 2024-01-17 21:20:34 +01:00
Alex 0263828560 Merge pull request 'Garage v0.9.1' (#689) from rel-v0.9.1 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/689
2024-01-17 12:00:23 +00:00
Alex Auvolat ee57dd922b Bump version to 0.9.1 2024-01-16 16:28:17 +01:00
Alex 9cfeea389a Merge pull request 'CLI help, comments & messages: make clear that full-length node ID = public key' (#688) from rename-public-key into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/688
2024-01-16 13:33:43 +00:00
Alex Auvolat 82a29bf6e5 help, comments: make clear that full-length node ID = public key
Generally, avoid using the "public key" terminology
2024-01-16 14:04:11 +01:00
Alex 707d85f602 Merge pull request 'sync garage v0.9 with garage v0.8' (#657) from sync-08-09 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/657
2024-01-16 11:33:27 +00:00
Alex Auvolat 4c5be79b80 Merge tag 'v0.8.5' into sync-08-09
Garage v0.8.5

This minor release includes the following improvements and fixes:

New features:

- Configuration: make LMDB's `map_size` configurable and make `block_size` and `sled_cache_capacity` expressable as strings (such as `10M`) (#628, #630)

- Add support for binding to Unix sockets for the S3, K2V, Admin and Web API servers (#640)

- Move the `convert_db` command into the main Garage binary (#645)

- Add support for specifying RPC secret and admin tokens as environment variables (#643)

- Add `allow_world_readable_secrets` option to config file (#663, #685)

Bug fixes:

- Use `statvfs` instead of mount list to determine free space in metadata/data directories (#611, #631)

- Add missing casts to fix 32-bit build (#632)

- Fix error when none of the HTTP servers (S3/K2V/Admin/Web) is started and fix shutdown hang (#613, #633)

- Add missing CORS headers to PostObject response (#609, #656)

- Monitoring: finer histogram boundaries in Prometheus exported metrics (#531, #686)

Other:

- Documentation improvements (#641)
2024-01-16 12:12:27 +01:00
Alex 083e982f5f Merge pull request 'Garage v0.8.5' (#687) from rel-0.8.5 into main-0.8.x
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/687
2024-01-16 10:30:54 +00:00
Alex Auvolat 50643e61bf Bump version to 0.8.5 2024-01-16 10:47:33 +01:00
Alex a6421ee5a5 Merge pull request 'monitoring: finer histogram boundaries in prometheus metrics (fix #531)' (#686) from fix-531 into main-0.8.x
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/686
2024-01-15 16:44:58 +00:00
Alex 993ce74976 Merge pull request '0.8.x: config: refactor secret sourcing' (#685) from secret-sourcing into main-0.8.x
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/685
2024-01-15 16:41:50 +00:00
Alex Auvolat f512609123 monitoring: finer histogram boundaries in prometheus metrics (fix #531) 2024-01-15 17:33:35 +01:00
Alex Auvolat 97bae7213a config: additional tests for secret sourcing 2024-01-15 17:30:30 +01:00
Alex Auvolat 7228695ee2 config: refactor secret sourcing 2024-01-15 17:18:46 +01:00
Alex ee7fe27d3d Merge pull request 'Add allow_world_readable_secrets option to config file' (#663) from PicNoir/garage:nin/world-readable-conf-file into main-0.8.x
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/663
2024-01-15 15:20:16 +00:00
Alex d91a1de731 Merge pull request 'fix typo in peertube doc' (#617) from Lapineige/garage:main into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/617
2024-01-11 11:19:42 +00:00
Alex 723e56b37f Merge pull request 'Jepsen testing (NLnet task 3 subtask 1)' (#544) from jepsen into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/544
2024-01-11 10:52:12 +00:00
Alex Auvolat 60f0bd03b6 doc: add talk for SEED webinar 2024-01-11 11:40:44 +01:00
Alex Auvolat fa9247f11b jepsen: updated results, confirming that task3 works 2023-12-14 16:23:48 +01:00
Alex a8b0e01f88 Merge pull request 'OpenAPI specification of admin APIv1' (#672) from api-v1 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/672
2023-11-29 15:42:46 +00:00
Quentin Dufour 8088690650 fix the doc 2023-11-28 16:18:28 +01:00
Alex ffa659433d Merge pull request 'Doc: fix db_engines section and improve config reference' (#674) from fix-doc-db-engine into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/674
2023-11-28 12:03:46 +00:00
Alex Auvolat cfa5550cb2 doc: move replication_mode to top of configuration page reference 2023-11-28 11:58:27 +01:00
Alex Auvolat 939d1f2e17 doc: improve navigation in configuration reference 2023-11-28 11:53:26 +01:00
Alex Auvolat 1f6efe57be doc: update the db_engine section 2023-11-28 11:33:31 +01:00
Quentin Dufour 3908619eac add ClusterHealthReport endpoint to the API 2023-11-28 09:34:01 +01:00
Quentin Dufour 68d23cccdf disable int64 finally for now 2023-11-23 10:20:36 +01:00
Quentin Dufour 9f1043586c set layout version as required 2023-11-23 10:16:16 +01:00
Quentin Dufour 1caa6e29e5 capacity is int64 2023-11-23 10:02:41 +01:00
Quentin Dufour 814b3e11d4 fix query parameters for keys 2023-11-23 08:50:10 +01:00
Quentin Dufour 2d37e7fa39 convert showsecretkey from bool to enum 2023-11-22 21:05:36 +01:00
Quentin Dufour 4f473f43c9 Change how query parameters are handled 2023-11-22 20:39:38 +01:00
Quentin Dufour 3684c29ad0 handle key changes 2023-11-22 18:14:38 +01:00
Quentin Dufour 0d415f42ac Port GetKeyInfo by adding showSecretKey query param 2023-11-22 18:05:11 +01:00
Quentin Dufour 20b3afbde4 Port layout endpoints 2023-11-22 17:49:51 +01:00
Quentin Dufour e3cd6ed530 port GetLayout and AddLayout 2023-11-22 15:24:30 +01:00
Quentin Dufour 9b24d7c402 Upgrade GetNodes 2023-11-22 14:25:04 +01:00
Alex 36bd21a148 Merge pull request 'Allow 0 as a part number marker' (#670) from asonix/garage:main into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/670
2023-11-22 10:33:31 +00:00
Quentin Dufour d1d1940252 Health info message now advertises API v1 2023-11-22 09:28:50 +01:00
Quentin Dufour c63b446989 skeleton for api v1 2023-11-22 08:58:09 +01:00
asonix 92fd899fb6 Allow 0 as a part number marker 2023-11-21 17:39:51 -06:00
Alex Auvolat 92dd2bbe15 jepsen: nlnet task3a seems to fix things 2023-11-16 18:09:13 +01:00
Alex Auvolat 18e5811159 jepsen: add patch and use more complete names 2023-11-16 12:57:21 +01:00
Félix Baylac Jacqué f83fa02193 Add allow_world_readable_secrets option to config file
Sometimes, the secret files permissions checks gets in the way. It's
by no mean complete, it doesn't take the Posix ACLs into account among
other things. Correctly checking the ACLs would be too involving (see
https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/658#issuecomment-7102)
and would likely still fail in some weird chmod settings.

We're adding a new configuration file key allowing the user to disable
this permission check altogether.

The (already existing) env variable counterpart always take precedence
to this config file option. That's useful in cases where the
configuration file is static and cannot be easily altered.

Fixes https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/658

Co-authored-by: Florian Klink <flokli@flokli.de>
2023-10-26 18:25:13 +02:00
Alex f4d3905d15 Merge pull request 'nix: add clang to flake.nix and shell.nix' (#664) from add-clang into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/664
2023-10-26 09:25:53 +00:00
Alex a0fa50dfcd Merge pull request 's3 api: refactoring and bug fix in ListObjects' (#655) from fix-list-objects into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/655
2023-10-26 09:22:47 +00:00
Alex Auvolat d50fa2a562 nix: add clang to flake.nix and shell.nix 2023-10-26 11:19:22 +02:00
Alex 4b3dee2ca3 Merge pull request 's3 api: add missing CORS headers to PostObject responses (fix #609)' (#656) from fix-cors-post-object into main-0.8.x
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/656
2023-10-26 09:17:14 +00:00
Alex Auvolat 5b1f50be65 jepsen: testing 2023-10-25 14:43:24 +02:00
Alex Auvolat 9df7fa0bcd jepsen: use 7 nodes 2023-10-25 14:04:39 +02:00
Alex Auvolat fd85010a40 jepsen: failures with set2 test in --scenario r 2023-10-25 12:13:27 +02:00
Alex Auvolat cfbfa09d24 jepsen: fix set2 test omg finally this is so stupid 2023-10-25 11:50:16 +02:00
Alex Auvolat db921cc05f jepsen: reconfigure nemesis + add db nemesis 2023-10-25 11:41:34 +02:00
Alex Auvolat 4fa2646a75 jepsen: got a failure with set1 2023-10-24 17:45:22 +02:00
Alex Auvolat d7ab2c639e jepsen: fix nemesis to actually generate many operations 2023-10-24 16:39:50 +02:00
Alex Auvolat d13bde5e26 jepsen: set1 and set2 don't fail anymore ?? 2023-10-24 15:44:05 +02:00
Alex 75d5d08ee1 Merge pull request 'Ensure increasing version timestamps when writing new object versions' (#543) from increasing-timestamps into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/543
2023-10-24 10:07:16 +00:00
Alex Auvolat d2c365767b jepsen: more testing 2023-10-24 11:39:45 +02:00
Alex Auvolat fb6c9a1243 jepsen: update readme 2023-10-20 15:55:09 +02:00
Alex Auvolat 9030c1eef8 jepsen: code path for nemesis final generator 2023-10-20 15:53:46 +02:00
Alex Auvolat 654775308e jepsen: add cluster reconfiguration nemesis 2023-10-20 15:48:37 +02:00
Alex Auvolat f5b0972781 jepsen: register crdt read-after-write is fixed with deleteobject patch 2023-10-20 15:00:10 +02:00
Alex Auvolat c82d91c6bc DeleteObject: always insert a deletion marker with a bigger timestamp than everything before 2023-10-20 13:56:35 +02:00
Alex Auvolat 8686cfd0b1 s3 api: also ensure increasing timestamps for create_multipart_upload 2023-10-20 13:37:37 +02:00
Alex Auvolat d148b83d4f jepsen: reg2 failure seems to happen only with deleteobject 2023-10-20 13:36:48 +02:00
Alex Auvolat c6cde1f143 remove now-unused key parameter in check_quotas 2023-10-20 13:20:47 +02:00
Alex Auvolat 4b93ce179a jepsen: errors in reg2 workload under investigation 2023-10-20 12:56:55 +02:00
Alex Auvolat 4ba18ce9cc jepsen: wip checker for register-like behavior 2023-10-20 12:13:11 +02:00
Alex Auvolat ac04934dae s3 api: add missing CORS headers to PostObject responses (fix #609) 2023-10-20 10:37:48 +02:00
Alex Auvolat ef662822c9 jepsen: fix the list-objects call (?) 2023-10-19 23:40:55 +02:00
Alex Auvolat da8b170748 jepsen: investigating listobjects error 2023-10-19 16:45:24 +02:00
Alex Auvolat 58b0ee1b1a list objects: prettyness and add asserts 2023-10-19 15:26:17 +02:00
Alex Auvolat 158dc17a06 listobjects: fix panic if continuation token is an empty string 2023-10-19 15:08:47 +02:00
Alex Auvolat 74e50edddd jepsen: refactoring 2023-10-19 14:34:19 +02:00
Alex 0215b11402 Merge pull request 'Add support for specifying rpc_secret_file, metrics_token_file and admin_token_file using environment variables' (#643) from networkException/garage:token-file-env into main-0.8.x
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/643
2023-10-19 09:33:12 +00:00
networkException 8599051c49 garage: support specifying token / secret as environment variables
this patch adds support for specifying the `rpc_secret_file`,
`metrics_token_file` and `admin_token_file` as environment variables.
2023-10-19 03:39:02 +02:00
networkException 4a19ee94bb garage: fix admin-token description 2023-10-19 03:31:50 +02:00
networkException c99cb58d71 util: move reading secret file into seperate helper
this patch moves the logic to read a secret file (and check for correct
permissions) from `secret_from_file` into a new `read_secret_file`
helper.
2023-10-19 03:29:48 +02:00
networkException 5feb6a1f64 docs: add documentation for specifying token / secret file as environment variables 2023-10-19 03:28:44 +02:00
Alex Auvolat b3bf16ee27 make jepsen test more robust: handle errors and timeouts, fixed access key 2023-10-18 17:51:34 +02:00
Alex Auvolat d146cdd5b6 cargo fmt 2023-10-18 16:38:26 +02:00
Alex Auvolat 3d6ed63824 check_quotas: avoid re-fetching object from object table 2023-10-18 16:36:48 +02:00
Alex Auvolat 45b0453d0f Ensure increasing version timestamps in PutObject 2023-10-18 16:31:50 +02:00
Alex Auvolat ddd3de7fce refactor jepsen code 2023-10-18 16:30:45 +02:00
Alex Auvolat 84d43501ce refactor jepsen setup logic 2023-10-18 15:34:12 +02:00
Alex Auvolat 012ade5d4b jepsen: update jepsen and fix garage key info 2023-10-18 14:06:32 +02:00
Alex Auvolat ef5ca86dfc jepsen: update to garage 0.9.0 2023-10-18 14:01:18 +02:00
Alex Auvolat 9ec4cca334 reformatting 2023-10-18 12:03:12 +02:00
Alex Auvolat 18ee8efb5f Check read-after-write property for sets 2023-10-18 12:03:12 +02:00
Alex Auvolat 55eb4e87c4 set tests with independant tests together 2023-10-18 12:03:11 +02:00
Alex Auvolat 0bb1577ae1 two set workloads with different checkers 2023-10-18 12:03:11 +02:00
Alex Auvolat 6eb26be548 Add garage set test (this one works :p) 2023-10-18 12:03:11 +02:00
Alex Auvolat eb86eaa6d2 refactor jepsen test 2023-10-18 12:03:11 +02:00
Alex Auvolat 80d7b7d858 remove useless files 2023-10-18 12:03:11 +02:00
Alex Auvolat 93a7132b4c the fix for increasing timestamps does not make things linearizable 2023-10-18 12:03:11 +02:00
Alex Auvolat dc5245ce65 even without nemesis, s3 get/put/delete is not linearizable (is this normal?) 2023-10-18 12:03:11 +02:00
Alex Auvolat 70c1d3db46 better match exceptions 2023-10-18 12:03:11 +02:00
Alex Auvolat bc11701999 jepsen: s3 gets and puts 2023-10-18 12:03:11 +02:00
Alex Auvolat ca4cc7e44f jepsen connects to vagrant vms 2023-10-18 12:03:11 +02:00
Alex Auvolat 17ebb65273 jepsen ssh into containers seem to work ? 2023-10-18 12:03:11 +02:00
Alex Auvolat 7011b71fbd jepsen: wip 2023-10-18 12:03:11 +02:00
Alex a5e8ffeb63 Merge pull request 'use mold linker when invoking cargo manually (not in nix build scripts)' (#646) from mold-linker into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/646
2023-10-18 10:02:34 +00:00
Alex b53510c5b7 Merge pull request 'fix compilation on macos' (#654) from trinity-1686a/garage:fix-macos-compilation into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/654
2023-10-16 09:33:33 +00:00
trinity-1686a c7f5dcd953 fix compilation on macos
fsblkcnt_t is ony 32b there, so we have to do an additional cast
2023-10-15 17:57:27 +02:00
Alex d8263fdf92 Merge pull request 'documentation updates for v0.9.0' (#647) from doc-updates into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/647
2023-10-11 12:57:37 +00:00
Alex Auvolat d24aaba697 doc: update quick start and real world for v0.9.0 2023-10-11 14:49:54 +02:00
Alex Auvolat b571dcd811 doc: updates to the "migrating to v0.9" page 2023-10-10 15:43:26 +02:00
Alex e6df7089a1 Merge pull request 'Garage v0.9' (#473) from next into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/473
2023-10-10 13:28:28 +00:00
Alex Auvolat 952c9570c4 bump version to v0.9.0 2023-10-10 14:08:11 +02:00
Alex Auvolat 3d7892477d convert_db: fix build 2023-10-10 14:06:25 +02:00
Alex Auvolat d4932c31ea Merge branch 'main' into next 2023-10-10 13:57:21 +02:00
Alex Auvolat d3fffd30dc use mold linker when invoking cargo manually (not in nix build scripts) 2023-10-10 13:56:48 +02:00
Alex e75fe2157d Merge pull request 'Move convert_db command into main garage binary' (#645) from convert-db-main-binary into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/645
2023-10-10 11:42:14 +00:00
Alex Auvolat 2d5d7a7031 Move convert_db command into main garage binary 2023-10-10 12:13:15 +02:00
Alex Auvolat 0c431b0c03 admin api: increased compatibility for v0/ endpoints 2023-10-05 16:56:13 +02:00
Alex Auvolat 1c13135f25 admin api: remove broken GET /v0/key router rule 2023-10-05 16:27:29 +02:00
Alex Auvolat 2448eb7713 upgrade doc: fixes and precisions 2023-10-05 15:29:55 +02:00
Alex Auvolat 6790e24f5a Add migration to v0.9 guide 2023-10-05 15:20:48 +02:00
Alex Auvolat 9ccc1d6f4a move upgrade test to release build 2023-10-05 10:42:10 +02:00
Alex Auvolat 920dec393a cli: more precise doc comment 2023-10-04 10:44:42 +02:00
Alex Auvolat 2e656b541b Merge branch 'main' into next 2023-10-03 18:40:37 +02:00
Alex 1243db87f2 Merge pull request 'Add support for binding to unix domain sockets' (#640) from networkException/garage:unix-sockets into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/640
2023-10-03 16:23:02 +00:00
networkException 6f8a87814b doc: add documentation for specifying unix socket paths 2023-10-03 17:56:34 +02:00
networkException 7907a09acc api: allow custom unix bind mode and use 0o220 for admin server 2023-10-03 17:31:40 +02:00
Alex 16aa418e47 Merge pull request 'doc: update endpoint_url documentation' (#641) from flokli/garage:aws-endpoint-url into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/641
2023-10-02 14:30:53 +00:00
Florian Klink cb359b4434 doc: update endpoint_url documentation
Since `awscli` `>=1.29.0` or `>=2.13.0` it is now possible to use the
`AWS_ENDPOINT_URL` environment variable, or the `endpoint_url` config
key to override the endpoint URL. This means, the aws bash function to
wrap with --endpoint-url is not necessary anymore. Update invocations to
reflect that.

https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html
https://github.com/aws/aws-cli/issues/4454#issuecomment-1626116607
2023-10-02 17:16:11 +03:00
networkException 8ec6a53b35 everywhere: support unix sockets when binding in various places
this patch implements binding to paths as a unix socket for generic
server and web server.
2023-09-29 18:57:44 +02:00
networkException 7353038a64 config: allow using paths for unix domain sockets in various places
this patch updates the config format to also allow paths in bind
addresses for unix domain sockets.

this has been added to all apis except rpc.
2023-09-29 18:38:30 +02:00
networkException 10195f1567 util: add helper sum type for unix and tcp socket addresses
this patch introduces a new sum type that can represent either a
tcp socket address or a unix domain socket path.
2023-09-29 18:37:36 +02:00
networkException 6086a3fa07 cargo: add hyperlocal as a dependency 2023-09-29 18:37:12 +02:00
Alex Auvolat 9ac1d5be0e add upgrade test for garage 0.8 -> 0.9 2023-09-27 14:57:37 +02:00
Alex Auvolat 897cbf2c27 actually update rmp-serde to 1.1.2 for both garage and netapp dependency (fix #629) 2023-09-27 13:13:00 +02:00
Alex Auvolat ad82035b98 Merge branch 'main' into next 2023-09-27 13:11:52 +02:00
Alex aa7eadc799 Merge pull request 'New layout: fixes and UX improvements' (#634) from new-layout-ux into next
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/634
2023-09-27 09:04:32 +00:00
Alex Auvolat 0e5925fff6 layout doc: reformulate 2023-09-22 16:14:47 +02:00
Alex Auvolat 8d07888fa2 layout doc: write explanations for bizarre scenarios 2023-09-22 16:07:46 +02:00
Alex Auvolat 405aa42b7d layout doc: update old text 2023-09-22 10:06:31 +02:00
Alex Auvolat b4a0e636d8 new layout doc: add examples of unexpected layout, to explain 2023-09-22 09:49:07 +02:00
Alex 1d986bd889 Merge pull request 'Refactor db transactions and add on_commit for table.queue_insert' (#637) from k2v-indices-lmdb into next
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/637
2023-09-21 14:03:35 +00:00
Alex Auvolat 0635250b2b garage_table/queue_insert: delay worker notification to after transaction commit (fix #583) 2023-09-21 15:37:28 +02:00
Alex Auvolat f97168f805 garage_db: refactor transactions and add on_commit mechanism 2023-09-21 15:35:31 +02:00
Alex Auvolat 3ecc17f8c5 new layout: use deterministic randomness for reproducible results 2023-09-21 11:21:35 +02:00
Alex 3a0e074047 Merge pull request 'prez-ocp' (#636) from prez-ocp into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/636
2023-09-21 08:15:10 +00:00
Alex Auvolat 95ae09917b add ocp2023 presentation 2023-09-19 14:02:07 +02:00
Alex Auvolat a7ababb5db doc: update sticker 2023-09-18 16:40:06 +02:00
Alex Auvolat 013b026d56 update cargo.nix 2023-09-18 12:18:56 +02:00
Alex Auvolat 0088599f52 new layout: fix clippy lints 2023-09-18 12:17:07 +02:00
Alex Auvolat 749b4865d0 new layout: improve display and fix comments 2023-09-18 12:07:45 +02:00
Alex Auvolat 015ccb39aa new layout: make zone_redundancy optionnal (if not set, is maximum) 2023-09-18 11:59:08 +02:00
Alex Auvolat 2e229d4430 new layout: improve output display 2023-09-12 17:24:51 +02:00
Alex be1a16b42b Merge pull request 'Fix multiple shutdown issues' (#633) from fix-shutdown into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/633
2023-09-12 12:54:50 +00:00
Alex Auvolat 91e764a2bf fix hang on shutdown 2023-09-12 14:35:48 +02:00
Alex Auvolat aa79810596 Fix error when none of S3/K2V/WEB/ADMIN server is started (fix #613) 2023-09-12 14:35:19 +02:00
Alex Auvolat fd7d8fec59 Merge branch 'main' into next 2023-09-11 23:09:20 +02:00
Alex 143a349f55 Merge pull request 'fix 32-bit build' (#632) from fix-32bit into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/632
2023-09-11 21:08:26 +00:00
Alex Auvolat 9cfe55ab60 fix 32-bit build 2023-09-11 20:01:29 +02:00
Alex Auvolat 51abbb02d8 Merge branch 'main' into next 2023-09-11 20:00:02 +02:00
Alex 2548a247f2 Merge pull request 'use statvfs instead of mount list to determine free data/meta space (fix #611)' (#631) from fix-free-space into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/631
2023-09-11 17:29:23 +00:00
Alex Auvolat d5bb50d738 use statvfs instead of mount list to determine free data/meta space (fix #611) 2023-09-11 19:08:24 +02:00
Alex fc635f7072 Merge pull request 'make lmdb's map_size configurable (fix #628)' (#630) from configurable-map-size into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/630
2023-09-11 16:48:14 +00:00
Alex Auvolat f8b3883611 config: make block_size and sled_cache_capacity expressable as strings 2023-09-11 18:34:59 +02:00
Alex Auvolat 51b9731a08 make lmdb's map_size configurable (fix #628) 2023-09-11 18:03:44 +02:00
Alex Auvolat ad6b1cc0be Merge branch 'main' into next 2023-09-11 13:14:18 +02:00
Alex 7228fbfd4f Merge pull request 'multi-hdd support (fix #218)' (#625) from multihdd into next
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/625
2023-09-11 10:52:01 +00:00
Alex Auvolat ba7ac52c19 block repair: simpler/more robust iterator progress calculation 2023-09-11 12:31:34 +02:00
Alex Auvolat 9526328d38 scrub: clear saved checkpoint when canceling scrub 2023-09-11 12:10:48 +02:00
Alex Auvolat 7f9ba49c71 block manager: remove data_dir field 2023-09-11 11:57:36 +02:00
Alex Auvolat de5d792181 block manager: fix indentation (why not detected by cargo fmt?) 2023-09-11 11:52:57 +02:00
Alex Auvolat be91ef6294 block manager: fix bug where rebalance didn't delete old copies 2023-09-07 16:04:03 +02:00
Alex Auvolat 2657b5c1b9 block manager: fix bugs 2023-09-07 15:30:56 +02:00
Alex Auvolat eb972a8422 doc: update multi-hdd section 2023-09-07 14:48:36 +02:00
Alex Auvolat 2f112ac682 correct free data space accounting for multiple data dirs on same fs 2023-09-07 14:42:20 +02:00
Alex Auvolat 6a067e30ee doc: documentation of rebalance repair 2023-09-07 13:49:12 +02:00
Alex Auvolat 6b008b5bd3 block manager: add rebalance operation to rebalance multi-hdd setups 2023-09-07 13:44:11 +02:00
Alex Auvolat 6595efd82f Document multi-hdd support 2023-09-07 13:23:02 +02:00
Alex Auvolat bca347a1e8 doc: update page on upgradin clusters 2023-09-07 12:52:44 +02:00
Alex Auvolat 99ed18350f block manager: refactor and fix monitoring/statistics 2023-09-07 12:41:36 +02:00
Alex Auvolat f38a31b330 block manager: avoid incorrect data_dir configs and avoid losing files 2023-09-06 17:49:30 +02:00
Alex Auvolat e30865984a block manager: scrub checkpointing 2023-09-06 16:35:28 +02:00
Alex Auvolat 55c514999e block manager: fixes in layout 2023-09-06 16:35:28 +02:00
Alex Auvolat a44f486931 block manager: refactoring & increase max worker count to 8 2023-09-06 16:35:28 +02:00
Alex Auvolat 3a74844df0 block manager: fix dir_not_empty 2023-09-06 16:35:28 +02:00
Alex Auvolat 93114a9747 block manager: refactoring 2023-09-06 16:35:28 +02:00
Alex Auvolat fd00a47ddc table queue: increase batch size 2023-09-06 16:35:28 +02:00
Alex Auvolat 1b8c265c14 block manager: get rid of check_block_status 2023-09-06 16:35:28 +02:00
Alex Auvolat 3199cab4c8 update cargo.nix 2023-09-06 16:35:28 +02:00
Alex Auvolat a09f86729c block manager: move blocks in write_block if necessary 2023-09-06 16:35:28 +02:00
Alex Auvolat 887b3233f4 block manager: use data paths from layout 2023-09-06 16:35:28 +02:00
Alex Auvolat 6c420c0880 block manager: multi-directory layout computation 2023-09-06 16:35:28 +02:00
Alex Auvolat 71c0188055 block manager: skeleton for multi-hdd support 2023-09-06 16:35:28 +02:00
Alex Auvolat 4b4f2000f4 lifecycle: fix SkipBucket bug 2023-09-06 16:34:07 +02:00
Alex 5f86b48f97 Merge pull request 'Revert netapp to 0.5.2 to avoid rmp-serde upgrade that breaks things' (#627) from hold-netapp-0.5.2 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/627
2023-09-05 22:08:40 +00:00
Alex Auvolat 51eac97260 update version to 0.8.4 2023-09-05 23:28:12 +02:00
Alex Auvolat e78566591b Revert netapp update, hold to version 0.5.2 that uses rmp-serde 0.15 2023-09-05 23:23:23 +02:00
Alex 3f461d8891 Merge pull request 'object lifecycles (fix #309)' (#620) from bucket-lifecycle into next
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/620
2023-09-04 09:45:10 +00:00
Alex Auvolat 8e0c020bb9 lifecycle worker: correct small clippy lints 2023-09-04 11:33:44 +02:00
Alex Auvolat 1cdc321e28 lifecycle worker: don't get stuck on non-existent bucket 2023-08-31 11:36:30 +02:00
Alex Auvolat f579d6d9b4 lifecycle worker: fix potential inifinite loop 2023-08-31 11:29:54 +02:00
Alex Auvolat a00a52633f lifecycle worker: add log message when starting 2023-08-31 11:25:14 +02:00
Alex Auvolat adbf5925de lifecycle worker: use queue_insert and process objects in batches 2023-08-31 11:19:26 +02:00
Alex Auvolat 1cfcc61de8 lifecycle worker: mitigate potential bugs + refactoring 2023-08-31 00:28:37 +02:00
Alex Auvolat be03a4610f s3api: remove redundant serde rename attribute 2023-08-31 00:00:26 +02:00
Alex Auvolat b2f679675e lifecycle worker: take into account disabled rules 2023-08-30 23:52:09 +02:00
Alex Auvolat 5fad4c4658 update cargo.nix 2023-08-30 23:47:42 +02:00
Alex Auvolat 01c327a07a lifecycle worker: avoid building chrono's serde feature 2023-08-30 23:46:15 +02:00
Alex Auvolat f0a395e2e5 s3 bucket apis: remove redundant call 2023-08-30 23:39:28 +02:00
Alex Auvolat d94f1c9178 reference manual: remove obsolete caveat about multipart uploads 2023-08-30 23:27:02 +02:00
Alex Auvolat 5c923d48d7 reference manual: document support for lifecycle configuration 2023-08-30 23:24:28 +02:00
Alex Auvolat a1d57283c0 bucket_table: bucketparams::new doesn't need to be pub 2023-08-30 20:07:14 +02:00
Alex Auvolat d2e94e36d6 lifecycle config: add missing line in merge() and remove tracing 2023-08-30 20:05:53 +02:00
Alex Auvolat 75ccc5a95c lifecycle config: store date as given, try to debug 2023-08-30 20:02:07 +02:00
Alex Auvolat 7200954318 lifecycle worker: add logging 2023-08-30 14:54:52 +02:00
Alex Auvolat 0f1849e1ac lifecycle worker: launch with the rest of Garage 2023-08-30 14:51:08 +02:00
Alex Auvolat da8b224e24 lifecycle worker: skip entire bucket when no lifecycle config is set 2023-08-30 14:38:19 +02:00
Alex Auvolat 2996dc875f lifecycle worker: implement main functionality 2023-08-30 14:29:03 +02:00
Alex Auvolat a2e0e34db5 lifecycle: skeleton for lifecycle worker 2023-08-30 12:41:11 +02:00
Alex Auvolat f7b409f114 use a NaiveDate in data model, it serializes to string (iso 8601 format) 2023-08-30 11:24:01 +02:00
Alex Auvolat abf011c290 lifecycle: implement validation into garage's internal data structure 2023-08-29 18:22:03 +02:00
Alex Auvolat 8041d9a827 s3: add xml structures to serialize/deserialize lifecycle configs 2023-08-29 17:44:17 +02:00
Alex Auvolat 0b83e0558e bucket_table: data model for lifecycle configuration 2023-08-29 17:00:41 +02:00
Lapineige 47e7f9e122 another typo 2023-08-19 20:29:24 +00:00
Lapineige 5ffcdb4634 fix typo 2023-08-19 15:17:51 +00:00
362 changed files with 49343 additions and 6905 deletions
+3
View File
@@ -0,0 +1,3 @@
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
-290
View File
@@ -1,290 +0,0 @@
---
kind: pipeline
name: default
node:
nix-daemon: 1
steps:
- name: check formatting
image: nixpkgs/nix:nixos-22.05
commands:
- nix-shell --attr rust --run "cargo fmt -- --check"
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- name: unit + func tests
image: nixpkgs/nix:nixos-22.05
environment:
GARAGE_TEST_INTEGRATION_EXE: result-bin/bin/garage
GARAGE_TEST_INTEGRATION_PATH: tmp-garage-integration
commands:
- nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- nix-build --no-build-output --attr test.amd64
- ./result/bin/garage_db-*
- ./result/bin/garage_api-*
- ./result/bin/garage_model-*
- ./result/bin/garage_rpc-*
- ./result/bin/garage_table-*
- ./result/bin/garage_util-*
- ./result/bin/garage_web-*
- ./result/bin/garage-*
- ./result/bin/integration-* || (cat tmp-garage-integration/stderr.log; false)
- rm result
- rm -rv tmp-garage-integration
- name: integration tests
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr integration --run ./script/test-smoke.sh || (cat /tmp/garage.log; false)
trigger:
event:
- custom
- push
- pull_request
- tag
- cron
---
kind: pipeline
type: docker
name: release-linux-amd64
node:
nix-daemon: 1
steps:
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr pkgs.amd64.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr rust --run "./script/not-dynamic.sh result-bin/bin/garage"
- name: integration
image: nixpkgs/nix:nixos-22.05
commands:
- nix-shell --attr integration --run ./script/test-smoke.sh || (cat /tmp/garage.log; false)
- name: push static binary
image: nixpkgs/nix:nixos-22.05
environment:
AWS_ACCESS_KEY_ID:
from_secret: garagehq_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: garagehq_aws_secret_access_key
TARGET: "x86_64-unknown-linux-musl"
commands:
- nix-shell --attr release --run "to_s3"
- name: docker build and publish
image: nixpkgs/nix:nixos-22.05
environment:
DOCKER_AUTH:
from_secret: docker_auth
DOCKER_PLATFORM: "linux/amd64"
CONTAINER_NAME: "dxflrs/amd64_garage"
HOME: "/kaniko"
commands:
- mkdir -p /kaniko/.docker
- echo $DOCKER_AUTH > /kaniko/.docker/config.json
- export CONTAINER_TAG=${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr release --run "to_docker"
trigger:
event:
- promote
- cron
---
kind: pipeline
type: docker
name: release-linux-i386
node:
nix-daemon: 1
steps:
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr pkgs.i386.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr rust --run "./script/not-dynamic.sh result-bin/bin/garage"
- name: integration
image: nixpkgs/nix:nixos-22.05
commands:
- nix-shell --attr integration --run ./script/test-smoke.sh || (cat /tmp/garage.log; false)
- name: push static binary
image: nixpkgs/nix:nixos-22.05
environment:
AWS_ACCESS_KEY_ID:
from_secret: garagehq_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: garagehq_aws_secret_access_key
TARGET: "i686-unknown-linux-musl"
commands:
- nix-shell --attr release --run "to_s3"
- name: docker build and publish
image: nixpkgs/nix:nixos-22.05
environment:
DOCKER_AUTH:
from_secret: docker_auth
DOCKER_PLATFORM: "linux/386"
CONTAINER_NAME: "dxflrs/386_garage"
HOME: "/kaniko"
commands:
- mkdir -p /kaniko/.docker
- echo $DOCKER_AUTH > /kaniko/.docker/config.json
- export CONTAINER_TAG=${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr release --run "to_docker"
trigger:
event:
- promote
- cron
---
kind: pipeline
type: docker
name: release-linux-arm64
node:
nix-daemon: 1
steps:
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr pkgs.arm64.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr rust --run "./script/not-dynamic.sh result-bin/bin/garage"
- name: push static binary
image: nixpkgs/nix:nixos-22.05
environment:
AWS_ACCESS_KEY_ID:
from_secret: garagehq_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: garagehq_aws_secret_access_key
TARGET: "aarch64-unknown-linux-musl"
commands:
- nix-shell --attr release --run "to_s3"
- name: docker build and publish
image: nixpkgs/nix:nixos-22.05
environment:
DOCKER_AUTH:
from_secret: docker_auth
DOCKER_PLATFORM: "linux/arm64"
CONTAINER_NAME: "dxflrs/arm64_garage"
HOME: "/kaniko"
commands:
- mkdir -p /kaniko/.docker
- echo $DOCKER_AUTH > /kaniko/.docker/config.json
- export CONTAINER_TAG=${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr release --run "to_docker"
trigger:
event:
- promote
- cron
---
kind: pipeline
type: docker
name: release-linux-arm
node:
nix-daemon: 1
steps:
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr pkgs.arm.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr rust --run "./script/not-dynamic.sh result-bin/bin/garage"
- name: push static binary
image: nixpkgs/nix:nixos-22.05
environment:
AWS_ACCESS_KEY_ID:
from_secret: garagehq_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: garagehq_aws_secret_access_key
TARGET: "armv6l-unknown-linux-musleabihf"
commands:
- nix-shell --attr release --run "to_s3"
- name: docker build and publish
image: nixpkgs/nix:nixos-22.05
environment:
DOCKER_AUTH:
from_secret: docker_auth
DOCKER_PLATFORM: "linux/arm"
CONTAINER_NAME: "dxflrs/arm_garage"
HOME: "/kaniko"
commands:
- mkdir -p /kaniko/.docker
- echo $DOCKER_AUTH > /kaniko/.docker/config.json
- export CONTAINER_TAG=${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr release --run "to_docker"
trigger:
event:
- promote
- cron
---
kind: pipeline
type: docker
name: refresh-release-page
node:
nix-daemon: 1
steps:
- name: multiarch-docker
image: nixpkgs/nix:nixos-22.05
environment:
DOCKER_AUTH:
from_secret: docker_auth
HOME: "/root"
commands:
- mkdir -p /root/.docker
- echo $DOCKER_AUTH > /root/.docker/config.json
- export CONTAINER_TAG=${DRONE_TAG:-$DRONE_COMMIT}
- nix-shell --attr release --run "multiarch_docker"
- name: refresh-index
image: nixpkgs/nix:nixos-22.05
environment:
AWS_ACCESS_KEY_ID:
from_secret: garagehq_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: garagehq_aws_secret_access_key
commands:
- mkdir -p /etc/nix && cp nix/nix.conf /etc/nix/nix.conf
- nix-shell --attr release --run "refresh_index"
depends_on:
- release-linux-amd64
- release-linux-i386
- release-linux-arm64
- release-linux-arm
trigger:
event:
- promote
- cron
---
kind: signature
hmac: 24aebbcdba84fd0cdf963061d7bb72ae5b915bfdd0f50c7b019001126fb7fa56
...
+44
View File
@@ -0,0 +1,44 @@
when:
event:
- push
- tag
- pull_request
- deployment
- cron
steps:
- name: check formatting
image: nixpkgs/nix:nixos-22.05
commands:
- nix-shell --attr devShell --run "cargo fmt -- --check"
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- name: unit + func tests
image: nixpkgs/nix:nixos-22.05
environment:
GARAGE_TEST_INTEGRATION_EXE: result-bin/bin/garage
GARAGE_TEST_INTEGRATION_PATH: tmp-garage-integration
commands:
- nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- nix-build --no-build-output --attr test.amd64
- ./result/bin/garage_db-*
- ./result/bin/garage_api-*
- ./result/bin/garage_model-*
- ./result/bin/garage_rpc-*
- ./result/bin/garage_table-*
- ./result/bin/garage_util-*
- ./result/bin/garage_web-*
- ./result/bin/garage-*
- ./result/bin/integration-* || (cat tmp-garage-integration/stderr.log; false)
- rm result
- rm -rv tmp-garage-integration
- name: integration tests
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- nix-shell --attr ci --run ./script/test-smoke.sh || (cat /tmp/garage.log; false)
+29
View File
@@ -0,0 +1,29 @@
when:
event:
- deployment
- cron
depends_on:
- release
steps:
- name: refresh-index
image: nixpkgs/nix:nixos-22.05
secrets:
- source: garagehq_aws_access_key_id
target: AWS_ACCESS_KEY_ID
- source: garagehq_aws_secret_access_key
target: AWS_SECRET_ACCESS_KEY
commands:
- mkdir -p /etc/nix && cp nix/nix.conf /etc/nix/nix.conf
- nix-shell --attr ci --run "refresh_index"
- name: multiarch-docker
image: nixpkgs/nix:nixos-22.05
secrets:
- docker_auth
commands:
- mkdir -p /root/.docker
- echo $DOCKER_AUTH > /root/.docker/config.json
- export CONTAINER_TAG=${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- nix-shell --attr ci --run "multiarch_docker"
+70
View File
@@ -0,0 +1,70 @@
when:
event:
- deployment
- cron
matrix:
include:
- ARCH: amd64
TARGET: x86_64-unknown-linux-musl
- ARCH: i386
TARGET: i686-unknown-linux-musl
- ARCH: arm64
TARGET: aarch64-unknown-linux-musl
- ARCH: arm
TARGET: armv6l-unknown-linux-musleabihf
steps:
- name: build
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr pkgs.${ARCH}.release --argstr git_version ${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- name: check is static binary
image: nixpkgs/nix:nixos-22.05
commands:
- nix-build --no-build-output --attr pkgs.${ARCH}.release --argstr git_version ${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- nix-shell --attr ci --run "./script/not-dynamic.sh result-bin/bin/garage"
- name: integration tests
image: nixpkgs/nix:nixos-22.05
commands:
- nix-shell --attr ci --run ./script/test-smoke.sh || (cat /tmp/garage.log; false)
when:
- matrix:
ARCH: amd64
- matrix:
ARCH: i386
- name: upgrade tests
image: nixpkgs/nix:nixos-22.05
commands:
- nix-shell --attr ci --run "./script/test-upgrade.sh v0.8.4 x86_64-unknown-linux-musl" || (cat /tmp/garage.log; false)
when:
- matrix:
ARCH: amd64
- name: push static binary
image: nixpkgs/nix:nixos-22.05
environment:
TARGET: "${TARGET}"
secrets:
- source: garagehq_aws_access_key_id
target: AWS_ACCESS_KEY_ID
- source: garagehq_aws_secret_access_key
target: AWS_SECRET_ACCESS_KEY
commands:
- nix-shell --attr ci --run "to_s3"
- name: docker build and publish
image: nixpkgs/nix:nixos-22.05
environment:
DOCKER_PLATFORM: "linux/${ARCH}"
CONTAINER_NAME: "dxflrs/${ARCH}_garage"
secrets:
- docker_auth
commands:
- mkdir -p /root/.docker
- echo $DOCKER_AUTH > /root/.docker/config.json
- export CONTAINER_TAG=${CI_COMMIT_TAG:-$CI_COMMIT_SHA}
- nix-shell --attr ci --run "to_docker"
Generated
+1318 -877
View File
File diff suppressed because it is too large Load Diff
+2671 -2006
View File
File diff suppressed because it is too large Load Diff
+119 -9
View File
@@ -3,6 +3,7 @@ resolver = "2"
members = [
"src/db",
"src/util",
"src/net",
"src/rpc",
"src/table",
"src/block",
@@ -17,19 +18,128 @@ members = [
default-members = ["src/garage"]
[workspace.dependencies]
# Internal Garage crates
format_table = { version = "0.1.1", path = "src/format-table" }
garage_api = { version = "0.8.3", path = "src/api" }
garage_block = { version = "0.8.3", path = "src/block" }
garage_db = { version = "0.8.3", path = "src/db", default-features = false }
garage_model = { version = "0.8.3", path = "src/model", default-features = false }
garage_rpc = { version = "0.8.3", path = "src/rpc" }
garage_table = { version = "0.8.3", path = "src/table" }
garage_util = { version = "0.8.3", path = "src/util" }
garage_web = { version = "0.8.3", path = "src/web" }
garage_api = { version = "0.9.3", path = "src/api" }
garage_block = { version = "0.9.3", path = "src/block" }
garage_db = { version = "0.9.3", path = "src/db", default-features = false }
garage_model = { version = "0.9.3", path = "src/model", default-features = false }
garage_net = { version = "0.9.3", path = "src/net" }
garage_rpc = { version = "0.9.3", path = "src/rpc" }
garage_table = { version = "0.9.3", path = "src/table" }
garage_util = { version = "0.9.3", path = "src/util" }
garage_web = { version = "0.9.3", path = "src/web" }
k2v-client = { version = "0.0.4", path = "src/k2v-client" }
# External crates from crates.io
arc-swap = "1.0"
argon2 = "0.5"
async-trait = "0.1.7"
backtrace = "0.3"
base64 = "0.21"
blake2 = "0.10"
bytes = "1.0"
bytesize = "1.1"
cfg-if = "1.0"
chrono = "0.4"
crypto-common = "0.1"
digest = "0.10"
err-derive = "0.3"
gethostname = "0.4"
git-version = "0.3.4"
hex = "0.4"
hexdump = "0.1"
hmac = "0.12"
idna = "0.5"
itertools = "0.12"
lazy_static = "1.4"
md-5 = "0.10"
mktemp = "0.5"
nix = { version = "0.27", default-features = false, features = ["fs"] }
nom = "7.1"
parse_duration = "2.1"
pin-project = "1.0.12"
pnet_datalink = "0.34"
rand = "0.8"
sha2 = "0.10"
timeago = { version = "0.4", default-features = false }
xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] }
sodiumoxide = { version = "0.2.5-0", package = "kuska-sodiumoxide" }
kuska-handshake = { version = "0.2.0", features = ["default", "async_std"] }
clap = { version = "4.1", features = ["derive", "env"] }
pretty_env_logger = "0.5"
structopt = { version = "0.3", default-features = false }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
heed = { version = "0.11", default-features = false, features = ["lmdb"] }
rusqlite = "0.30.0"
sled = "0.34"
async-compression = { version = "0.4", features = ["tokio", "zstd"] }
zstd = { version = "0.13", default-features = false }
quick-xml = { version = "0.26", features = [ "serialize" ] }
rmp-serde = "1.1.2"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_bytes = "0.11"
serde_json = "1.0"
toml = { version = "0.8", default-features = false, features = ["parse"] }
# newer version requires rust edition 2021
k8s-openapi = { version = "0.21", features = ["v1_24"] }
kube = { version = "0.88", default-features = false, features = ["runtime", "derive", "client", "rustls-tls"] }
schemars = "0.8"
reqwest = { version = "0.11", default-features = false, features = ["rustls-tls-manual-roots", "json"] }
form_urlencoded = "1.0.0"
http = "1.0"
httpdate = "1.0"
http-range = "0.1"
http-body-util = "0.1"
hyper = { version = "1.0", default-features = false }
hyper-util = { version = "0.1", features = [ "full" ] }
multer = "3.0"
percent-encoding = "2.2"
roxmltree = "0.19"
url = "2.3"
futures = "0.3"
futures-util = "0.3"
tokio = { version = "1.0", default-features = false, features = ["net", "rt", "rt-multi-thread", "io-util", "net", "time", "macros", "sync", "signal", "fs"] }
tokio-util = { version = "0.7", features = ["compat", "io"] }
tokio-stream = { version = "0.1", features = ["net"] }
opentelemetry = { version = "0.17", features = [ "rt-tokio", "metrics", "trace" ] }
opentelemetry-prometheus = "0.10"
opentelemetry-otlp = "0.10"
opentelemetry-contrib = "0.9"
prometheus = "0.13"
# used by the k2v-client crate only
aws-sigv4 = { version = "1.1" }
hyper-rustls = { version = "0.26", features = ["http2"] }
log = "0.4"
thiserror = "1.0"
# ---- used only as build / dev dependencies ----
assert-json-diff = "2.0"
rustc_version = "0.4.0"
static_init = "1.0"
aws-config = "1.1.4"
aws-sdk-config = "1.13"
aws-sdk-s3 = "1.14"
[profile.dev]
#lto = "thin" # disabled for now, adds 2-4 min to each CI build
lto = "off"
[profile.release]
debug = true
lto = true
codegen-units = 1
opt-level = "s"
strip = true
+1 -1
View File
@@ -1,4 +1,4 @@
Garage [![Build Status](https://drone.deuxfleurs.fr/api/badges/Deuxfleurs/garage/status.svg?ref=refs/heads/main)](https://drone.deuxfleurs.fr/Deuxfleurs/garage)
Garage [![status-badge](https://woodpecker.deuxfleurs.fr/api/badges/1/status.svg)](https://woodpecker.deuxfleurs.fr/repos/1)
===
<p align="center" style="text-align:center;">
+24
View File
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<title>Garage Adminstration API v0</title>
<!-- needed for adaptive design -->
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="./css/redoc.css" rel="stylesheet">
<!--
Redoc doesn't change outer page styles
-->
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<redoc spec-url='./garage-admin-v1.yml'></redoc>
<script src="./redoc.standalone.js"> </script>
</body>
</html>
File diff suppressed because it is too large Load Diff
+67 -13
View File
@@ -37,30 +37,84 @@ import (
"context"
"fmt"
"os"
"strings"
garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
)
func main() {
// Set Host and other parameters
// Initialization
configuration := garage.NewConfiguration()
configuration.Host = "127.0.0.1:3903"
// We can now generate a client
client := garage.NewAPIClient(configuration)
// Authentication is handled through the context pattern
ctx := context.WithValue(context.Background(), garage.ContextAccessToken, "s3cr3t")
// Send a request
resp, r, err := client.NodesApi.GetNodes(ctx).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `NodesApi.GetNodes``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
// Nodes
fmt.Println("--- nodes ---")
nodes, _, _ := client.NodesApi.GetNodes(ctx).Execute()
fmt.Fprintf(os.Stdout, "First hostname: %v\n", nodes.KnownNodes[0].Hostname)
capa := int64(1000000000)
change := []garage.NodeRoleChange{
garage.NodeRoleChange{NodeRoleUpdate: &garage.NodeRoleUpdate {
Id: *nodes.KnownNodes[0].Id,
Zone: "dc1",
Capacity: *garage.NewNullableInt64(&capa),
Tags: []string{ "fast", "amd64" },
}},
}
staged, _, _ := client.LayoutApi.AddLayout(ctx).NodeRoleChange(change).Execute()
msg, _, _ := client.LayoutApi.ApplyLayout(ctx).LayoutVersion(*garage.NewLayoutVersion(staged.Version + 1)).Execute()
fmt.Printf(strings.Join(msg.Message, "\n")) // Layout configured
// Process the response
fmt.Fprintf(os.Stdout, "Target hostname: %v\n", resp.KnownNodes[resp.Node].Hostname)
health, _, _ := client.NodesApi.GetHealth(ctx).Execute()
fmt.Printf("Status: %s, nodes: %v/%v, storage: %v/%v, partitions: %v/%v\n", health.Status, health.ConnectedNodes, health.KnownNodes, health.StorageNodesOk, health.StorageNodes, health.PartitionsAllOk, health.Partitions)
// Key
fmt.Println("\n--- key ---")
key := "openapi-key"
keyInfo, _, _ := client.KeyApi.AddKey(ctx).AddKeyRequest(garage.AddKeyRequest{Name: *garage.NewNullableString(&key) }).Execute()
defer client.KeyApi.DeleteKey(ctx).Id(*keyInfo.AccessKeyId).Execute()
fmt.Printf("AWS_ACCESS_KEY_ID=%s\nAWS_SECRET_ACCESS_KEY=%s\n", *keyInfo.AccessKeyId, *keyInfo.SecretAccessKey.Get())
id := *keyInfo.AccessKeyId
canCreateBucket := true
updateKeyRequest := *garage.NewUpdateKeyRequest()
updateKeyRequest.SetName("openapi-key-updated")
updateKeyRequest.SetAllow(garage.UpdateKeyRequestAllow { CreateBucket: &canCreateBucket })
update, _, _ := client.KeyApi.UpdateKey(ctx).Id(id).UpdateKeyRequest(updateKeyRequest).Execute()
fmt.Printf("Updated %v with key name %v\n", *update.AccessKeyId, *update.Name)
keyList, _, _ := client.KeyApi.ListKeys(ctx).Execute()
fmt.Printf("Keys count: %v\n", len(keyList))
// Bucket
fmt.Println("\n--- bucket ---")
global_name := "global-ns-openapi-bucket"
local_name := "local-ns-openapi-bucket"
bucketInfo, _, _ := client.BucketApi.CreateBucket(ctx).CreateBucketRequest(garage.CreateBucketRequest{
GlobalAlias: &global_name,
LocalAlias: &garage.CreateBucketRequestLocalAlias {
AccessKeyId: keyInfo.AccessKeyId,
Alias: &local_name,
},
}).Execute()
defer client.BucketApi.DeleteBucket(ctx).Id(*bucketInfo.Id).Execute()
fmt.Printf("Bucket id: %s\n", *bucketInfo.Id)
updateBucketRequest := *garage.NewUpdateBucketRequest()
website := garage.NewUpdateBucketRequestWebsiteAccess()
website.SetEnabled(true)
website.SetIndexDocument("index.html")
website.SetErrorDocument("errors/4xx.html")
updateBucketRequest.SetWebsiteAccess(*website)
quotas := garage.NewUpdateBucketRequestQuotas()
quotas.SetMaxSize(1000000000)
quotas.SetMaxObjects(999999999)
updateBucketRequest.SetQuotas(*quotas)
updatedBucket, _, _ := client.BucketApi.UpdateBucket(ctx).Id(*bucketInfo.Id).UpdateBucketRequest(updateBucketRequest).Execute()
fmt.Printf("Bucket %v website activation: %v\n", *updatedBucket.Id, *updatedBucket.WebsiteAccess)
bucketList, _, _ := client.BucketApi.ListBuckets(ctx).Execute()
fmt.Printf("Bucket count: %v\n", len(bucketList))
}
```
+2 -2
View File
@@ -31,9 +31,9 @@ npm install --save git+https://git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-js.
A short example:
```javascript
const garage = require('garage_administration_api_v0garage_v0_8_0');
const garage = require('garage_administration_api_v1garage_v0_9_0');
const api = new garage.ApiClient("http://127.0.0.1:3903/v0");
const api = new garage.ApiClient("http://127.0.0.1:3903/v1");
api.authentications['bearerAuth'].accessToken = "s3cr3t";
const [node, layout, key, bucket] = [
+6 -5
View File
@@ -80,7 +80,7 @@ from garage_admin_sdk.apis import *
from garage_admin_sdk.models import *
configuration = garage_admin_sdk.Configuration(
host = "http://localhost:3903/v0",
host = "http://localhost:3903/v1",
access_token = "s3cr3t"
)
@@ -94,13 +94,14 @@ print(f"running garage {status.garage_version}, node_id {status.node}")
# Change layout of this node
current = layout.get_layout()
layout.add_layout({
status.node: NodeClusterInfo(
layout.add_layout([
NodeRoleChange(
id = status.node,
zone = "dc1",
capacity = 1,
capacity = 1000000000,
tags = [ "dev" ],
)
})
])
layout.apply_layout(LayoutVersion(
version = current.version + 1
))
+4 -4
View File
@@ -146,7 +146,7 @@ Keep the Key ID and the Secret key in a pad, they will be needed later.
We need two buckets, one for normal videos (named peertube-video) and one for webtorrent videos (named peertube-playlist).
```bash
garage bucket create peertube-video
garage bucket create peertube-videos
garage bucket create peertube-playlist
```
@@ -216,7 +216,7 @@ object_storage:
# Same settings but for webtorrent videos
videos:
bucket_name: 'peertube-video'
bucket_name: 'peertube-videos'
prefix: ''
# You must fill this field to make Peertube use our reverse proxy/website logic
base_url: 'http://peertube-videos.web.garage.localhost'
@@ -421,7 +421,7 @@ Now we can write a simple script (eg `~/.local/bin/matrix-cache-gc`):
## CONFIGURATION ##
AWS_ACCESS_KEY_ID=GKxxx
AWS_SECRET_ACCESS_KEY=xxxx
S3_ENDPOINT=http://localhost:3900
AWS_ENDPOINT_URL=http://localhost:3900
S3_BUCKET=matrix
MEDIA_STORE=/var/lib/matrix-synapse/media
PG_USER=matrix
@@ -442,7 +442,7 @@ EOF
s3_media_upload update-db 1d
s3_media_upload --no-progress check-deleted $MEDIA_STORE
s3_media_upload --no-progress upload $MEDIA_STORE $S3_BUCKET --delete --endpoint-url $S3_ENDPOINT
s3_media_upload --no-progress upload $MEDIA_STORE $S3_BUCKET --delete --endpoint-url $AWS_ENDPOINT_URL
```
This script will list all the medias that were not accessed in the 24 hours according to your database.
+2 -2
View File
@@ -55,8 +55,8 @@ Create your key and bucket:
```bash
garage key create my-key
garage bucket create backup
garage bucket allow backup --read --write --key my-key
garage bucket create backups
garage bucket allow backups --read --write --key my-key
```
Then register your Key ID and Secret key in your environment:
+4 -3
View File
@@ -70,16 +70,17 @@ Then a file named `~/.aws/config` and put:
```toml
[default]
region=garage
endpoint_url=http://127.0.0.1:3900
```
Now, supposing Garage is listening on `http://127.0.0.1:3900`, you can list your buckets with:
```bash
aws --endpoint-url http://127.0.0.1:3900 s3 ls
aws s3 ls
```
Passing the `--endpoint-url` parameter to each command is annoying but AWS developers do not provide a corresponding configuration entry.
As a workaround, you can redefine the aws command by editing the file `~/.bashrc`:
If you're using awscli `<1.29.0` or `<2.13.0`, you need to pass `--endpoint-url` to each CLI invocation explicitly.
As a workaround, you can redefine the aws command by editing the file `~/.bashrc` in this case:
```
function aws { command aws --endpoint-url http://127.0.0.1:3900 $@ ; }
+1 -1
View File
@@ -38,7 +38,7 @@ Our website serving logic is as follow:
Now we need to infer the URL of your website through your bucket name.
Let assume:
- we set `root_domain = ".web.example.com"` in `garage.toml` ([ref](@/documentation/reference-manual/configuration.md#root_domain))
- we set `root_domain = ".web.example.com"` in `garage.toml` ([ref](@/documentation/reference-manual/configuration.md#web_root_domain))
- our bucket name is `garagehq.deuxfleurs.fr`.
Our bucket will be served if the Host field matches one of these 2 values (the port is ignored):
+1 -1
View File
@@ -18,7 +18,7 @@ api_bind_addr = "0.0.0.0:3903"
```
This will allow anyone to scrape Prometheus metrics by fetching
`http://localhost:3093/metrics`. If you want to restrict access
`http://localhost:3903/metrics`. If you want to restrict access
to the exported metrics, set the `metrics_token` configuration value
to a bearer token to be used when fetching the metrics endpoint.
+45 -43
View File
@@ -19,9 +19,10 @@ To run a real-world deployment, make sure the following conditions are met:
- You have at least three machines with sufficient storage space available.
- Each machine has a public IP address which is reachable by other machines. It
is highly recommended that you use IPv6 for this end-to-end connectivity. If
IPv6 is not available, then using a mesh VPN such as
- Each machine has an IP address which makes it directly reachable by all other machines.
In many cases, nodes will be behind a NAT and will not each have a public
IPv4 addresses. In this case, is recommended that you use IPv6 for this
end-to-end connectivity if it is available. Otherwise, using a mesh VPN such as
[Nebula](https://github.com/slackhq/nebula) or
[Yggdrasil](https://yggdrasil-network.github.io/) are approaches to consider
in addition to building out your own VPN tunneling.
@@ -42,7 +43,7 @@ For our example, we will suppose the following infrastructure with IPv6 connecti
| Brussels | Mars | fc00:F::1 | 1.5 TB |
Note that Garage will **always** store the three copies of your data on nodes at different
locations. This means that in the case of this small example, the available capacity
locations. This means that in the case of this small example, the usable capacity
of the cluster is in fact only 1.5 TB, because nodes in Brussels can't store more than that.
This also means that nodes in Paris and London will be under-utilized.
To make better use of the available hardware, you should ensure that the capacity
@@ -75,28 +76,23 @@ to store 2 TB of data in total.
- For the metadata storage, Garage does not do checksumming and integrity
verification on its own. If you are afraid of bitrot/data corruption,
put your metadata directory on a BTRFS partition. Otherwise, just use regular
put your metadata directory on a ZFS or BTRFS partition. Otherwise, just use regular
EXT4 or XFS.
- Having a single server with several storage drives is currently not very well
supported in Garage ([#218](https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/218)).
For an easy setup, just put all your drives in a RAID0 or a ZFS RAIDZ array.
If you're adventurous, you can try to format each of your disk as
a separate XFS partition, and then run one `garage` daemon per disk drive,
or use something like [`mergerfs`](https://github.com/trapexit/mergerfs) to merge
all your disks in a single union filesystem that spreads load over them.
- Servers with multiple HDDs are supported natively by Garage without resorting
to RAID, see [our dedicated documentation page](@/documentation/operations/multi-hdd.md).
## Get a Docker image
Our docker image is currently named `dxflrs/garage` and is stored on the [Docker Hub](https://hub.docker.com/r/dxflrs/garage/tags?page=1&ordering=last_updated).
We encourage you to use a fixed tag (eg. `v0.8.0`) and not the `latest` tag.
For this example, we will use the latest published version at the time of the writing which is `v0.8.0` but it's up to you
We encourage you to use a fixed tag (eg. `v0.9.3`) and not the `latest` tag.
For this example, we will use the latest published version at the time of the writing which is `v0.9.3` but it's up to you
to check [the most recent versions on the Docker Hub](https://hub.docker.com/r/dxflrs/garage/tags?page=1&ordering=last_updated).
For example:
```
sudo docker pull dxflrs/garage:v0.8.0
sudo docker pull dxflrs/garage:v0.9.3
```
## Deploying and configuring Garage
@@ -161,12 +157,13 @@ docker run \
-v /etc/garage.toml:/etc/garage.toml \
-v /var/lib/garage/meta:/var/lib/garage/meta \
-v /var/lib/garage/data:/var/lib/garage/data \
dxflrs/garage:v0.8.0
dxflrs/garage:v0.9.3
```
It should be restarted automatically at each reboot.
Please note that we use host networking as otherwise Docker containers
can not communicate with IPv6.
With this command line, Garage should be started automatically at each boot.
Please note that we use host networking as otherwise the network indirection
added by Docker would prevent Garage nodes from communicating with one another
(especially if using IPv6).
If you want to use `docker-compose`, you may use the following `docker-compose.yml` file as a reference:
@@ -174,7 +171,7 @@ If you want to use `docker-compose`, you may use the following `docker-compose.y
version: "3"
services:
garage:
image: dxflrs/garage:v0.8.0
image: dxflrs/garage:v0.9.3
network_mode: "host"
restart: unless-stopped
volumes:
@@ -183,10 +180,12 @@ services:
- /var/lib/garage/data:/var/lib/garage/data
```
Upgrading between Garage versions should be supported transparently,
but please check the relase notes before doing so!
To upgrade, simply stop and remove this container and
start again the command with a new version of Garage.
If you wish to upgrade your cluster, make sure to read the corresponding
[documentation page](@/documentation/operations/upgrading.md) first, as well as
the documentation relevant to your version of Garage in the case of major
upgrades. With the containerized setup proposed here, the upgrade process
will require stopping and removing the existing container, and re-creating it
with the upgraded version.
## Controling the daemon
@@ -270,12 +269,12 @@ of a role that is assigned to each active cluster node.
For our example, we will suppose we have the following infrastructure
(Capacity, Identifier and Zone are specific values to Garage described in the following):
| Location | Name | Disk Space | `Capacity` | `Identifier` | `Zone` |
|----------|---------|------------|------------|--------------|--------------|
| Paris | Mercury | 1 TB | `10` | `563e` | `par1` |
| Paris | Venus | 2 TB | `20` | `86f0` | `par1` |
| London | Earth | 2 TB | `20` | `6814` | `lon1` |
| Brussels | Mars | 1.5 TB | `15` | `212f` | `bru1` |
| Location | Name | Disk Space | Identifier | Zone (`-z`) | Capacity (`-c`) |
|----------|---------|------------|------------|-------------|-----------------|
| Paris | Mercury | 1 TB | `563e` | `par1` | `1T` |
| Paris | Venus | 2 TB | `86f0` | `par1` | `2T` |
| London | Earth | 2 TB | `6814` | `lon1` | `2T` |
| Brussels | Mars | 1.5 TB | `212f` | `bru1` | `1.5T` |
#### Node identifiers
@@ -297,6 +296,8 @@ garage status
It will display the IP address associated with each node;
from the IP address you will be able to recognize the node.
We will now use the `garage layout assign` command to configure the correct parameters for each node.
#### Zones
Zones are simply a user-chosen identifier that identify a group of server that are grouped together logically.
@@ -306,29 +307,29 @@ In most cases, a zone will correspond to a geographical location (i.e. a datacen
Behind the scene, Garage will use zone definition to try to store the same data on different zones,
in order to provide high availability despite failure of a zone.
Zones are passed to Garage using the `-z` flag of `garage layout assign` (see below).
#### Capacity
Garage reasons on an abstract metric about disk storage that is named the *capacity* of a node.
The capacity configured in Garage must be proportional to the disk space dedicated to the node.
Garage needs to know the storage capacity (disk space) it can/should use on
each node, to be able to correctly balance data.
Capacity values must be **integers** but can be given any signification.
Here we chose that 1 unit of capacity = 100 GB.
Capacity values are expressed in bytes and are passed to Garage using the `-c` flag of `garage layout assign` (see below).
Note that the amount of data stored by Garage on each server may not be strictly proportional to
its capacity value, as Garage will priorize having 3 copies of data in different zones,
even if this means that capacities will not be strictly respected. For example in our above examples,
nodes Earth and Mars will always store a copy of everything each, and the third copy will
have 66% chance of being stored by Venus and 33% chance of being stored by Mercury.
#### Tags
You can add additional tags to nodes using the `-t` flag of `garage layout assign` (see below).
Tags have no specific meaning for Garage and can be used at your convenience.
#### Injecting the topology
Given the information above, we will configure our cluster as follow:
```bash
garage layout assign 563e -z par1 -c 10 -t mercury
garage layout assign 86f0 -z par1 -c 20 -t venus
garage layout assign 6814 -z lon1 -c 20 -t earth
garage layout assign 212f -z bru1 -c 15 -t mars
garage layout assign 563e -z par1 -c 1T -t mercury
garage layout assign 86f0 -z par1 -c 2T -t venus
garage layout assign 6814 -z lon1 -c 2T -t earth
garage layout assign 212f -z bru1 -c 1.5T -t mars
```
At this point, the changes in the cluster layout have not yet been applied.
@@ -338,6 +339,7 @@ To show the new layout that will be applied, call:
garage layout show
```
Make sure to read carefully the output of `garage layout show`.
Once you are satisfied with your new layout, apply it with:
```bash
+29
View File
@@ -472,3 +472,32 @@ https:// {
More information on how this endpoint is implemented in Garage is available
in the [Admin API Reference](@/documentation/reference-manual/admin-api.md) page.
### Fileserver browser
Caddy's built-in
[file_server](https://caddyserver.com/docs/caddyfile/directives/file_server)
browser functionality can be extended with the
[caddy-fs-s3](https://github.com/sagikazarmark/caddy-fs-s3) module.
This can be configured to use Garage as a backend with the following
configuration:
```caddy
browse.garage.tld {
file_server {
fs s3 {
bucket test-bucket
region garage
endpoint https://s3.garage.tld
use_path_style
}
browse
}
}
```
Caddy must also be configured with the required `AWS_ACCESS_KEY_ID` and
`AWS_SECRET_ACCESS_KEY` environment variables to access the bucket.
-2
View File
@@ -48,7 +48,5 @@ locations. They use Garage themselves for the following tasks:
- As a backup target using `rclone` and `restic`
- In the Drone continuous integration platform to store task logs
The Deuxfleurs Garage cluster is a multi-site cluster currently composed of
9 nodes in 3 physical locations.
+1 -1
View File
@@ -80,7 +80,7 @@ nix-build \
--git_version $(git rev-parse HEAD)
```
*The result is located in `result/bin`. You can pass arguments to cross compile: check `.drone.yml` for examples.*
*The result is located in `result/bin`. You can pass arguments to cross compile: check `.woodpecker/release.yml` for examples.*
If you modify a `Cargo.toml` or regenerate any `Cargo.lock`, you must run `cargo2nix`:
+3 -5
View File
@@ -81,12 +81,9 @@ Our cache will be checked.
- http://www.lpenz.org/articles/nixchannel/index.html
## Drone
## Woodpecker
Do not try to set a build as trusted from the interface or the CLI tool,
your request would be ignored. Instead, directly edit the database (table `repos`, column `repo_trusted`).
Drone can do parallelism both at the step and the pipeline level. At the step level, parallelism is restricted to the same runner.
Woodpecker can do parallelism both at the step and the pipeline level. At the step level, parallelism is restricted to the same runner.
## Building Docker containers
@@ -99,3 +96,4 @@ We were:
- Unable to use the kaniko container provided by Google as we can't run arbitrary logic: we need to put our secret in .docker/config.json.
Finally we chose to build kaniko through nix and use it in a `nix-shell`.
We then switched to using kaniko from nixpkgs when it was packaged.
+17 -38
View File
@@ -42,7 +42,7 @@ and the docker containers on Docker Hub.
## Automation
We automated our release process with Nix and Drone to make it more reliable.
We automated our release process with Nix and Woodpecker to make it more reliable.
Here we describe how we have done in case you want to debug or improve it.
### Caching build steps
@@ -62,52 +62,31 @@ Sending to the cache is done through `nix copy`, for example:
nix copy --to 's3://nix?endpoint=garage.deuxfleurs.fr&region=garage&secret-key=/etc/nix/signing-key.sec' result
```
*Note that you need the signing key. In our case, it is stored as a secret in Drone.*
*The signing key possessed by the Garage maintainers is required to update the Nix cache.*
The previous command will only send the built packet and not its dependencies.
To send its dependency, a tool named `nix-copy-closure` has been created but it is not compatible with the S3 protocol.
Instead, you can use the following commands to list all the runtime dependencies:
The previous command will only send the built package and not its dependencies.
In the case of our CI pipeline, we want to cache all intermediate build steps
as well. This can be done using this quite involved command (here as an example
for the `pkgs.amd64.relase` package):
```bash
nix copy \
--to 's3://nix?endpoint=garage.deuxfleurs.fr&region=garage&secret-key=/etc/nix/signing-key.sec' \
$(nix-store -qR result/)
nix copy -j8 \
--to 's3://nix?endpoint=garage.deuxfleurs.fr&region=garage&secret-key=/etc/nix/nix-signing-key.sec' \
$(nix path-info pkgs.amd64.release --file default.nix --derivation --recursive | sed 's/\.drv$/.drv^*/')
```
*We could also write this expression with xargs but this tool is not available in our container.*
This command will simultaneously build all of the required Nix paths (using at
most 8 parallel Nix builder jobs) and send the resulting objects to the cache.
But in certain cases, we want to cache compile time dependencies also.
For example, the Nix project does not provide binaries for cross compiling to i686 and thus we need to compile gcc on our own.
We do not want to compile gcc each time, so even if it is a compile time dependency, we want to cache it.
This time, the command is a bit more involved:
```bash
nix copy --to \
's3://nix?endpoint=garage.deuxfleurs.fr&region=garage&secret-key=/etc/nix/signing-key.sec' \
$(nix-store -qR --include-outputs \
$(nix-instantiate))
```
This is the command we use in our CI as we expect the final binary to change, so we mainly focus on
caching our development dependencies.
*Currently there is no automatic garbage collection of the cache: we should monitor its growth.
Hopefully, we can erase it totally without breaking any build, the next build will only be slower.*
In practise, we concluded that we do not want to cache all the compilation dependencies.
Instead, we want to cache the toolchain we use to build Garage each time we change it.
So we removed from Drone any automatic update of the cache and instead handle them manually with:
This can be run for all the Garage packages we build using the following command:
```
source ~/.awsrc
nix-shell --run 'refresh_toolchain'
nix-shell --attr cache --run 'refresh_cache'
```
Internally, it will run `nix-build` on `nix/toolchain.nix` and send the output plus its depedencies to the cache.
To erase the cache:
We don't automate this step at each CI build, as *there is currently no automatic garbage collection of the cache.*
This means we should also monitor the cache's size; if it ever becomes too big we can erase it with:
```
mc rm --recursive --force 'garage/nix/'
@@ -157,9 +136,9 @@ nix-shell --run refresh_index
If you want to compile for different architectures, you will need to repeat all these commands for each architecture.
**In practise, and except for debugging, you will never directly run these commands. Release is handled by drone**
**In practice, and except for debugging, you will never directly run these commands. Release is handled by Woodpecker.**
### Drone
### Drone (obsolete)
Our instance is available at [https://drone.deuxfleurs.fr](https://drone.deuxfleurs.fr).
You need an account on [https://git.deuxfleurs.fr](https://git.deuxfleurs.fr) to use it.
+11 -2
View File
@@ -49,7 +49,7 @@ verifications. Of course, scrubbing the entire data store will also take longer.
## Block check and resync
In some cases, nodes hold a reference to a block but do not actually have the block
stored on disk. Conversely, they may also have on disk blocks that are not referenced
stored on disk. Conversely, they may also have on-disk blocks that are not referenced
any more. To fix both cases, a block repair may be run with `garage repair blocks`.
This will scan the entire block reference counter table to check that the blocks
exist on disk, and will scan the entire disk store to check that stored blocks
@@ -91,6 +91,16 @@ is definitely lost, then there is no other choice than to declare your S3 object
as unrecoverable, and to delete them properly from the data store. This can be done
using the `garage block purge` command.
## Rebalancing data directories
In [multi-HDD setups](@/documentation/operations/multi-hdd.md), to ensure that
data blocks are well balanced between storage locations, you may run a
rebalance operation using `garage repair rebalance`. This is useful when
adding storage locations or when capacities of the storage locations have been
changed. Once this is finished, Garage will know for each block of a single
possible location where it can be, which can increase access speed. This
operation will also move out all data from locations marked as read-only.
# Metadata operations
@@ -114,4 +124,3 @@ in your cluster, you can run one of the following repair procedures:
- `garage repair versions`: checks that all versions belong to a non-deleted object, and purges any orphan version
- `garage repair block_refs`: checks that all block references belong to a non-deleted object version, and purges any orphan block reference (this will then allow the blocks to be garbage-collected)
+209 -12
View File
@@ -9,18 +9,30 @@ a certain capacity, or a gateway node that does not store data and is only
used as an API entry point for faster cluster access.
An introduction to building cluster layouts can be found in the [production deployment](@/documentation/cookbook/real-world.md) page.
In Garage, all of the data that can be stored in a given cluster is divided
into slices which we call *partitions*. Each partition is stored by
one or several nodes in the cluster
(see [`replication_mode`](@/documentation/reference-manual/configuration.md#replication_mode)).
The layout determines the correspondence between these partitions,
which exist on a logical level, and actual storage nodes.
## How cluster layouts work in Garage
In Garage, a cluster layout is composed of the following components:
A cluster layout is composed of the following components:
- a table of roles assigned to nodes
- a table of roles assigned to nodes, defined by the user
- an optimal assignation of partitions to nodes, computed by an algorithm that is ran once when calling `garage layout apply` or the ApplyClusterLayout API endpoint
- a version number
Garage nodes will always use the cluster layout with the highest version number.
Garage nodes also maintain and synchronize between them a set of proposed role
changes that haven't yet been applied. These changes will be applied (or
canceled) in the next version of the layout
canceled) in the next version of the layout.
All operations on the layout can be realized using the `garage` CLI or using the
[administration API endpoint](@/documentation/reference-manual/admin-api.md).
We give here a description of CLI commands, the admin API semantics are very similar.
The following commands insert modifications to the set of proposed role changes
for the next layout version (but they do not create the new layout immediately):
@@ -51,7 +63,7 @@ commands will fail otherwise.
## Warnings about Garage cluster layout management
**Warning: never make several calls to `garage layout apply` or `garage layout
**⚠️ Never make several calls to `garage layout apply` or `garage layout
revert` with the same value of the `--version` flag. Doing so can lead to the
creation of several different layouts with the same version number, in which
case your Garage cluster will become inconsistent until fixed.** If a call to
@@ -65,13 +77,198 @@ shell, you shouldn't have much issues as long as you run commands one after
the other and take care of checking the output of `garage layout show`
before applying any changes.
If you are using the `garage` CLI to script layout changes, follow the following recommendations:
If you are using the `garage` CLI or the admin API to script layout changes,
follow the following recommendations:
- Make all of your `garage` CLI calls to the same RPC host. Do not use the
`garage` CLI to connect to individual nodes to send them each a piece of the
layout changes you are making, as the changes propagate asynchronously
between nodes and might not all be taken into account at the time when the
new layout is applied.
- If using the CLI, make all of your `garage` CLI calls to the same RPC host.
If using the admin API, make all of your API calls to the same Garage node. Do
not connect to individual nodes to send them each a piece of the layout changes
you are making, as the changes propagate asynchronously between nodes and might
not all be taken into account at the time when the new layout is applied.
- **Only call `garage layout apply` once**, and call it **strictly after** all
of the `layout assign` and `layout remove` commands have returned.
- **Only call `garage layout apply`/ApplyClusterLayout once**, and call it
**strictly after** all of the `layout assign` and `layout remove`
commands/UpdateClusterLayout API calls have returned.
## Understanding unexpected layout calculations
When adding, removing or modifying nodes in a cluster layout, sometimes
unexpected assignations of partitions to node can occur. These assignations
are in fact normal and logical, given the objectives of the algorithm. Indeed,
**the layout algorithm prioritizes moving less data between nodes over
achieving equal distribution of load. It also tries to use all links between
pairs of nodes in equal proportions when moving data.** This section presents
two examples and illustrates how one can control Garage's behavior to obtain
the desired results.
### Example 1
In this example, a cluster is originally composed of 3 nodes in 3 different
zones (data centers). The three nodes are of equal capacity, therefore they
are all fully exploited and all store a copy of all of the data in the cluster.
Then, a fourth node of the same size is added in the datacenter `dc1`.
As illustrated by the following, **Garage will by default not store any data on the new node**:
```
$ garage layout show
==== CURRENT CLUSTER LAYOUT ====
ID Tags Zone Capacity Usable capacity
b10c110e4e854e5a node1 dc1 1000.0 MB 1000.0 MB (100.0%)
a235ac7695e0c54d node2 dc2 1000.0 MB 1000.0 MB (100.0%)
62b218d848e86a64 node3 dc3 1000.0 MB 1000.0 MB (100.0%)
Zone redundancy: maximum
Current cluster layout version: 6
==== STAGED ROLE CHANGES ====
ID Tags Zone Capacity
a11c7cf18af29737 node4 dc1 1000.0 MB
==== NEW CLUSTER LAYOUT AFTER APPLYING CHANGES ====
ID Tags Zone Capacity Usable capacity
b10c110e4e854e5a node1 dc1 1000.0 MB 1000.0 MB (100.0%)
a11c7cf18af29737 node4 dc1 1000.0 MB 0 B (0.0%)
a235ac7695e0c54d node2 dc2 1000.0 MB 1000.0 MB (100.0%)
62b218d848e86a64 node3 dc3 1000.0 MB 1000.0 MB (100.0%)
Zone redundancy: maximum
==== COMPUTATION OF A NEW PARTITION ASSIGNATION ====
Partitions are replicated 3 times on at least 3 distinct zones.
Optimal partition size: 3.9 MB (3.9 MB in previous layout)
Usable capacity / total cluster capacity: 3.0 GB / 4.0 GB (75.0 %)
Effective capacity (replication factor 3): 1000.0 MB
A total of 0 new copies of partitions need to be transferred.
dc1 Tags Partitions Capacity Usable capacity
b10c110e4e854e5a node1 256 (0 new) 1000.0 MB 1000.0 MB (100.0%)
a11c7cf18af29737 node4 0 (0 new) 1000.0 MB 0 B (0.0%)
TOTAL 256 (256 unique) 2.0 GB 1000.0 MB (50.0%)
dc2 Tags Partitions Capacity Usable capacity
a235ac7695e0c54d node2 256 (0 new) 1000.0 MB 1000.0 MB (100.0%)
TOTAL 256 (256 unique) 1000.0 MB 1000.0 MB (100.0%)
dc3 Tags Partitions Capacity Usable capacity
62b218d848e86a64 node3 256 (0 new) 1000.0 MB 1000.0 MB (100.0%)
TOTAL 256 (256 unique) 1000.0 MB 1000.0 MB (100.0%)
```
While unexpected, this is logical because of the following facts:
- storing some data on the new node does not help increase the total quantity
of data that can be stored on the cluster, as the two other zones (`dc2` and
`dc3`) still need to store a full copy of everything, and their capacity is
still the same;
- there is therefore no need to move any data on the new node as this would be pointless;
- moving data to the new node has a cost which the algorithm decides to not pay if not necessary.
This distribution of data can however not be what the administrator wanted: if
they added a new node to `dc1`, it might be because the existing node is too
slow, and they wish to divide its load by half. In that case, what they need to
do to force Garage to distribute the data between the two nodes is to attribute
only half of the capacity to each node in `dc1` (in our example, 500M instead of 1G).
In that case, Garage would determine that to be able to store 1G in total, it
would need to store 500M on the old node and 500M on the added one.
### Example 2
The following example is a slightly different scenario, where `dc1` had two
nodes that were used at 50%, and `dc2` and `dc3` each have one node that is
100% used. All node capacities are the same.
Then, a node from `dc1` is moved into `dc3`. One could expect that the roles of
`dc1` and `dc3` would simply be swapped: the remaining node in `dc1` would be
used at 100%, and the two nodes now in `dc3` would be used at 50%. Instead,
this happens:
```
==== CURRENT CLUSTER LAYOUT ====
ID Tags Zone Capacity Usable capacity
b10c110e4e854e5a node1 dc1 1000.0 MB 500.0 MB (50.0%)
a11c7cf18af29737 node4 dc1 1000.0 MB 500.0 MB (50.0%)
a235ac7695e0c54d node2 dc2 1000.0 MB 1000.0 MB (100.0%)
62b218d848e86a64 node3 dc3 1000.0 MB 1000.0 MB (100.0%)
Zone redundancy: maximum
Current cluster layout version: 8
==== STAGED ROLE CHANGES ====
ID Tags Zone Capacity
a11c7cf18af29737 node4 dc3 1000.0 MB
==== NEW CLUSTER LAYOUT AFTER APPLYING CHANGES ====
ID Tags Zone Capacity Usable capacity
b10c110e4e854e5a node1 dc1 1000.0 MB 1000.0 MB (100.0%)
a235ac7695e0c54d node2 dc2 1000.0 MB 1000.0 MB (100.0%)
62b218d848e86a64 node3 dc3 1000.0 MB 753.9 MB (75.4%)
a11c7cf18af29737 node4 dc3 1000.0 MB 246.1 MB (24.6%)
Zone redundancy: maximum
==== COMPUTATION OF A NEW PARTITION ASSIGNATION ====
Partitions are replicated 3 times on at least 3 distinct zones.
Optimal partition size: 3.9 MB (3.9 MB in previous layout)
Usable capacity / total cluster capacity: 3.0 GB / 4.0 GB (75.0 %)
Effective capacity (replication factor 3): 1000.0 MB
A total of 128 new copies of partitions need to be transferred.
dc1 Tags Partitions Capacity Usable capacity
b10c110e4e854e5a node1 256 (128 new) 1000.0 MB 1000.0 MB (100.0%)
TOTAL 256 (256 unique) 1000.0 MB 1000.0 MB (100.0%)
dc2 Tags Partitions Capacity Usable capacity
a235ac7695e0c54d node2 256 (0 new) 1000.0 MB 1000.0 MB (100.0%)
TOTAL 256 (256 unique) 1000.0 MB 1000.0 MB (100.0%)
dc3 Tags Partitions Capacity Usable capacity
62b218d848e86a64 node3 193 (0 new) 1000.0 MB 753.9 MB (75.4%)
a11c7cf18af29737 node4 63 (0 new) 1000.0 MB 246.1 MB (24.6%)
TOTAL 256 (256 unique) 2.0 GB 1000.0 MB (50.0%)
```
As we can see, the node that was moved to `dc3` (node4) is only used at 25% (approximatively),
whereas the node that was already in `dc3` (node3) is used at 75%.
This can be explained by the following:
- node1 will now be the only node remaining in `dc1`, thus it has to store all
of the data in the cluster. Since it was storing only half of it before, it has
to retrieve the other half from other nodes in the cluster.
- The data which it does not have is entirely stored by the other node that was
in `dc1` and that is now in `dc3` (node4). There is also a copy of it on node2
and node3 since both these nodes have a copy of everything.
- node3 and node4 are the two nodes that will now be in a datacenter that is
under-utilized (`dc3`), this means that those are the two candidates from which
data can be removed to be moved to node1.
- Garage will move data in equal proportions from all possible sources, in this
case it means that it will tranfer 25% of the entire data set from node3 to
node1 and another 25% from node4 to node1.
This explains why node3 ends with 75% utilization (100% from before minus 25%
that is moved to node1), and node4 ends with 25% (50% from before minus 25%
that is moved to node1).
This illustrates the second principle of the layout computation: **if there is
a choice in moving data out of some nodes, then all links between pairs of
nodes are used in equal proportions** (this is approximately true, there is
randomness in the algorithm to achieve this so there might be some small
fluctuations, as we see above).
+101
View File
@@ -0,0 +1,101 @@
+++
title = "Multi-HDD support"
weight = 15
+++
Since v0.9, Garage natively supports nodes that have several storage drives
for storing data blocks (not for metadata storage).
## Initial setup
To set up a new Garage storage node with multiple HDDs,
format and mount all your drives in different directories,
and use a Garage configuration as follows:
```toml
data_dir = [
{ path = "/path/to/hdd1", capacity = "2T" },
{ path = "/path/to/hdd2", capacity = "4T" },
]
```
Garage will automatically balance all blocks stored by the node
among the different specified directories, proportionnally to the
specified capacities.
## Updating the list of storage locations
If you add new storage locations to your `data_dir`,
Garage will not rebalance existing data between storage locations.
Newly written blocks will be balanced proportionnally to the specified capacities,
and existing data may be moved between drives to improve balancing,
but only opportunistically when a data block is re-written (e.g. an object
is re-uploaded, or an object with a duplicate block is uploaded).
To understand precisely what is happening, we need to dive in to how Garage
splits data among the different storage locations.
First of all, Garage divides the set of all possible block hashes
in a fixed number of slices (currently 1024), and assigns
to each slice a primary storage location among the specified data directories.
The number of slices having their primary location in each data directory
is proportionnal to the capacity specified in the config file.
When Garage receives a block to write, it will always write it in the primary
directory of the slice that contains its hash.
Now, to be able to not lose existing data blocks when storage locations
are added, Garage also keeps a list of secondary data directories
for all of the hash slices. Secondary data directories for a slice indicates
storage locations that once were primary directories for that slice, i.e. where
Garage knows that data blocks of that slice might be stored.
When Garage is requested to read a certain data block,
it will first look in the primary storage directory of its slice,
and if it doesn't find it there it goes through all of the secondary storage
locations until it finds it. This allows Garage to continue operating
normally when storage locations are added, without having to shuffle
files between drives to place them in the correct location.
This relatively simple strategy works well but does not ensure that data
is correctly balanced among drives according to their capacity.
To rebalance data, two strategies can be used:
- Lazy rebalancing: when a block is re-written (e.g. the object is re-uploaded),
Garage checks whether the existing copy is in the primary directory of the slice
or in a secondary directory. If the current copy is in a secondary directory,
Garage re-writes a copy in the primary directory and deletes the one from the
secondary directory. This might never end up rebalancing everything if there
are data blocks that are only read and never written.
- Active rebalancing: an operator of a Garage node can explicitly launch a repair
procedure that rebalances the data directories, moving all blocks to their
primary location. Once done, all secondary locations for all hash slices are
removed so that they won't be checked anymore when looking for a data block.
## Read-only storage locations
If you would like to move all data blocks from an existing data directory to one
or several new data directories, mark the old directory as read-only:
```toml
data_dir = [
{ path = "/path/to/old_data", read_only = true },
{ path = "/path/to/new_hdd1", capacity = "2T" },
{ path = "/path/to/new_hdd2", capacity = "4T" },
]
```
Garage will be able to read requested blocks from the read-only directory.
Garage will also move data out of the read-only directory either progressively
(lazy rebalancing) or if requested explicitly (active rebalancing).
Once an active rebalancing has finished, your read-only directory should be empty:
it might still contain subdirectories, but no data files. You can check that
it contains no files using:
```bash
find -type f /path/to/old_data # should not print anything
```
at which point it can be removed from the `data_dir` list in your config file.
+2 -2
View File
@@ -9,7 +9,7 @@ On a new version release, there is 2 possibilities:
- protocols and data structures remained the same ➡️ this is a **minor upgrade**
- protocols or data structures changed ➡️ this is a **major upgrade**
You can quickly now what type of update you will have to operate by looking at the version identifier:
You can quickly know what type of update you will have to operate by looking at the version identifier:
when we require our users to do a major upgrade, we will always bump the first nonzero component of the version identifier
(e.g. from v0.7.2 to v0.8.0).
Conversely, for versions that only require a minor upgrade, the first nonzero component will always stay the same (e.g. from v0.8.0 to v0.8.1).
@@ -80,6 +80,6 @@ The entire procedure would look something like this:
5. If any specific migration procedure is required, it is usually in one of the two cases:
- It can be run on online nodes after the new version has started, during regular cluster operation.
- it has to be run offline
- it has to be run offline, in which case you will have to again take all nodes offline one after the other to run the repair
For this last step, please refer to the specific documentation pertaining to the version upgrade you are doing.
+21 -16
View File
@@ -79,14 +79,14 @@ index = "index.html"
api_bind_addr = "[::]:3904"
[admin]
api_bind_addr = "0.0.0.0:3903"
api_bind_addr = "[::]:3903"
admin_token = "$(openssl rand -base64 32)"
metrics_token = "$(openssl rand -base64 32)"
EOF
```
Now that your configuration file has been created, you can put
it in the right place. By default, garage looks at **`/etc/garage.toml`.**
Now that your configuration file has been created, you may save it to the directory of your choice.
By default, Garage looks for **`/etc/garage.toml`.**
You can also store it somewhere else, but you will have to specify `-c path/to/garage.toml`
at each invocation of the `garage` binary (for example: `garage -c ./garage.toml server`, `garage -c ./garage.toml status`).
@@ -103,16 +103,19 @@ your data to be persisted properly.
### Launching the Garage server
Use the following command to launch the Garage server with our configuration file:
Use the following command to launch the Garage server:
```
garage server
garage -c path/to/garage.toml server
```
You can tune Garage's verbosity as follows (from less verbose to more verbose):
If you have placed the `garage.toml` file in `/etc` (its default location), you can simply run `garage server`.
```
RUST_LOG=garage=info garage server
You can tune Garage's verbosity by setting the `RUST_LOG=` environment variable. \
Available log levels are (from less verbose to more verbose): `error`, `warn`, `info` *(default)*, `debug` and `trace`.
```bash
RUST_LOG=garage=info garage server # default
RUST_LOG=garage=debug garage server
RUST_LOG=garage=trace garage server
```
@@ -126,7 +129,7 @@ Log level `debug` can help you check why your S3 API calls are not working.
The `garage` utility is also used as a CLI tool to configure your Garage deployment.
It uses values from the TOML configuration file to find the Garage daemon running on the
local node, therefore if your configuration file is not at `/etc/garage.toml` you will
again have to specify `-c path/to/garage.toml`.
again have to specify `-c path/to/garage.toml` at each invocation.
If the `garage` CLI is able to correctly detect the parameters of your local Garage node,
the following command should be enough to show the status of your cluster:
@@ -140,7 +143,7 @@ This should show something like this:
```
==== HEALTHY NODES ====
ID Hostname Address Tag Zone Capacity
563e1ac825ee3323 linuxbox 127.0.0.1:3901 NO ROLE ASSIGNED
563e1ac825ee3323 linuxbox 127.0.0.1:3901 NO ROLE ASSIGNED
```
## Creating a cluster layout
@@ -153,12 +156,12 @@ For our test deployment, we are using only one node. The way in which we configu
it does not matter, you can simply write:
```bash
garage layout assign -z dc1 -c 1 <node_id>
garage layout assign -z dc1 -c 1G <node_id>
```
where `<node_id>` corresponds to the identifier of the node shown by `garage status` (first column).
You can enter simply a prefix of that identifier.
For instance here you could write just `garage layout assign -z dc1 -c 1 563e`.
For instance here you could write just `garage layout assign -z dc1 -c 1G 563e`.
The layout then has to be applied to the cluster, using:
@@ -248,7 +251,7 @@ garage bucket info nextcloud-bucket
```
## Uploading and downlading from Garage
## Uploading and downloading from Garage
To download and upload files on garage, we can use a third-party tool named `awscli`.
@@ -269,12 +272,14 @@ named `~/.awsrc` with this content:
export AWS_ACCESS_KEY_ID=xxxx # put your Key ID here
export AWS_SECRET_ACCESS_KEY=xxxx # put your Secret key here
export AWS_DEFAULT_REGION='garage'
export AWS_ENDPOINT='http://localhost:3900'
export AWS_ENDPOINT_URL='http://localhost:3900'
function aws { command aws --endpoint-url $AWS_ENDPOINT $@ ; }
aws --version
```
Note you need to have at least `awscli` `>=1.29.0` or `>=2.13.0`, otherwise you
need to specify `--endpoint-url` explicitly on each `awscli` invocation.
Now, each time you want to use `awscli` on this target, run:
```bash
+14 -9
View File
@@ -8,18 +8,21 @@ listen address is specified in the `[admin]` section of the configuration
file (see [configuration file
reference](@/documentation/reference-manual/configuration.md))
**WARNING.** At this point, there is no comittement to stability of the APIs described in this document.
We will bump the version numbers prefixed to each API endpoint at each time the syntax
**WARNING.** At this point, there is no commitment to the stability of the APIs described in this document.
We will bump the version numbers prefixed to each API endpoint each time the syntax
or semantics change, meaning that code that relies on these endpoint will break
when changes are introduced.
The Garage administration API was introduced in version 0.7.2, this document
does not apply to older versions of Garage.
Versions:
- Before Garage 0.7.2 - no admin API
- Garage 0.7.2 - admin APIv0
- Garage 0.9.0 - admin APIv1, deprecate admin APIv0
## Access control
The admin API uses two different tokens for acces control, that are specified in the config file's `[admin]` section:
The admin API uses two different tokens for access control, that are specified in the config file's `[admin]` section:
- `metrics_token`: the token for accessing the Metrics endpoint (if this token
is not set in the config file, the Metrics endpoint can be accessed without
@@ -85,8 +88,8 @@ Consult the full health check API endpoint at /v0/health for more details
### On-demand TLS `GET /check`
To prevent abuses for on-demand TLS, Caddy developpers have specified an endpoint that can be queried by the reverse proxy
to know if a given domain is allowed to get a certificate. Garage implements this endpoints to tell if a given domain is handled by Garage or is garbage.
To prevent abuse for on-demand TLS, Caddy developers have specified an endpoint that can be queried by the reverse proxy
to know if a given domain is allowed to get a certificate. Garage implements these endpoints to tell if a given domain is handled by Garage or is garbage.
Garage responds with the following logic:
- If the domain matches the pattern `<bucket-name>.<s3_api.root_domain>`, returns 200 OK
@@ -99,7 +102,7 @@ You must manually declare the domain in your reverse-proxy. Idem for K2V.*
*Note 2: buckets in a user's namespace are not supported yet by this endpoint. This is a limitation of this endpoint currently.*
**Example:** Suppose a Garage instance configured with `s3_api.root_domain = .s3.garage.localhost` and `s3_web.root_domain = .web.garage.localhost`.
**Example:** Suppose a Garage instance is configured with `s3_api.root_domain = .s3.garage.localhost` and `s3_web.root_domain = .web.garage.localhost`.
With a private `media` bucket (name in the global namespace, website is disabled), the endpoint will feature the following behavior:
@@ -131,7 +134,9 @@ $ curl -so /dev/null -w "%{http_code}" http://localhost:3903/check?domain=exampl
### Cluster operations
These endpoints are defined on a dedicated [Redocly page](https://garagehq.deuxfleurs.fr/api/garage-admin-v0.html). You can also download its [OpenAPI specification](https://garagehq.deuxfleurs.fr/api/garage-admin-v0.yml).
These endpoints have a dedicated OpenAPI spec.
- APIv1 - [HTML spec](https://garagehq.deuxfleurs.fr/api/garage-admin-v1.html) - [OpenAPI YAML](https://garagehq.deuxfleurs.fr/api/garage-admin-v1.yml)
- APIv0 (deprecated) - [HTML spec](https://garagehq.deuxfleurs.fr/api/garage-admin-v0.html) - [OpenAPI YAML](https://garagehq.deuxfleurs.fr/api/garage-admin-v0.yml)
Requesting the API from the command line can be as simple as running:
+275 -160
View File
@@ -8,6 +8,8 @@ weight = 20
Here is an example `garage.toml` configuration file that illustrates all of the possible options:
```toml
replication_mode = "3"
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
metadata_fsync = true
@@ -15,22 +17,22 @@ data_fsync = false
db_engine = "lmdb"
block_size = 1048576
block_size = "1M"
sled_cache_capacity = 134217728
sled_cache_capacity = "128MiB"
sled_flush_every_ms = 2000
replication_mode = "3"
lmdb_map_size = "1T"
compression_level = 1
rpc_secret = "4425f5c26c5e11581d3223904324dcb5b5d5dfb14e5e7f35e38c595424f5f1e6"
rpc_bind_addr = "[::]:3901"
rpc_bind_outgoing = false
rpc_public_addr = "[fc00:1::1]:3901"
bootstrap_peers = [
"563e1ac825ee3323aa441e72c26d1030d6d4414aeb3dd25287c531e7fc2bc95d@[fc00:1::1]:3901",
"86f0f26ae4afbd59aaf9cfb059eefac844951efd5b8caeec0d53f4ed6c85f332[fc00:1::2]:3901",
"86f0f26ae4afbd59aaf9cfb059eefac844951efd5b8caeec0d53f4ed6c85f332@[fc00:1::2]:3901",
"681456ab91350f92242e80a531a3ec9392cb7c974f72640112f90a600d7921a4@[fc00:B::1]:3901",
"212fd62eeaca72c122b45a7f4fa0f55e012aa5e24ac384a72a3016413fa724ff@[fc00:F::1]:3901",
]
@@ -67,8 +69,8 @@ root_domain = ".web.garage"
[admin]
api_bind_addr = "0.0.0.0:3903"
metrics_token = "cacce0b2de4bc2d9f5b5fdff551e01ac1496055aed248202d415398987e35f81"
admin_token = "ae8cb40ea7368bbdbb6430af11cca7da833d3458a5f52086f4e805a570fb5c2a"
metrics_token = "BCAdFjoa9G0KJR0WXnHHm7fs1ZAbfpI8iIZ+Z/a2NgI="
admin_token = "UkLeGWEvHnXBqnueR3ISEMWpOnm40jH2tM2HnnL/0F4="
trace_sink = "http://localhost:4317"
```
@@ -76,136 +78,62 @@ The following gives details about each available configuration option.
## Available configuration options
### `metadata_dir`
### Index
The directory in which Garage will store its metadata. This contains the node identifier,
the network configuration and the peer list, the list of buckets and keys as well
as the index of all objects, object version and object blocks.
Top-level configuration options:
[`block_size`](#block_size),
[`bootstrap_peers`](#bootstrap_peers),
[`compression_level`](#compression_level),
[`data_dir`](#data_dir),
[`data_fsync`](#data_fsync),
[`db_engine`](#db_engine),
[`lmdb_map_size`](#lmdb_map_size),
[`metadata_dir`](#metadata_dir),
[`metadata_fsync`](#metadata_fsync),
[`replication_mode`](#replication_mode),
[`rpc_bind_addr`](#rpc_bind_addr),
[`rpc_bind_outgoing`](#rpc_bind_outgoing),
[`rpc_public_addr`](#rpc_public_addr),
[`rpc_secret`/`rpc_secret_file`](#rpc_secret),
[`sled_cache_capacity`](#sled_cache_capacity),
[`sled_flush_every_ms`](#sled_flush_every_ms).
Store this folder on a fast SSD drive if possible to maximize Garage's performance.
The `[consul_discovery]` section:
[`api`](#consul_api),
[`ca_cert`](#consul_ca_cert),
[`client_cert`](#consul_client_cert_and_key),
[`client_key`](#consul_client_cert_and_key),
[`consul_http_addr`](#consul_http_addr),
[`meta`](#consul_tags_and_meta),
[`service_name`](#consul_service_name),
[`tags`](#consul_tags_and_meta),
[`tls_skip_verify`](#consul_tls_skip_verify),
[`token`](#consul_token).
### `data_dir`
The `[kubernetes_discovery]` section:
[`namespace`](#kube_namespace),
[`service_name`](#kube_service_name),
[`skip_crd`](#kube_skip_crd).
The directory in which Garage will store the data blocks of objects.
This folder can be placed on an HDD. The space available for `data_dir`
should be counted to determine a node's capacity
when [adding it to the cluster layout](@/documentation/cookbook/real-world.md).
The `[s3_api]` section:
[`api_bind_addr`](#s3_api_bind_addr),
[`root_domain`](#s3_root_domain),
[`s3_region`](#s3_region).
### `db_engine` (since `v0.8.0`)
The `[s3_web]` section:
[`bind_addr`](#web_bind_addr),
[`root_domain`](#web_root_domain).
By default, Garage uses the Sled embedded database library
to store its metadata on-disk. Since `v0.8.0`, Garage can use alternative storage backends as follows:
The `[admin]` section:
[`api_bind_addr`](#admin_api_bind_addr),
[`metrics_token`/`metrics_token_file`](#admin_metrics_token),
[`admin_token`/`admin_token_file`](#admin_token),
[`trace_sink`](#admin_trace_sink),
| DB engine | `db_engine` value | Database path |
| --------- | ----------------- | ------------- |
| [Sled](https://sled.rs) | `"sled"` | `<metadata_dir>/db/` |
| [LMDB](https://www.lmdb.tech) | `"lmdb"` | `<metadata_dir>/db.lmdb/` |
| [Sqlite](https://sqlite.org) | `"sqlite"` | `<metadata_dir>/db.sqlite` |
Performance characteristics of the different DB engines are as follows:
### Top-level configuration options
- Sled: the default database engine, which tends to produce
large data files and also has performance issues, especially when the metadata folder
is on a traditional HDD and not on SSD.
- LMDB: the recommended alternative on 64-bit systems,
much more space-efficiant and slightly faster. Note that the data format of LMDB is not portable
between architectures, so for instance the Garage database of an x86-64
node cannot be moved to an ARM64 node. Also note that, while LMDB can technically be used on 32-bit systems,
this will limit your node to very small database sizes due to how LMDB works; it is therefore not recommended.
- Sqlite: Garage supports Sqlite as a storage backend for metadata,
however it may have issues and is also very slow in its current implementation,
so it is not recommended to be used for now.
It is possible to convert Garage's metadata directory from one format to another with a small utility named `convert_db`,
which can be downloaded at the following locations:
[for amd64](https://garagehq.deuxfleurs.fr/_releases/convert_db/amd64/convert_db),
[for i386](https://garagehq.deuxfleurs.fr/_releases/convert_db/i386/convert_db),
[for arm64](https://garagehq.deuxfleurs.fr/_releases/convert_db/arm64/convert_db),
[for arm](https://garagehq.deuxfleurs.fr/_releases/convert_db/arm/convert_db).
The `convert_db` utility is used as folows:
```
convert-db -a <input db engine> -i <input db path> \
-b <output db engine> -o <output db path>
```
Make sure to specify the full database path as presented in the table above,
and not just the path to the metadata directory.
### `metadata_fsync`
Whether to enable synchronous mode for the database engine or not.
This is disabled (`false`) by default.
This reduces the risk of metadata corruption in case of power failures,
at the cost of a significant drop in write performance,
as Garage will have to pause to sync data to disk much more often
(several times for API calls such as PutObject).
Using this option reduces the risk of simultaneous metadata corruption on several
cluster nodes, which could lead to data loss.
If multi-site replication is used, this option is most likely not necessary, as
it is extremely unlikely that two nodes in different locations will have a
power failure at the exact same time.
(Metadata corruption on a single node is not an issue, the corrupted data file
can always be deleted and reconstructed from the other nodes in the cluster.)
Here is how this option impacts the different database engines:
| Database | `metadata_fsync = false` (default) | `metadata_fsync = true` |
|----------|------------------------------------|-------------------------------|
| Sled | default options | *unsupported* |
| Sqlite | `PRAGMA synchronous = OFF` | `PRAGMA synchronous = NORMAL` |
| LMDB | `MDB_NOMETASYNC` + `MDB_NOSYNC` | `MDB_NOMETASYNC` |
Note that the Sqlite database is always ran in `WAL` mode (`PRAGMA journal_mode = WAL`).
### `data_fsync`
Whether to `fsync` data blocks and their containing directory after they are
saved to disk.
This is disabled (`false`) by default.
This might reduce the risk that a data block is lost in rare
situations such as simultaneous node losing power,
at the cost of a moderate drop in write performance.
Similarly to `metatada_fsync`, this is likely not necessary
if geographical replication is used.
### `block_size`
Garage splits stored objects in consecutive chunks of size `block_size`
(except the last one which might be smaller). The default size is 1MB and
should work in most cases. We recommend increasing it to e.g. 10MB if
you are using Garage to store large files and have fast network connections
between all nodes (e.g. 1gbps).
If you are interested in tuning this, feel free to do so (and remember to
report your findings to us!). When this value is changed for a running Garage
installation, only files newly uploaded will be affected. Previously uploaded
files will remain available. This however means that chunks from existing files
will not be deduplicated with chunks from newly uploaded files, meaning you
might use more storage space that is optimally possible.
### `sled_cache_capacity`
This parameter can be used to tune the capacity of the cache used by
[sled](https://sled.rs), the database Garage uses internally to store metadata.
Tune this to fit the RAM you wish to make available to your Garage instance.
This value has a conservative default (128MB) so that Garage doesn't use too much
RAM by default, but feel free to increase this for higher performance.
### `sled_flush_every_ms`
This parameters can be used to tune the flushing interval of sled.
Increase this if sled is thrashing your SSD, at the risk of losing more data in case
of a power outage (though this should not matter much as data is replicated on other
nodes). The default value, 2000ms, should be appropriate for most use cases.
### `replication_mode`
#### `replication_mode` {#replication_mode}
Garage supports the following replication modes:
@@ -288,7 +216,160 @@ to the cluster while rebalancing is in progress. In theory, no data should be
lost as rebalancing is a routine operation for Garage, although we cannot
guarantee you that everything will go right in such an extreme scenario.
### `compression_level`
#### `metadata_dir` {#metadata_dir}
The directory in which Garage will store its metadata. This contains the node identifier,
the network configuration and the peer list, the list of buckets and keys as well
as the index of all objects, object version and object blocks.
Store this folder on a fast SSD drive if possible to maximize Garage's performance.
#### `data_dir` {#data_dir}
The directory in which Garage will store the data blocks of objects.
This folder can be placed on an HDD. The space available for `data_dir`
should be counted to determine a node's capacity
when [adding it to the cluster layout](@/documentation/cookbook/real-world.md).
Since `v0.9.0`, Garage supports multiple data directories with the following syntax:
```toml
data_dir = [
{ path = "/path/to/old_data", read_only = true },
{ path = "/path/to/new_hdd1", capacity = "2T" },
{ path = "/path/to/new_hdd2", capacity = "4T" },
]
```
See [the dedicated documentation page](@/documentation/operations/multi-hdd.md)
on how to operate Garage in such a setup.
#### `db_engine` (since `v0.8.0`) {#db_engine}
Since `v0.8.0`, Garage can use alternative storage backends as follows:
| DB engine | `db_engine` value | Database path |
| --------- | ----------------- | ------------- |
| [LMDB](https://www.lmdb.tech) (default since `v0.9.0`) | `"lmdb"` | `<metadata_dir>/db.lmdb/` |
| [Sled](https://sled.rs) (default up to `v0.8.0`) | `"sled"` | `<metadata_dir>/db/` |
| [Sqlite](https://sqlite.org) | `"sqlite"` | `<metadata_dir>/db.sqlite` |
Sled was the only database engine up to Garage v0.7.0. Performance issues and
API limitations of Sled prompted the addition of alternative engines in v0.8.0.
Since v0.9.0, LMDB is the default engine instead of Sled, and Sled is
deprecated. We plan to remove Sled in Garage v1.0.
Performance characteristics of the different DB engines are as follows:
- Sled: tends to produce large data files and also has performance issues,
especially when the metadata folder is on a traditional HDD and not on SSD.
- LMDB: the recommended database engine on 64-bit systems, much more
space-efficient and slightly faster. Note that the data format of LMDB is not
portable between architectures, so for instance the Garage database of an
x86-64 node cannot be moved to an ARM64 node. Also note that, while LMDB can
technically be used on 32-bit systems, this will limit your node to very
small database sizes due to how LMDB works; it is therefore not recommended.
- Sqlite: Garage supports Sqlite as an alternative storage backend for
metadata, and although it has not been tested as much, it is expected to work
satisfactorily. Since Garage v0.9.0, performance issues have largely been
fixed by allowing for a no-fsync mode (see `metadata_fsync`). Sqlite does not
have the database size limitation of LMDB on 32-bit systems.
It is possible to convert Garage's metadata directory from one format to another
using the `garage convert-db` command, which should be used as follows:
```
garage convert-db -a <input db engine> -i <input db path> \
-b <output db engine> -o <output db path>
```
Make sure to specify the full database path as presented in the table above
(third colummn), and not just the path to the metadata directory.
#### `metadata_fsync` {#metadata_fsync}
Whether to enable synchronous mode for the database engine or not.
This is disabled (`false`) by default.
This reduces the risk of metadata corruption in case of power failures,
at the cost of a significant drop in write performance,
as Garage will have to pause to sync data to disk much more often
(several times for API calls such as PutObject).
Using this option reduces the risk of simultaneous metadata corruption on several
cluster nodes, which could lead to data loss.
If multi-site replication is used, this option is most likely not necessary, as
it is extremely unlikely that two nodes in different locations will have a
power failure at the exact same time.
(Metadata corruption on a single node is not an issue, the corrupted data file
can always be deleted and reconstructed from the other nodes in the cluster.)
Here is how this option impacts the different database engines:
| Database | `metadata_fsync = false` (default) | `metadata_fsync = true` |
|----------|------------------------------------|-------------------------------|
| Sled | default options | *unsupported* |
| Sqlite | `PRAGMA synchronous = OFF` | `PRAGMA synchronous = NORMAL` |
| LMDB | `MDB_NOMETASYNC` + `MDB_NOSYNC` | `MDB_NOMETASYNC` |
Note that the Sqlite database is always ran in `WAL` mode (`PRAGMA journal_mode = WAL`).
#### `data_fsync` {#data_fsync}
Whether to `fsync` data blocks and their containing directory after they are
saved to disk.
This is disabled (`false`) by default.
This might reduce the risk that a data block is lost in rare
situations such as simultaneous node losing power,
at the cost of a moderate drop in write performance.
Similarly to `metatada_fsync`, this is likely not necessary
if geographical replication is used.
#### `block_size` {#block_size}
Garage splits stored objects in consecutive chunks of size `block_size`
(except the last one which might be smaller). The default size is 1MiB and
should work in most cases. We recommend increasing it to e.g. 10MiB if
you are using Garage to store large files and have fast network connections
between all nodes (e.g. 1gbps).
If you are interested in tuning this, feel free to do so (and remember to
report your findings to us!). When this value is changed for a running Garage
installation, only files newly uploaded will be affected. Previously uploaded
files will remain available. This however means that chunks from existing files
will not be deduplicated with chunks from newly uploaded files, meaning you
might use more storage space that is optimally possible.
#### `sled_cache_capacity` {#sled_cache_capacity}
This parameter can be used to tune the capacity of the cache used by
[sled](https://sled.rs), the database Garage uses internally to store metadata.
Tune this to fit the RAM you wish to make available to your Garage instance.
This value has a conservative default (128MB) so that Garage doesn't use too much
RAM by default, but feel free to increase this for higher performance.
#### `sled_flush_every_ms` {#sled_flush_every_ms}
This parameters can be used to tune the flushing interval of sled.
Increase this if sled is thrashing your SSD, at the risk of losing more data in case
of a power outage (though this should not matter much as data is replicated on other
nodes). The default value, 2000ms, should be appropriate for most use cases.
#### `lmdb_map_size` {#lmdb_map_size}
This parameters can be used to set the map size used by LMDB,
which is the size of the virtual memory region used for mapping the database file.
The value of this parameter is the maximum size the metadata database can take.
This value is not bound by the physical RAM size of the machine running Garage.
If not specified, it defaults to 1GiB on 32-bit machines and 1TiB on 64-bit machines.
#### `compression_level` {#compression_level}
Zstd compression level to use for storing blocks.
@@ -312,7 +393,7 @@ Compression is done synchronously, setting a value too high will add latency to
This value can be different between nodes, compression is done by the node which receive the
API call.
### `rpc_secret`, `rpc_secret_file` or `GARAGE_RPC_SECRET` (env)
#### `rpc_secret`, `rpc_secret_file` or `GARAGE_RPC_SECRET`, `GARAGE_RPC_SECRET_FILE` (env) {#rpc_secret}
Garage uses a secret key, called an RPC secret, that is shared between all
nodes of the cluster in order to identify these nodes and allow them to
@@ -324,7 +405,10 @@ Since Garage `v0.8.2`, the RPC secret can also be stored in a file whose path is
given in the configuration variable `rpc_secret_file`, or specified as an
environment variable `GARAGE_RPC_SECRET`.
### `rpc_bind_addr`
Since Garage `v0.8.5` and `v0.9.1`, you can also specify the path of a file
storing the secret as the `GARAGE_RPC_SECRET_FILE` environment variable.
#### `rpc_bind_addr` {#rpc_bind_addr}
The address and port on which to bind for inter-cluster communcations
(reffered to as RPC for remote procedure calls).
@@ -333,14 +417,25 @@ the node, even in the case of a NAT: the NAT should be configured to forward the
port number to the same internal port nubmer. This means that if you have several nodes running
behind a NAT, they should each use a different RPC port number.
### `rpc_public_addr`
#### `rpc_bind_outgoing`(since v0.9.2) {#rpc_bind_outgoing}
If enabled, pre-bind all sockets for outgoing connections to the same IP address
used for listening (the IP address specified in `rpc_bind_addr`) before
trying to connect to remote nodes.
This can be necessary if a node has multiple IP addresses,
but only one is allowed or able to reach the other nodes,
for instance due to firewall rules or specific routing configuration.
Disabled by default.
#### `rpc_public_addr` {#rpc_public_addr}
The address and port that other nodes need to use to contact this node for
RPC calls. **This parameter is optional but recommended.** In case you have
a NAT that binds the RPC port to a port that is different on your public IP,
this field might help making it work.
### `bootstrap_peers`
#### `bootstrap_peers` {#bootstrap_peers}
A list of peer identifiers on which to contact other Garage peers of this cluster.
These peer identifiers have the following syntax:
@@ -356,43 +451,54 @@ be obtained by running `garage node id` and then included directly in the
key will be returned by `garage node id` and you will have to add the IP
yourself.
### `allow_world_readable_secrets`
## The `[consul_discovery]` section
Garage checks the permissions of your secret files to make sure they're not
world-readable. In some cases, the check might fail and consider your files as
world-readable even if they're not, for instance when using Posix ACLs.
Setting `allow_world_readable_secrets` to `true` bypass this
permission verification.
Alternatively, you can set the `GARAGE_ALLOW_WORLD_READABLE_SECRETS`
environment variable to `true` to bypass the permissions check.
### The `[consul_discovery]` section
Garage supports discovering other nodes of the cluster using Consul. For this
to work correctly, nodes need to know their IP address by which they can be
reached by other nodes of the cluster, which should be set in `rpc_public_addr`.
### `consul_http_addr` and `service_name`
#### `consul_http_addr` {#consul_http_addr}
The `consul_http_addr` parameter should be set to the full HTTP(S) address of the Consul server.
### `api`
#### `api` {#consul_api}
Two APIs for service registration are supported: `catalog` and `agent`. `catalog`, the default, will register a service using
the `/v1/catalog` endpoints, enabling mTLS if `client_cert` and `client_key` are provided. The `agent` API uses the
`v1/agent` endpoints instead, where an optional `token` may be provided.
### `service_name`
#### `service_name` {#consul_service_name}
`service_name` should be set to the service name under which Garage's
RPC ports are announced.
### `client_cert`, `client_key`
#### `client_cert`, `client_key` {#consul_client_cert_and_key}
TLS client certificate and client key to use when communicating with Consul over TLS. Both are mandatory when doing so.
Only available when `api = "catalog"`.
### `ca_cert`
#### `ca_cert` {#consul_ca_cert}
TLS CA certificate to use when communicating with Consul over TLS.
### `tls_skip_verify`
#### `tls_skip_verify` {#consul_tls_skip_verify}
Skip server hostname verification in TLS handshake.
`ca_cert` is ignored when this is set.
### `token`
#### `token` {#consul_token}
Uses the provided token for communication with Consul. Only available when `api = "agent"`.
The policy assigned to this token should at least have these rules:
@@ -412,47 +518,49 @@ node_prefix "" {
}
```
### `tags` and `meta`
#### `tags` and `meta` {#consul_tags_and_meta}
Additional list of tags and map of service meta to add during service registration.
## The `[kubernetes_discovery]` section
### The `[kubernetes_discovery]` section
Garage supports discovering other nodes of the cluster using kubernetes custom
resources. For this to work, a `[kubernetes_discovery]` section must be present
with at least the `namespace` and `service_name` parameters.
### `namespace`
#### `namespace` {#kube_namespace}
`namespace` sets the namespace in which the custom resources are
configured.
### `service_name`
#### `service_name` {#kube_service_name}
`service_name` is added as a label to the advertised resources to
filter them, to allow for multiple deployments in a single namespace.
### `skip_crd`
#### `skip_crd` {#kube_skip_crd}
`skip_crd` can be set to true to disable the automatic creation and
patching of the `garagenodes.deuxfleurs.fr` CRD. You will need to create the CRD
manually.
## The `[s3_api]` section
### The `[s3_api]` section
### `api_bind_addr`
#### `api_bind_addr` {#s3_api_bind_addr}
The IP and port on which to bind for accepting S3 API calls.
This endpoint does not suport TLS: a reverse proxy should be used to provide it.
### `s3_region`
Alternatively, since `v0.8.5`, a path can be used to create a unix socket with 0222 mode.
#### `s3_region` {#s3_region}
Garage will accept S3 API calls that are targetted to the S3 region defined here.
API calls targetted to other regions will fail with a AuthorizationHeaderMalformed error
message that redirects the client to the correct region.
### `root_domain` {#root_domain}
#### `root_domain` {#s3_root_domain}
The optional suffix to access bucket using vhost-style in addition to path-style request.
Note path-style requests are always enabled, whether or not vhost-style is configured.
@@ -464,18 +572,20 @@ using the hostname `my-bucket.s3.garage.eu`.
## The `[s3_web]` section
### The `[s3_web]` section
Garage allows to publish content of buckets as websites. This section configures the
behaviour of this module.
### `bind_addr`
#### `bind_addr` {#web_bind_addr}
The IP and port on which to bind for accepting HTTP requests to buckets configured
for website access.
This endpoint does not suport TLS: a reverse proxy should be used to provide it.
### `root_domain`
Alternatively, since `v0.8.5`, a path can be used to create a unix socket with 0222 mode.
#### `root_domain` {#web_root_domain}
The optional suffix appended to bucket names for the corresponding HTTP Host.
@@ -484,39 +594,44 @@ will be accessible either with hostname `deuxfleurs.fr.web.garage.eu`
or with hostname `deuxfleurs.fr`.
## The `[admin]` section
### The `[admin]` section
Garage has a few administration capabilities, in particular to allow remote monitoring. These features are detailed below.
### `api_bind_addr`
#### `api_bind_addr` {#admin_api_bind_addr}
If specified, Garage will bind an HTTP server to this port and address, on
which it will listen to requests for administration features.
See [administration API reference](@/documentation/reference-manual/admin-api.md) to learn more about these features.
### `metrics_token`, `metrics_token_file` or `GARAGE_METRICS_TOKEN` (env)
Alternatively, since `v0.8.5`, a path can be used to create a unix socket. Note that for security reasons,
the socket will have 0220 mode. Make sure to set user and group permissions accordingly.
#### `metrics_token`, `metrics_token_file` or `GARAGE_METRICS_TOKEN`, `GARAGE_METRICS_TOKEN_FILE` (env) {#admin_metrics_token}
The token for accessing the Metrics endpoint. If this token is not set, the
Metrics endpoint can be accessed without access control.
You can use any random string for this value. We recommend generating a random token with `openssl rand -hex 32`.
You can use any random string for this value. We recommend generating a random token with `openssl rand -base64 32`.
`metrics_token` was introduced in Garage `v0.7.2`.
`metrics_token_file` and the `GARAGE_METRICS_TOKEN` environment variable are supported since Garage `v0.8.2`.
`GARAGE_METRICS_TOKEN_FILE` is supported since `v0.8.5` / `v0.9.1`.
### `admin_token`, `admin_token_file` or `GARAGE_ADMIN_TOKEN` (env)
#### `admin_token`, `admin_token_file` or `GARAGE_ADMIN_TOKEN`, `GARAGE_ADMIN_TOKEN_FILE` (env) {#admin_token}
The token for accessing all of the other administration endpoints. If this
token is not set, access to these endpoints is disabled entirely.
You can use any random string for this value. We recommend generating a random token with `openssl rand -hex 32`.
You can use any random string for this value. We recommend generating a random token with `openssl rand -base64 32`.
`admin_token` was introduced in Garage `v0.7.2`.
`admin_token_file` and the `GARAGE_ADMIN_TOKEN` environment variable are supported since Garage `v0.8.2`.
`GARAGE_ADMIN_TOKEN_FILE` is supported since `v0.8.5` / `v0.9.1`.
### `trace_sink`
#### `trace_sink` {#admin_trace_sink}
Optionally, the address of an OpenTelemetry collector. If specified,
Garage will send traces in the OpenTelemetry format to this endpoint. These
+15 -7
View File
@@ -37,6 +37,21 @@ A Garage cluster can very easily evolve over time, as storage nodes are added or
Garage will automatically rebalance data between nodes as needed to ensure the desired number of copies.
Read about cluster layout management [here](@/documentation/operations/layout.md).
### Several replication modes
Garage supports a variety of replication modes, with 1 copy, 2 copies or 3 copies of your data,
and with various levels of consistency, in order to adapt to a variety of usage scenarios.
Read our reference page on [supported replication modes](@/documentation/reference-manual/configuration.md#replication_mode)
to select the replication mode best suited to your use case (hint: in most cases, `replication_mode = "3"` is what you want).
### Compression and deduplication
All data stored in Garage is deduplicated, and optionnally compressed using
Zstd. Objects uploaded to Garage are chunked in blocks of constant sizes (see
[`block_size`](@/documentation/reference-manual/configuration.md#block_size)),
and the hashes of individual blocks are used to dispatch them to storage nodes
and to deduplicate them.
### No RAFT slowing you down
It might seem strange to tout the absence of something as a desirable feature,
@@ -48,13 +63,6 @@ As a consequence, requests can be handled much faster, even in cases where laten
between cluster nodes is important (see our [benchmarks](@/documentation/design/benchmarks/index.md) for data on this).
This is particularly usefull when nodes are far from one another and talk to one other through standard Internet connections.
### Several replication modes
Garage supports a variety of replication modes, with 1 copy, 2 copies or 3 copies of your data,
and with various levels of consistency, in order to adapt to a variety of usage scenarios.
Read our reference page on [supported replication modes](@/documentation/reference-manual/configuration.md#replication-mode)
to select the replication mode best suited to your use case (hint: in most cases, `replication_mode = "3"` is what you want).
### Web server for static websites
A storage bucket can easily be configured to be served directly by Garage as a static web site.
+106
View File
@@ -27,6 +27,112 @@ Exposes the Garage replication factor configured on the node
garage_replication_factor 3
```
#### `garage_local_disk_avail` and `garage_local_disk_total` (gauge)
Reports the available and total disk space on each node, for data and metadata separately.
```
garage_local_disk_avail{volume="data"} 540341960704
garage_local_disk_avail{volume="metadata"} 540341960704
garage_local_disk_total{volume="data"} 763063566336
garage_local_disk_total{volume="metadata"} 763063566336
```
### Cluster health status metrics
#### `cluster_healthy` (gauge)
Whether all storage nodes are connected (0 or 1)
```
cluster_healthy 0
```
#### `cluster_available` (gauge)
Whether all requests can be served, even if some storage nodes are disconnected
```
cluster_available 1
```
#### `cluster_connected_nodes` (gauge)
Number of nodes currently connected
```
cluster_connected_nodes 3
```
#### `cluster_known_nodes` (gauge)
Number of nodes already seen once in the cluster
```
cluster_known_nodes 3
```
#### `cluster_layout_node_connected` (gauge)
Connection status for individual nodes of the cluster layout
```
cluster_layout_node_connected{id="62b218d848e86a64",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 1
cluster_layout_node_connected{id="a11c7cf18af29737",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 0
cluster_layout_node_connected{id="a235ac7695e0c54d",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 1
cluster_layout_node_connected{id="b10c110e4e854e5a",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 1
```
#### `cluster_layout_node_disconnected_time` (gauge)
Time (in seconds) since last connection to individual nodes of the cluster layout
```
cluster_layout_node_disconnected_time{id="62b218d848e86a64",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 0
cluster_layout_node_disconnected_time{id="a235ac7695e0c54d",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 0
cluster_layout_node_disconnected_time{id="b10c110e4e854e5a",role_capacity="1000000000",role_gateway="0",role_zone="dc1"} 0
```
#### `cluster_storage_nodes` (gauge)
Number of storage nodes declared in the current layout
```
cluster_storage_nodes 4
```
#### `cluster_storage_nodes_ok` (gauge)
Number of storage nodes currently connected
```
cluster_storage_nodes_ok 3
```
#### `cluster_partitions` (gauge)
Number of partitions in the layout (this is always 256)
```
cluster_partitions 256
```
#### `cluster_partitions_all_ok` (gauge)
Number of partitions for which all storage nodes are connected
```
cluster_partitions_all_ok 64
```
#### `cluster_partitions_quorum` (gauge)
Number of partitions for which we have a quorum of connected nodes and all requests can be served
```
cluster_partitions_quorum 256
```
### Metrics of the API endpoints
#### `api_admin_request_counter` (counter)
+18 -14
View File
@@ -75,16 +75,13 @@ but these endpoints are documented in [Red Hat Ceph Storage - Chapter 2. Ceph Ob
| Endpoint | Garage | [Openstack Swift](https://docs.openstack.org/swift/latest/s3_compat.html) | [Ceph Object Gateway](https://docs.ceph.com/en/latest/radosgw/s3/) | [Riak CS](https://docs.riak.com/riak/cs/2.1.1/references/apis/storage/s3/index.html) | [OpenIO](https://docs.openio.io/latest/source/arch-design/s3_compliancy.html) |
|------------------------------|----------------------------------|-----------------|---------------|---------|-----|
| [AbortMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) | ✅ Implemented (see details below) | ✅ | ✅ | ✅ | ✅ |
| [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) | ✅ Implemented | ✅| ✅ | ✅ | ✅ |
| [ListMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUpload.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) | ✅ Implemented (see details below) | ✅ | ✅| ✅ | ✅ |
| [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
Our implementation of Multipart Upload is currently a bit more restrictive than Amazon's one in some edge cases.
For more information, please refer to our [issue tracker](https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/204).
| [AbortMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) | ✅ Implemented | ✅| ✅ | ✅ | ✅ |
| [ListMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUpload.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
| [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) | ✅ Implemented | ✅ | ✅| ✅ | ✅ |
| [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) | ✅ Implemented | ✅ | ✅ | ✅ | ✅ |
### Website endpoints
@@ -127,15 +124,22 @@ If you need this feature, please [share your use case in our dedicated issue](ht
| Endpoint | Garage | [Openstack Swift](https://docs.openstack.org/swift/latest/s3_compat.html) | [Ceph Object Gateway](https://docs.ceph.com/en/latest/radosgw/s3/) | [Riak CS](https://docs.riak.com/riak/cs/2.1.1/references/apis/storage/s3/index.html) | [OpenIO](https://docs.openio.io/latest/source/arch-design/s3_compliancy.html) |
|------------------------------|----------------------------------|-----------------|---------------|---------|-----|
| [DeleteBucketLifecycle](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) | ❌ Missing | ❌| ✅| ❌| ✅|
| [GetBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) | ❌ Missing | ❌| ✅ | ❌| ✅|
| [PutBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) | ❌ Missing | ❌| ✅ | ❌| ✅|
| [DeleteBucketLifecycle](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) | ✅ Implemented | ❌| ✅| ❌| ✅|
| [GetBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) | ✅ Implemented | ❌| ✅ | ❌| ✅|
| [PutBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) | ⚠ Partially implemented (see below) | ❌| ✅ | ❌| ✅|
| [GetBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) | ❌ Stub (see below) | ✅| ✅ | ❌| ✅|
| [ListObjectVersions](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html) | ❌ Missing | ❌| ✅ | ❌| ✅|
| [PutBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) | ❌ Missing | ❌| ✅| ❌| ✅|
**PutBucketLifecycleConfiguration:** The only actions supported are
`AbortIncompleteMultipartUpload` and `Expiration` (without the
`ExpiredObjectDeleteMarker` field). All other operations are dependent on
either bucket versionning or storage classes which Garage currently does not
implement. The deprecated `Prefix` member directly in the the `Rule`
structure/XML tag is not supported, specified prefixes must be inside the
`Filter` structure/XML tag.
**GetBucketVersioning:** Stub implementation (Garage does not yet support versionning so this always returns "versionning not enabled").
**GetBucketVersioning:** Stub implementation which always returns "versionning not enabled", since Garage does not yet support bucket versionning.
### Replication endpoints
@@ -0,0 +1,72 @@
+++
title = "Migrating from 0.8 to 0.9"
weight = 12
+++
**This guide explains how to migrate to 0.9 if you have an existing 0.8 cluster.
We don't recommend trying to migrate to 0.9 directly from 0.7 or older.**
This migration procedure has been tested on several clusters without issues.
However, it is still a *critical procedure* that might cause issues.
**Make sure to back up all your data before attempting it!**
You might also want to read our [general documentation on upgrading Garage](@/documentation/operations/upgrading.md).
The following are **breaking changes** in Garage v0.9 that require your attention when migrating:
- LMDB is now the default metadata db engine and Sled is deprecated. If you were using Sled, make sure to specify `db_engine = "sled"` in your configuration file, or take the time to [convert your database](https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#db-engine-since-v0-8-0).
- Capacity values are now in actual byte units. The translation from the old layout will assign 1 capacity = 1Gb by default, which might be wrong for your cluster. This does not cause any data to be moved around, but you might want to re-assign correct capacity values post-migration.
- Multipart uploads that were started in Garage v0.8 will not be visible in Garage v0.9 and will have to be restarted from scratch.
- Changes to the admin API: some `v0/` endpoints have been replaced by `v1/` counterparts with updated/uniformized syntax. All other endpoints have also moved to `v1/` by default, without syntax changes, but are still available under `v0/` for compatibility.
## Simple migration procedure (takes cluster offline for a while)
The migration steps are as follows:
1. Disable API and web access. You may do this by stopping your reverse proxy or by commenting out
the `api_bind_addr` values in your `config.toml` file and restarting Garage.
2. Do `garage repair --all-nodes --yes tables` and `garage repair --all-nodes --yes blocks`,
check the logs and check that all data seems to be synced correctly between
nodes. If you have time, do additional checks (`versions`, `block_refs`, etc.)
3. Check that the block resync queue and Merkle queue are empty:
run `garage stats -a` to query them or inspect metrics in the Grafana dashboard.
4. Turn off Garage v0.8
5. **Backup the metadata folder of all your nodes!** For instance, use the following command
if your metadata directory is `/var/lib/garage/meta`: `cd /var/lib/garage ; tar -acf meta-v0.8.tar.zst meta/`
6. Install Garage v0.9
7. Update your configuration file if necessary.
8. Turn on Garage v0.9
9. Do `garage repair --all-nodes --yes tables` and `garage repair --all-nodes --yes blocks`.
Wait for a full table sync to run.
10. Your upgraded cluster should be in a working state. Re-enable API and Web
access and check that everything went well.
11. Monitor your cluster in the next hours to see if it works well under your production load, report any issue.
12. You might want to assign correct capacity values to all your nodes. Doing so might cause data to be moved
in your cluster, which should also be monitored carefully.
## Minimal downtime migration procedure
The migration to Garage v0.9 can be done with almost no downtime,
by restarting all nodes at once in the new version.
The migration steps are as follows:
1. Do `garage repair --all-nodes --yes tables` and `garage repair --all-nodes --yes blocks`,
check the logs and check that all data seems to be synced correctly between
nodes. If you have time, do additional checks (`versions`, `block_refs`, etc.)
2. Turn off each node individually; back up its metadata folder (see above); turn it back on again.
This will allow you to take a backup of all nodes without impacting global cluster availability.
You can do all nodes of a single zone at once as this does not impact the availability of Garage.
3. Prepare your binaries and configuration files for Garage v0.9
4. Shut down all v0.8 nodes simultaneously, and restart them all simultaneously in v0.9.
Use your favorite deployment tool (Ansible, Kubernetes, Nomad) to achieve this as fast as possible.
Garage v0.9 should be in a working state as soon as it starts.
5. Proceed with repair and monitoring as described in steps 9-12 above.
+4 -4
View File
@@ -8,9 +8,9 @@ listen address is specified in the `[admin]` section of the configuration
file (see [configuration file
reference](@/documentation/reference-manual/configuration.md))
**WARNING.** At this point, there is no comittement to stability of the APIs described in this document.
We will bump the version numbers prefixed to each API endpoint at each time the syntax
or semantics change, meaning that code that relies on these endpoint will break
**WARNING.** At this point, there is no commitment to the stability of the APIs described in this document.
We will bump the version numbers prefixed to each API endpoint each time the syntax
or semantics change, meaning that code that relies on these endpoints will break
when changes are introduced.
The Garage administration API was introduced in version 0.7.2, this document
@@ -19,7 +19,7 @@ does not apply to older versions of Garage.
## Access control
The admin API uses two different tokens for acces control, that are specified in the config file's `[admin]` section:
The admin API uses two different tokens for access control, that are specified in the config file's `[admin]` section:
- `metrics_token`: the token for accessing the Metrics endpoint (if this token
is not set in the config file, the Metrics endpoint can be accessed without
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.
+1
View File
@@ -0,0 +1 @@
.direnv/
+17
View File
@@ -0,0 +1,17 @@
*
!*.txt
!*.md
!assets
!.gitignore
!*.svg
!*.png
!*.jpg
!*.tex
!Makefile
!.gitignore
!assets/*.drawio.pdf
!talk.pdf
+34
View File
@@ -0,0 +1,34 @@
ASSETS=assets/consistent_hashing_1.pdf \
assets/consistent_hashing_2.pdf \
assets/consistent_hashing_3.pdf \
assets/consistent_hashing_4.pdf \
assets/garage_tables.pdf \
assets/consensus.pdf_tex \
assets/lattice1.pdf_tex \
assets/lattice2.pdf_tex \
assets/lattice3.pdf_tex \
assets/lattice4.pdf_tex \
assets/lattice5.pdf_tex \
assets/lattice6.pdf_tex \
assets/lattice7.pdf_tex \
assets/lattice8.pdf_tex \
assets/latticeB_1.pdf_tex \
assets/latticeB_2.pdf_tex \
assets/latticeB_3.pdf_tex \
assets/latticeB_4.pdf_tex \
assets/latticeB_5.pdf_tex \
assets/latticeB_6.pdf_tex \
assets/latticeB_7.pdf_tex \
assets/latticeB_8.pdf_tex \
assets/latticeB_9.pdf_tex \
assets/latticeB_10.pdf_tex \
assets/deuxfleurs.pdf
talk.pdf: talk.tex $(ASSETS)
pdflatex talk.tex
assets/%.pdf: assets/%.svg
inkscape -D -z --file=$^ --export-pdf=$@
assets/%.pdf_tex: assets/%.svg
inkscape -D -z --file=$^ --export-pdf=$@ --export-latex
+39
View File
@@ -0,0 +1,39 @@
### (fr) Garage, un système de stockage de données géo-distribué léger et robuste
Garage est un système de stockage de données léger, géo-distribué, qui
implémente le protocole de stockage S3 de Amazon. Garage est destiné
principalement à l'auto-hébergement sur du matériel courant d'occasion. À ce
titre, il doit tolérer un grand nombre de pannes: coupures de courant, coupures
de connexion Internet, pannes de machines, ... Il doit également être facile à
déployer et à maintenir, afin de pouvoir être facilement utilisé par des
amateurs ou des petites organisations.
Cette présentation vous proposera un aperçu de Garage et du choix technique
principal qui rend un système comme Garage possible: le refus d'utiliser des
algorithmes de consensus, remplacés avantageusement par des méthodes à
cohérence faible. Notre modèle est fortement inspiré de la base de donnée
Dynamo (DeCandia et al, 2007), et fait usage des types de données CRDT (Shapiro
et al, 2011). Nous exploreront comment ces méthodes s'appliquent à la
construction de l'abstraction "stockage objet" dans un système distribué, et
quelles autres abstractions peuvent ou ne peuvent pas être construites dans ce
modèle.
### (en) Garage, a lightweight and robust geo-distributed data storage system
Garage is a lightweight geo-distributed data store that implements the Amazon
S3 object storage protocol. Garage is meant primarily for self-hosting at home
on second-hand commodity hardware, meaning it has to tolerate a wide variety of
failure scenarios such as power cuts, Internet disconnections and machine
crashes. It also has to be easy to deploy and maintain, so that hobbyists and
small organizations can use it without trouble.
This talk will present Garage and the key technical choice that made Garage
possible: refusing to use consensus algorithms and using instead weak
consistency methods, with a model that is loosely based on that of the Dynamo
database (DeCandia et al, 2007) and that makes heavy use of conflict-free
replicated data types (Shapiro et al, 2011). We will explore how these methods
are suited to building the "object store" abstraction in a distributed system,
and what other abstractions are possible or impossible to build in this model.
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="800"
height="300"
viewBox="0 0 211.66666 79.374999"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="consensus.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="310.49139"
inkscape:cy="179.1688"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g1218"
transform="translate(-8.9161476,-12.502301)">
<circle
style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
id="path111"
cx="38.904896"
cy="37.936272"
r="13.474442" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="38.879501"
y="40.908073"
id="text1105"><tspan
sodipodi:role="line"
id="tspan1103"
style="stroke-width:0.264583;fill:#000000"
x="38.879501"
y="40.908073">$\bot$</tspan></text>
</g>
<g
id="g1218-3"
transform="translate(127.41938,-12.502301)">
<circle
style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
id="path111-5"
cx="38.904896"
cy="37.936272"
r="13.474442" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="38.879501"
y="40.908073"
id="text1105-6"><tspan
sodipodi:role="line"
id="tspan1103-2"
style="stroke-width:0.264583;fill:#000000"
x="38.879501"
y="40.908073">$x$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 44.289635,25.433971 H 145.90576"
id="path1414"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="92.729836"
y="21.781803"
id="text2092"><tspan
sodipodi:role="line"
id="tspan2090"
style="stroke-width:0.264583;fill:#000000"
x="92.729836"
y="21.781803">$propose(x) / x$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="166.29887"
y="69.89299"
id="text2092-9"><tspan
sodipodi:role="line"
id="tspan2090-1"
style="stroke-width:0.264583;fill:#000000"
x="166.29887"
y="69.89299">$propose(y) / x$</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="m 155.82329,35.899857 c -8.35129,12.319651 0.54055,24.640898 11.72797,24.072085 8.65403,-0.440005 18.59818,-11.705963 11.8146,-20.570891"
id="path2150"
sodipodi:nodetypes="csc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 53 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 54 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 57 KiB

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 70.424515 70.300102"
version="1.1"
id="svg8"
sodipodi:docname="logo.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
inkscape:export-filename="/home/quentin/Documents/dev/deuxfleurs/site/src/img/logo.png"
inkscape:export-xdpi="699.30194"
inkscape:export-ydpi="699.30194"
width="70.424515"
height="70.300102"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs12" />
<sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="12.125"
inkscape:cx="43.092783"
inkscape:cy="48.082474"
inkscape:window-width="3072"
inkscape:window-height="1659"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<g
id="g79969"
transform="translate(-0.827,34.992103)">
<path
fill="#ffffff"
d="m 15.632,34.661 c -0.799,-0.597 -1.498,-1.484 -2.035,-2.592 l -0.228,-0.47 -0.46,0.249 c -0.975,0.528 -1.913,0.858 -2.744,0.969 L 9.963,29.061 6.327,30.029 C 6.17,29.175 6.202,28.142 6.423,27.007 L 6.526,26.482 5.994,26.416 C 4.752,26.262 3.688,25.891 2.89,25.336 L 4.411,22.419 1.423,20.896 C 1.742,19.952 2.371,19.014 3.257,18.161 L 3.634,17.798 3.255,17.438 C 2.452,16.674 1.847,15.884 1.485,15.127 L 4.995,13.774 2.95,10.615 C 3.69,10.213 4.643,9.929 5.739,9.783 L 6.258,9.715 6.167,9.201 C 5.952,7.99 5.995,6.863 6.291,5.913 l 3.308,0.523 0.524,-3.308 c 0.988,0.013 2.08,0.326 3.164,0.907 L 13.749,4.283 13.975,3.81 C 14.454,2.807 15.019,1.986 15.628,1.406 L 18,4.326 20.372,1.406 c 0.609,0.58 1.175,1.401 1.653,2.404 l 0.226,0.473 0.462,-0.247 C 23.798,3.455 24.891,3.142 25.877,3.13 L 26.4,6.438 29.71,5.913 c 0.296,0.951 0.34,2.078 0.124,3.288 l -0.092,0.515 0.518,0.069 c 1.095,0.145 2.048,0.43 2.788,0.832 l -2.046,3.156 3.511,1.355 c -0.361,0.757 -0.966,1.547 -1.77,2.311 l -0.379,0.36 0.377,0.363 c 0.888,0.854 1.516,1.793 1.835,2.736 l -2.984,1.52 1.521,2.984 c -0.812,0.574 -1.871,0.964 -3.094,1.134 l -0.518,0.072 0.096,0.514 c 0.201,1.089 0.226,2.083 0.073,2.909 l -3.634,-0.97 -0.204,3.757 c -0.83,-0.11 -1.768,-0.44 -2.742,-0.968 l -0.459,-0.249 -0.228,0.47 c -0.539,1.107 -1.237,1.994 -2.036,2.591 L 18,32.293 Z"
id="path2" />
<path
d="M 7.092,10.678 C 6.562,9.189 6.394,7.708 6.66,6.478 l 2.368,0.375 0.987,0.156 0.157,-0.988 0.375,-2.368 C 11.808,3.78 13.16,4.396 14.409,5.359 14.527,5.022 14.653,4.696 14.791,4.392 13.24,3.257 11.568,2.629 10.061,2.629 9.938,2.629 9.816,2.633 9.695,2.642 L 9.184,5.865 5.96,5.354 C 5.36,6.841 5.395,8.769 6.045,10.747 6.38,10.71 6.729,10.686 7.092,10.678 Z M 21.593,5.359 c 1.248,-0.962 2.6,-1.578 3.86,-1.705 l 0.376,2.368 0.156,0.988 0.987,-0.157 2.369,-0.376 c 0.266,1.23 0.098,2.71 -0.432,4.2 0.361,0.009 0.711,0.032 1.046,0.07 C 30.606,8.769 30.64,6.841 30.04,5.353 L 26.815,5.865 26.304,2.641 c -0.12,-0.008 -0.242,-0.012 -0.365,-0.012 -1.507,0 -3.179,0.628 -4.73,1.762 0.14,0.306 0.266,0.631 0.384,0.968 z M 7.368,27 h 0.035 c 0.067,0 0.157,-0.604 0.26,-0.947 -0.098,0.004 -0.197,0.046 -0.294,0.046 -1.496,0 -2.826,-0.303 -3.83,-0.89 L 4.628,23.081 5.082,22.194 4.191,21.742 2.055,20.654 C 2.563,19.503 3.57,18.404 4.873,17.511 4.586,17.292 4.312,17.07 4.063,16.842 2.376,18.059 1.217,19.597 0.828,21.152 l 2.908,1.483 -1.482,2.843 C 3.475,26.501 5.303,27 7.368,27 Z m 27.806,-5.846 c -0.39,-1.555 -1.548,-3.093 -3.234,-4.311 -0.25,0.228 -0.523,0.451 -0.81,0.669 1.304,0.893 2.31,1.992 2.817,3.145 l -2.136,1.088 -0.891,0.453 0.454,0.892 1.089,2.137 c -1.004,0.587 -2.332,0.904 -3.828,0.904 -0.099,0 -0.199,-0.01 -0.299,-0.013 0.103,0.344 0.192,0.683 0.26,1.011 l 0.039,0.002 c 2.066,0 3.892,-0.563 5.112,-1.587 l -1.482,-2.908 z m -12.653,9.182 c -0.447,1.517 -1.181,2.812 -2.119,3.651 L 18.707,32.293 18,31.586 l -0.707,0.707 -1.695,1.694 c -0.938,-0.839 -1.673,-2.136 -2.12,-3.652 -0.296,0.206 -0.593,0.397 -0.886,0.563 0.636,1.98 1.741,3.559 3.1,4.409 L 18,33 l 2.308,2.308 c 1.358,-0.851 2.464,-2.428 3.101,-4.408 -0.295,-0.168 -0.591,-0.359 -0.888,-0.564 z"
fill="#ea596e"
id="path4" />
<path
fill="#ea596e"
d="m 20.118,5.683 c 0.426,1.146 0.748,2.596 0.841,4.284 l 0.2,3.683 3.564,-0.946 c 1.32,-0.351 2.655,-0.536 3.86,-0.536 0.16,0 0.318,0.003 0.474,0.01 l -1.827,2.819 3.139,1.211 c -0.958,0.759 -2.237,1.514 -3.814,2.123 l -3.441,1.328 2.001,3.099 c 0.918,1.42 1.509,2.782 1.838,3.96 L 23.709,25.853 23.527,29.21 C 22.508,28.533 21.395,27.55 20.329,26.237 L 18,23.374 15.672,26.236 c -1.066,1.312 -2.179,2.295 -3.198,2.972 l -0.18,-3.354 -3.248,0.864 c 0.329,-1.178 0.921,-2.54 1.839,-3.961 L 12.889,19.658 9.447,18.33 C 7.87,17.721 6.591,16.967 5.633,16.208 L 8.768,15 6.941,12.177 c 0.155,-0.006 0.313,-0.01 0.473,-0.01 1.206,0 2.541,0.185 3.861,0.536 l 3.564,0.947 0.202,-3.683 c 0.092,-1.688 0.415,-3.138 0.84,-4.284 L 18,8.292 20.118,5.683 M 20.308,0.692 18,3.533 15.692,0.692 C 13.703,2.224 12.271,5.684 12.046,9.804 10.429,9.374 8.854,9.167 7.414,9.167 c -2.11,0 -3.929,0.445 -5.161,1.289 l 1.989,3.073 -3.415,1.316 c 0.842,2.366 3.69,4.797 7.54,6.283 -2.241,3.465 -3.116,7.106 -2.407,9.516 l 3.537,-0.941 0.196,3.654 c 2.512,-0.07 5.703,-2.027 8.307,-5.228 2.603,3.201 5.796,5.158 8.306,5.228 l 0.198,-3.655 3.535,0.943 c 0.71,-2.411 -0.165,-6.05 -2.404,-9.517 3.849,-1.485 6.696,-3.918 7.538,-6.283 l -3.415,-1.318 1.99,-3.07 c -1.233,-0.844 -3.053,-1.29 -5.164,-1.29 -1.438,0 -3.013,0.207 -4.63,0.636 C 23.729,5.684 22.297,2.224 20.308,0.692 Z"
id="path6" />
</g>
<g
id="g79964"
transform="translate(-1.043816,35.993714)">
<path
fill="#ffffff"
d="m 51.92633,-2.0247139 c -0.799,-0.597 -1.498,-1.484 -2.035,-2.592 l -0.228,-0.47 -0.46,0.249 c -0.975,0.528 -1.913,0.858 -2.744,0.969 l -0.202,-3.7560001 -3.636,0.968 c -0.157,-0.854 -0.125,-1.887 0.096,-3.022 l 0.103,-0.525 -0.532,-0.066 c -1.242,-0.154 -2.306,-0.525 -3.104,-1.08 l 1.521,-2.917 -2.988,-1.523 c 0.319,-0.944 0.948,-1.882 1.834,-2.735 l 0.377,-0.363 -0.379,-0.36 c -0.803,-0.764 -1.408,-1.554 -1.77,-2.311 l 3.51,-1.353 -2.045,-3.159 c 0.74,-0.402 1.693,-0.686 2.789,-0.832 l 0.519,-0.068 -0.091,-0.514 c -0.215,-1.211 -0.172,-2.338 0.124,-3.288 l 3.308,0.523 0.524,-3.308 c 0.988,0.013 2.08,0.326 3.164,0.907 l 0.462,0.248 0.226,-0.473 c 0.479,-1.003 1.044,-1.824 1.653,-2.404 l 2.372,2.92 2.372,-2.92 c 0.609,0.58 1.175,1.401 1.653,2.404 l 0.226,0.473 0.462,-0.247 c 1.085,-0.581 2.178,-0.894 3.164,-0.906 l 0.523,3.308 3.31,-0.525 c 0.296,0.951 0.34,2.078 0.124,3.288 l -0.092,0.515 0.518,0.069 c 1.095,0.145 2.048,0.43 2.788,0.832 l -2.046,3.156 3.511,1.355 c -0.361,0.757 -0.966,1.547 -1.77,2.311 l -0.379,0.36 0.377,0.363 c 0.888,0.854 1.516,1.793 1.835,2.736 l -2.984,1.52 1.521,2.984 c -0.812,0.574 -1.871,0.964 -3.094,1.134 l -0.518,0.072 0.096,0.514 c 0.201,1.089 0.226,2.083 0.073,2.909 l -3.634,-0.97 -0.204,3.7570001 c -0.83,-0.11 -1.768,-0.44 -2.742,-0.968 l -0.459,-0.249 -0.228,0.47 c -0.539,1.107 -1.237,1.994 -2.036,2.591 l -2.367,-2.369 z"
id="path2-9" />
<path
d="m 43.38633,-26.007714 c -0.53,-1.489 -0.698,-2.97 -0.432,-4.2 l 2.368,0.375 0.987,0.156 0.157,-0.988 0.375,-2.368 c 1.261,0.127 2.613,0.743 3.862,1.706 0.118,-0.337 0.244,-0.663 0.382,-0.967 -1.551,-1.135 -3.223,-1.763 -4.73,-1.763 -0.123,0 -0.245,0.004 -0.366,0.013 l -0.511,3.223 -3.224,-0.511 c -0.6,1.487 -0.565,3.415 0.085,5.393 0.335,-0.037 0.684,-0.061 1.047,-0.069 z m 14.501,-5.319 c 1.248,-0.962 2.6,-1.578 3.86,-1.705 l 0.376,2.368 0.156,0.988 0.987,-0.157 2.369,-0.376 c 0.266,1.23 0.098,2.71 -0.432,4.2 0.361,0.009 0.711,0.032 1.046,0.07 0.651,-1.978 0.685,-3.906 0.085,-5.394 l -3.225,0.512 -0.511,-3.224 c -0.12,-0.008 -0.242,-0.012 -0.365,-0.012 -1.507,0 -3.179,0.628 -4.73,1.762 0.14,0.306 0.266,0.631 0.384,0.968 z m -14.225,21.641 h 0.035 c 0.067,0 0.157,-0.604 0.26,-0.947 -0.098,0.004 -0.197,0.046 -0.294,0.046 -1.496,0 -2.826,-0.303 -3.83,-0.89 l 1.089,-2.128 0.454,-0.887 -0.891,-0.452 -2.136,-1.088 c 0.508,-1.151 1.515,-2.25 2.818,-3.143 -0.287,-0.219 -0.561,-0.441 -0.81,-0.669 -1.687,1.217 -2.846,2.755 -3.235,4.31 l 2.908,1.483 -1.482,2.843 c 1.221,1.023 3.049,1.522 5.114,1.522 z m 27.806,-5.846 c -0.39,-1.555 -1.548,-3.093 -3.234,-4.311 -0.25,0.228 -0.523,0.451 -0.81,0.669 1.304,0.893 2.31,1.992 2.817,3.145 l -2.136,1.088 -0.891,0.453 0.454,0.892 1.089,2.137 c -1.004,0.587 -2.332,0.904 -3.828,0.904 -0.099,0 -0.199,-0.01 -0.299,-0.013 0.103,0.344 0.192,0.683 0.26,1.011 l 0.039,0.002 c 2.066,0 3.892,-0.563 5.112,-1.587 l -1.482,-2.908 z m -12.653,9.182 c -0.447,1.5170001 -1.181,2.8120001 -2.119,3.6510001 l -1.695,-1.694 -0.707,-0.707 -0.707,0.707 -1.695,1.694 c -0.938,-0.839 -1.673,-2.136 -2.12,-3.6520001 -0.296,0.2060001 -0.593,0.3970001 -0.886,0.5630001 0.636,1.98 1.741,3.559 3.1,4.409 l 2.308,-2.307 2.308,2.308 c 1.358,-0.851 2.464,-2.428 3.101,-4.408 -0.295,-0.168 -0.591,-0.359 -0.888,-0.5640001 z"
fill="#ea596e"
id="path4-3" />
<path
fill="#ea596e"
d="m 56.41233,-31.002714 c 0.426,1.146 0.748,2.596 0.841,4.284 l 0.2,3.683 3.564,-0.946 c 1.32,-0.351 2.655,-0.536 3.86,-0.536 0.16,0 0.318,0.003 0.474,0.01 l -1.827,2.819 3.139,1.211 c -0.958,0.759 -2.237,1.514 -3.814,2.123 l -3.441,1.328 2.001,3.099 c 0.918,1.42 1.509,2.782 1.838,3.96 l -3.244,-0.865 -0.182,3.357 c -1.019,-0.677 -2.132,-1.66 -3.198,-2.973 l -2.329,-2.863 -2.328,2.862 c -1.066,1.312 -2.179,2.295 -3.198,2.972 l -0.18,-3.354 -3.248,0.864 c 0.329,-1.178 0.921,-2.54 1.839,-3.961 l 2.004,-3.099 -3.442,-1.328 c -1.577,-0.609 -2.856,-1.363 -3.814,-2.122 l 3.135,-1.208 -1.827,-2.823 c 0.155,-0.006 0.313,-0.01 0.473,-0.01 1.206,0 2.541,0.185 3.861,0.536 l 3.564,0.947 0.202,-3.683 c 0.092,-1.688 0.415,-3.138 0.84,-4.284 l 2.119,2.609 2.118,-2.609 m 0.19,-4.991 -2.308,2.841 -2.308,-2.841 c -1.989,1.532 -3.421,4.992 -3.646,9.112 -1.617,-0.43 -3.192,-0.637 -4.632,-0.637 -2.11,0 -3.929,0.445 -5.161,1.289 l 1.989,3.073 -3.415,1.316 c 0.842,2.366 3.69,4.797 7.54,6.283 -2.241,3.465 -3.116,7.106 -2.407,9.5160001 l 3.537,-0.9410001 0.196,3.6540001 c 2.512,-0.07 5.703,-2.027 8.307,-5.2280001 2.603,3.2010001 5.796,5.1580001 8.306,5.2280001 l 0.198,-3.6550001 3.535,0.9430001 c 0.71,-2.4110001 -0.165,-6.0500001 -2.404,-9.5170001 3.849,-1.485 6.696,-3.918 7.538,-6.283 l -3.415,-1.318 1.99,-3.07 c -1.233,-0.844 -3.053,-1.29 -5.164,-1.29 -1.438,0 -3.013,0.207 -4.63,0.636 -0.225,-4.119 -1.657,-7.579 -3.646,-9.111 z"
id="path6-6" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:42.6667px;line-height:1.25;font-family:sans-serif;fill:#ea596e;fill-opacity:1;stroke:none"
x="2.2188232"
y="31.430677"
id="text46212"><tspan
sodipodi:role="line"
id="tspan46210"
x="2.2188232"
y="31.430677"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:42.6667px;font-family:'TeX Gyre Termes';-inkscape-font-specification:'TeX Gyre Termes'">D</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:42.6667px;line-height:1.25;font-family:sans-serif;fill:#ea596e;fill-opacity:1;stroke:none"
x="41.347008"
y="67.114784"
id="text46212-1"><tspan
sodipodi:role="line"
id="tspan46210-5"
x="41.347008"
y="67.114784"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:42.6667px;font-family:'TeX Gyre Termes';-inkscape-font-specification:'TeX Gyre Termes'">F</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

@@ -0,0 +1,537 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="850"
height="480"
viewBox="0 0 224.89584 127"
version="1.1"
id="svg8"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
sodipodi:docname="garage_tables.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs2">
<marker
style="overflow:visible"
id="marker1262"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true">
<path
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="path1260" />
</marker>
<marker
style="overflow:visible"
id="Arrow1Mend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true"
inkscape:collect="always">
<path
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="path965" />
</marker>
<marker
style="overflow:visible"
id="Arrow1Lend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend"
inkscape:isstock="true">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="path959" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="429.31483"
inkscape:cy="289.40871"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:window-width="1678"
inkscape:window-height="993"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="39.570904"
y="38.452755"
id="text2025"><tspan
sodipodi:role="line"
id="tspan2023"
x="39.570904"
y="38.452755"
style="font-size:5.64444px;stroke-width:0.264583" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="101.95796"
y="92.835831"
id="text2139"><tspan
sodipodi:role="line"
id="tspan2137"
x="101.95796"
y="92.835831"
style="stroke-width:0.264583"> </tspan></text>
<g
id="g2316"
transform="translate(-11.455511,1.5722486)">
<g
id="g2277">
<rect
style="fill:none;stroke:#000000;stroke-width:0.8;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833"
width="47.419891"
height="95.353409"
x="18.534418"
y="24.42766" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-3"
width="47.419891"
height="86.973076"
x="18.534418"
y="32.807987" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="32.250839"
y="29.894743"
id="text852"><tspan
sodipodi:role="line"
id="tspan850"
x="32.250839"
y="29.894743"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Object</tspan></text>
</g>
<g
id="g2066"
transform="translate(-2.1807817,-3.0621439)">
<g
id="g1969"
transform="matrix(0.12763631,0,0,0.12763631,0.7215051,24.717273)"
style="fill:#ff6600;fill-opacity:1;stroke:none;stroke-opacity:1">
<path
style="fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.264583;stroke-opacity:1"
d="m 203.71837,154.80038 c -1.11451,3.75057 -2.45288,5.84095 -5.11132,7.98327 -2.2735,1.83211 -4.66721,2.65982 -8.09339,2.79857 -2.59227,0.10498 -2.92868,0.0577 -5.02863,-0.70611 -3.99215,-1.45212 -7.1627,-4.65496 -8.48408,-8.57046 -1.28374,-3.80398 -0.61478,-8.68216 1.64793,-12.01698 0.87317,-1.28689 3.15089,-3.48326 4.18771,-4.03815 l 0.53332,-28.51234 5.78454,-5.09197 6.95158,6.16704 -3.21112,3.49026 3.17616,3.45499 -3.17616,3.40822 2.98973,3.28645 -3.24843,3.3829 4.49203,4.58395 0.0516,5.69106 c 1.06874,0.64848 3.81974,3.24046 4.69548,4.56257 0.452,0.68241 1.06834,2.0197 1.36962,2.97176 0.62932,1.98864 0.88051,5.785 0.47342,7.15497 z m -10.0406,2.32604 c -0.88184,-3.17515 -4.92402,-3.78864 -6.75297,-1.02492 -0.58328,0.8814 -0.6898,1.28852 -0.58362,2.23056 0.26492,2.35041 2.45434,3.95262 4.60856,3.37255 1.19644,-0.32217 2.39435,-1.44872 2.72875,-2.56621 0.30682,-1.02529 0.30686,-0.9045 -7.9e-4,-2.01198 z"
id="path1971"
sodipodi:nodetypes="ssscsscccccccccccssscsssscc" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="28.809687"
y="44.070885"
id="text852-9"><tspan
sodipodi:role="line"
id="tspan850-4"
x="28.809687"
y="44.070885"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">bucket </tspan></text>
</g>
<g
id="g2066-7"
transform="translate(-2.1807817,6.2627616)">
<g
id="g1969-8"
transform="matrix(0.12763631,0,0,0.12763631,0.7215051,24.717273)"
style="fill:#ff6600;fill-opacity:1;stroke:none;stroke-opacity:1">
<path
style="fill:#4040ff;fill-opacity:1;stroke:none;stroke-width:0.264583;stroke-opacity:1"
d="m 203.71837,154.80038 c -1.11451,3.75057 -2.45288,5.84095 -5.11132,7.98327 -2.2735,1.83211 -4.66721,2.65982 -8.09339,2.79857 -2.59227,0.10498 -2.92868,0.0577 -5.02863,-0.70611 -3.99215,-1.45212 -7.1627,-4.65496 -8.48408,-8.57046 -1.28374,-3.80398 -0.61478,-8.68216 1.64793,-12.01698 0.87317,-1.28689 3.15089,-3.48326 4.18771,-4.03815 l 0.53332,-28.51234 5.78454,-5.09197 6.95158,6.16704 -3.21112,3.49026 3.17616,3.45499 -3.17616,3.40822 2.98973,3.28645 -3.24843,3.3829 4.49203,4.58395 0.0516,5.69106 c 1.06874,0.64848 3.81974,3.24046 4.69548,4.56257 0.452,0.68241 1.06834,2.0197 1.36962,2.97176 0.62932,1.98864 0.88051,5.785 0.47342,7.15497 z m -10.0406,2.32604 c -0.88184,-3.17515 -4.92402,-3.78864 -6.75297,-1.02492 -0.58328,0.8814 -0.6898,1.28852 -0.58362,2.23056 0.26492,2.35041 2.45434,3.95262 4.60856,3.37255 1.19644,-0.32217 2.39435,-1.44872 2.72875,-2.56621 0.30682,-1.02529 0.30686,-0.9045 -7.9e-4,-2.01198 z"
id="path1971-4"
sodipodi:nodetypes="ssscsscccccccccccssscsssscc" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="28.809687"
y="44.070885"
id="text852-9-5"><tspan
sodipodi:role="line"
id="tspan850-4-0"
x="28.809687"
y="44.070885"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">file path </tspan></text>
<path
style="fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.0337704;stroke-opacity:1"
d="m 174.20027,104.45585 c -0.14225,0.47871 -0.31308,0.74552 -0.65239,1.01896 -0.29018,0.23384 -0.5957,0.33949 -1.03301,0.3572 -0.33087,0.0134 -0.37381,0.007 -0.64184,-0.0901 -0.50954,-0.18534 -0.91422,-0.59414 -1.08287,-1.0939 -0.16385,-0.48552 -0.0785,-1.10816 0.21033,-1.5338 0.11145,-0.16426 0.40217,-0.44459 0.53451,-0.51542 l 0.0681,-3.639207 0.73832,-0.64992 0.88727,0.787138 -0.40986,0.445484 0.4054,0.440982 -0.4054,0.435013 0.3816,0.41947 -0.41461,0.43178 0.57334,0.58508 0.007,0.72639 c 0.13641,0.0828 0.48753,0.4136 0.59931,0.58235 0.0577,0.0871 0.13636,0.25778 0.17481,0.3793 0.0803,0.25382 0.11239,0.73838 0.0604,0.91323 z m -1.28154,0.29689 c -0.11256,-0.40526 -0.62849,-0.48357 -0.86193,-0.13082 -0.0745,0.1125 -0.088,0.16447 -0.0745,0.2847 0.0338,0.3 0.31326,0.5045 0.58822,0.43046 0.15271,-0.0411 0.30561,-0.1849 0.34829,-0.32754 0.0392,-0.13086 0.0392,-0.11544 -1e-4,-0.2568 z"
id="path1971-3"
sodipodi:nodetypes="ssscsscccccccccccssscsssscc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="177.8474"
y="104.05132"
id="text852-9-6"><tspan
sodipodi:role="line"
id="tspan850-4-7"
x="177.8474"
y="104.05132"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">= partition key </tspan></text>
<path
style="fill:#4040ff;fill-opacity:1;stroke:none;stroke-width:0.0337704;stroke-opacity:1"
d="m 174.20027,113.78076 c -0.14225,0.47871 -0.31308,0.74552 -0.65239,1.01895 -0.29018,0.23385 -0.5957,0.33949 -1.03301,0.3572 -0.33087,0.0134 -0.37381,0.007 -0.64184,-0.0901 -0.50954,-0.18534 -0.91422,-0.59414 -1.08287,-1.0939 -0.16385,-0.48553 -0.0785,-1.10816 0.21033,-1.53381 0.11145,-0.16425 0.40217,-0.44459 0.53451,-0.51541 l 0.0681,-3.63921 0.73832,-0.64992 0.88727,0.78714 -0.40986,0.44548 0.4054,0.44098 -0.4054,0.43502 0.3816,0.41947 -0.41461,0.43178 0.57334,0.58508 0.007,0.72638 c 0.13641,0.0828 0.48753,0.4136 0.59931,0.58235 0.0577,0.0871 0.13636,0.25779 0.17481,0.37931 0.0803,0.25382 0.11239,0.73837 0.0604,0.91323 z m -1.28154,0.29689 c -0.11256,-0.40527 -0.62849,-0.48357 -0.86193,-0.13082 -0.0745,0.1125 -0.088,0.16446 -0.0745,0.2847 0.0338,0.3 0.31326,0.5045 0.58822,0.43046 0.15271,-0.0411 0.30561,-0.18491 0.34829,-0.32754 0.0392,-0.13087 0.0392,-0.11545 -1e-4,-0.2568 z"
id="path1971-4-5"
sodipodi:nodetypes="ssscsscccccccccccssscsssscc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="177.8474"
y="113.37622"
id="text852-9-5-3"><tspan
sodipodi:role="line"
id="tspan850-4-0-5"
x="177.8474"
y="113.37622"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">= sort key </tspan></text>
</g>
<g
id="g2161"
transform="translate(-62.264403,-59.333115)">
<g
id="g2271"
transform="translate(0,67.042823)">
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-6"
width="39.008453"
height="16.775949"
x="84.896881"
y="90.266838" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-3-1"
width="39.008453"
height="8.673645"
x="84.896881"
y="98.369141" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="89.826942"
y="96.212921"
id="text852-0"><tspan
sodipodi:role="line"
id="tspan850-6"
x="89.826942"
y="96.212921"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Version 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="89.826942"
y="104.71013"
id="text852-0-3"><tspan
sodipodi:role="line"
id="tspan850-6-2"
x="89.826942"
y="104.71013"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';fill:#4d4d4d;stroke-width:0.264583">deleted</tspan></text>
</g>
</g>
<g
id="g2263"
transform="translate(0,-22.791204)">
<g
id="g2161-1"
transform="translate(-62.264403,-10.910843)">
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-6-5"
width="39.008453"
height="36.749603"
x="84.896881"
y="90.266838" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-3-1-5"
width="39.008453"
height="28.647301"
x="84.896881"
y="98.369141" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="89.826942"
y="96.212921"
id="text852-0-4"><tspan
sodipodi:role="line"
id="tspan850-6-7"
x="89.826942"
y="96.212921"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Version 2</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="89.826942"
y="104.71013"
id="text852-0-3-6"><tspan
sodipodi:role="line"
id="tspan850-6-2-5"
x="89.826942"
y="104.71013"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';fill:#000000;stroke-width:0.264583">id</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.56254"
y="100.34132"
id="text852-0-3-6-6"><tspan
sodipodi:role="line"
id="tspan850-6-2-5-9"
x="27.56254"
y="100.34132"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';fill:#000000;stroke-width:0.264583">size</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.56254"
y="106.90263"
id="text852-0-3-6-6-3"><tspan
sodipodi:role="line"
id="tspan850-6-2-5-9-7"
x="27.56254"
y="106.90263"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';fill:#000000;stroke-width:0.264583">MIME type</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.56254"
y="111.92816"
id="text852-0-3-6-6-3-4"><tspan
sodipodi:role="line"
id="tspan850-6-2-5-9-7-5"
x="27.56254"
y="111.92816"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';fill:#000000;stroke-width:0.264583">...</tspan></text>
</g>
</g>
<g
id="g898"
transform="translate(-6.2484318,29.95006)">
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-7"
width="47.419891"
height="44.007515"
x="95.443573"
y="24.42766" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-3-4"
width="47.419891"
height="35.627186"
x="95.443573"
y="32.807987" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="107.46638"
y="29.894743"
id="text852-4"><tspan
sodipodi:role="line"
id="tspan850-3"
x="107.46638"
y="29.894743"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Version</tspan></text>
<path
style="fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.0337704;stroke-opacity:1"
d="m 102.90563,41.413279 c -0.14226,0.478709 -0.31308,0.745518 -0.65239,1.018956 -0.29019,0.233843 -0.59571,0.339489 -1.03301,0.357199 -0.33087,0.0134 -0.37381,0.0074 -0.64184,-0.09013 -0.50954,-0.185343 -0.914221,-0.594142 -1.082877,-1.093901 -0.163852,-0.485526 -0.07847,-1.108159 0.210335,-1.533803 0.111448,-0.164254 0.402172,-0.444591 0.534502,-0.515415 l 0.0681,-3.63921 0.73832,-0.64992 0.88727,0.787138 -0.40985,0.445484 0.40539,0.440982 -0.40539,0.435013 0.3816,0.41947 -0.41462,0.431781 0.57335,0.585078 0.007,0.726386 c 0.13641,0.08277 0.48753,0.413601 0.59931,0.58235 0.0577,0.0871 0.13636,0.257787 0.17481,0.379304 0.0803,0.253823 0.11239,0.738377 0.0604,0.913234 z m -1.28155,0.296888 c -0.11255,-0.405265 -0.62848,-0.483569 -0.86192,-0.130817 -0.0744,0.112498 -0.088,0.164461 -0.0745,0.2847 0.0338,0.299998 0.31326,0.504498 0.58822,0.43046 0.15271,-0.04112 0.3056,-0.184909 0.34828,-0.327542 0.0392,-0.130864 0.0392,-0.115447 -1e-4,-0.256801 z"
id="path1971-0"
sodipodi:nodetypes="ssscsscccccccccccssscsssscc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="104.99195"
y="41.008743"
id="text852-9-7"><tspan
sodipodi:role="line"
id="tspan850-4-8"
x="104.99195"
y="41.008743"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">id </tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="104.99195"
y="49.168018"
id="text852-9-7-6"><tspan
sodipodi:role="line"
id="tspan850-4-8-8"
x="104.99195"
y="49.168018"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">h(block 1)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="104.99195"
y="56.583336"
id="text852-9-7-6-8"><tspan
sodipodi:role="line"
id="tspan850-4-8-8-4"
x="104.99195"
y="56.583336"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">h(block 2)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="104.99195"
y="64.265732"
id="text852-9-7-6-3"><tspan
sodipodi:role="line"
id="tspan850-4-8-8-1"
x="104.99195"
y="64.265732"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">...</tspan></text>
</g>
<g
id="g898-3"
transform="translate(75.777779,38.888663)">
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-7-6"
width="47.419891"
height="29.989157"
x="95.443573"
y="24.42766" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.799999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect833-3-4-7"
width="47.419891"
height="21.608831"
x="95.443573"
y="32.807987" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="102.11134"
y="29.894743"
id="text852-4-5"><tspan
sodipodi:role="line"
id="tspan850-3-3"
x="102.11134"
y="29.894743"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Data block</tspan></text>
<path
style="fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.0337704;stroke-opacity:1"
d="m 102.90563,41.413279 c -0.14226,0.478709 -0.31308,0.745518 -0.65239,1.018956 -0.29019,0.233843 -0.59571,0.339489 -1.03301,0.357199 -0.33087,0.0134 -0.37381,0.0074 -0.64184,-0.09013 -0.50954,-0.185343 -0.914221,-0.594142 -1.082877,-1.093901 -0.163852,-0.485526 -0.07847,-1.108159 0.210335,-1.533803 0.111448,-0.164254 0.402172,-0.444591 0.534502,-0.515415 l 0.0681,-3.63921 0.73832,-0.64992 0.88727,0.787138 -0.40985,0.445484 0.40539,0.440982 -0.40539,0.435013 0.3816,0.41947 -0.41462,0.431781 0.57335,0.585078 0.007,0.726386 c 0.13641,0.08277 0.48753,0.413601 0.59931,0.58235 0.0577,0.0871 0.13636,0.257787 0.17481,0.379304 0.0803,0.253823 0.11239,0.738377 0.0604,0.913234 z m -1.28155,0.296888 c -0.11255,-0.405265 -0.62848,-0.483569 -0.86192,-0.130817 -0.0744,0.112498 -0.088,0.164461 -0.0745,0.2847 0.0338,0.299998 0.31326,0.504498 0.58822,0.43046 0.15271,-0.04112 0.3056,-0.184909 0.34828,-0.327542 0.0392,-0.130864 0.0392,-0.115447 -1e-4,-0.256801 z"
id="path1971-0-5"
sodipodi:nodetypes="ssscsscccccccccccssscsssscc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="104.99195"
y="41.008743"
id="text852-9-7-62"><tspan
sodipodi:role="line"
id="tspan850-4-8-9"
x="104.99195"
y="41.008743"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">hash </tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="104.99195"
y="49.168018"
id="text852-9-7-6-1"><tspan
sodipodi:role="line"
id="tspan850-4-8-8-2"
x="104.99195"
y="49.168018"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">data</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 42.105292,69.455903 89.563703,69.317144"
id="path954"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1262)"
d="m 134.32612,77.363197 38.12618,0.260865"
id="path1258"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="8.6727352"
y="16.687063"
id="text852-3"><tspan
sodipodi:role="line"
id="tspan850-67"
x="8.6727352"
y="16.687063"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Objects table </tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="89.190445"
y="16.687063"
id="text852-3-5"><tspan
sodipodi:role="line"
id="tspan850-67-3"
x="89.190445"
y="16.687063"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Versions table </tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="174.55702"
y="16.687063"
id="text852-3-56"><tspan
sodipodi:role="line"
id="tspan850-67-2"
x="174.55702"
y="16.687063"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono Bold';stroke-width:0.264583">Blocks table</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

@@ -0,0 +1,433 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice1.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="445.81962"
inkscape:cy="222.66987"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,514 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice2.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="384.39345"
inkscape:cy="227.46879"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="139.48744"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="131.61919"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1,515 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice3.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="324.06479"
inkscape:cy="168.98876"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="139.48744"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="119.58919"
cy="67.645035"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1,525 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice4.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.73673541"
inkscape:cx="287.07728"
inkscape:cy="294.54265"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="126.08154"
cy="67.968384"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="119.58919"
cy="67.645035"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549"
id="text4280"><tspan
sodipodi:role="line"
id="tspan4278"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549">return OK</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1,536 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice5.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="276.89766"
inkscape:cy="254.34273"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="126.08154"
cy="67.968384"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="119.58919"
cy="67.645035"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436"
id="text3707-1"><tspan
sodipodi:role="line"
id="tspan3705-5"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549"
id="text4280"><tspan
sodipodi:role="line"
id="tspan4278"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549">return OK</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

@@ -0,0 +1,553 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice6.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="277.85744"
inkscape:cy="254.34273"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="126.08154"
cy="67.968384"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="119.58919"
cy="67.645035"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436"
id="text3707-1"><tspan
sodipodi:role="line"
id="tspan3705-5"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-4"
cx="18.004833"
cy="70.942116"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="73.643356"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-65"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="73.643356">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549"
id="text4280"><tspan
sodipodi:role="line"
id="tspan4278"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549">return OK</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

@@ -0,0 +1,581 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice7.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="276.89766"
inkscape:cy="254.34273"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="126.08154"
cy="67.968384"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="119.58919"
cy="67.645035"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436"
id="text3707-1"><tspan
sodipodi:role="line"
id="tspan3705-5"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-4"
cx="18.004833"
cy="70.942116"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="73.643356"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-65"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="73.643356">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549"
id="text4280"><tspan
sodipodi:role="line"
id="tspan4278"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549">return OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="92.005798"
id="text4280-3"><tspan
sodipodi:role="line"
id="tspan4278-7"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="92.005798">return $\{\}\sqcup\{a\}=\{a\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-5"
cx="18.004833"
cy="81.007744"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="83.577797"
id="text3750-0-6"><tspan
sodipodi:role="line"
id="tspan3748-6-9"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="83.577797">$\to \{a\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,581 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="400"
viewBox="0 0 264.58333 105.83333"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lattice8.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="399.39712"
inkscape:cy="248.39311"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:1;stop-color:#000000"
id="rect288"
width="209.84705"
height="104.42732"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="stroke-width:0.264583;fill:#000000"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="stroke-width:0.264583;fill:#000000"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="stroke-width:0.264583;fill:#000000"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="stroke-width:0.264583;fill:#000000"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="132.33408"
cy="68.007973"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="126.08154"
cy="67.968384"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="119.58919"
cy="67.645035"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="stroke-width:0.264583;fill:#000000"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436"
id="text3707-1"><tspan
sodipodi:role="line"
id="tspan3705-5"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.261436">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-4"
cx="18.004833"
cy="70.942116"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="73.643356"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-65"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="73.643356">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549"
id="text4280"><tspan
sodipodi:role="line"
id="tspan4278"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="52.022549">return OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="14.395845"
y="92.005798"
id="text4280-3"><tspan
sodipodi:role="line"
id="tspan4278-7"
style="fill:#000000;stroke-width:0.264583"
x="14.395845"
y="92.005798">return $\{\}\sqcup\{a\}=\{a\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-5"
cx="18.004833"
cy="81.007744"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="83.577797"
id="text3750-0-6"><tspan
sodipodi:role="line"
id="tspan3748-6-9"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="83.577797">$\to \{a\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,576 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_1.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="469.81422"
inkscape:cy="257.22209"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="141.05479"
cy="95.316383"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="134.56244"
cy="94.993034"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,715 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_10.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="664.65036"
inkscape:cy="366.63745"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0"
cx="67.201363"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125"
id="text3750-9"><tspan
sodipodi:role="line"
id="tspan3748-3"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125">$\to \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="text4280-6"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="tspan2630">return $\{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7"
cx="67.201363"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073"
id="text3750-3-6"><tspan
sodipodi:role="line"
id="tspan3748-2-0"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073">$\to \{\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0-6"
cx="174.36296"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="179.81555"
y="127.6125"
id="text3750-9-1"><tspan
sodipodi:role="line"
id="tspan3748-3-8"
style="fill:#000000;stroke-width:0.264583"
x="179.81555"
y="127.6125">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403"
id="text3707-5-3-7"><tspan
sodipodi:role="line"
id="tspan3705-4-6-5"
style="fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583"
x="134.97845"
y="132.58472"
id="text3899"><tspan
sodipodi:role="line"
id="tspan3897"
style="stroke-width:0.264583"
x="134.97845"
y="132.58472">;</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="169.92604"
y="146.3129"
id="text4280-6-7"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="169.92604"
y="146.3129"
id="tspan2630-9">return $\{b\}$</tspan></text>
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7-2"
cx="174.36296"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="179.81555"
y="136.59073"
id="text3750-3-6-0"><tspan
sodipodi:role="line"
id="tspan3748-2-0-2"
style="fill:#000000;stroke-width:0.264583"
x="179.81555"
y="136.59073">$\to \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:end;text-anchor:end;fill:#ff0000;stroke-width:0.264583"
x="259.75"
y="135.53111"
id="text9043"><tspan
sodipodi:role="line"
id="tspan9041"
style="fill:#ff0000;stroke-width:0.264583"
x="259.75"
y="135.53111">${\Large\textbf{??!}}$~~~~~</tspan><tspan
sodipodi:role="line"
style="fill:#ff0000;stroke-width:0.264583"
x="259.75"
y="146.11446"
id="tspan9372">$\{a\} \not\sqsubseteq \{b\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

@@ -0,0 +1,576 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_2.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="586.70996"
inkscape:cy="321.01077"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="141.05479"
cy="95.316383"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,576 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_3.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.0838024"
inkscape:cx="465.25525"
inkscape:cy="269.21938"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,587 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_4.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="505.32622"
inkscape:cy="316.72869"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

@@ -0,0 +1,604 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_5.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="408.21983"
inkscape:cy="319.65343"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0"
cx="67.201363"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125"
id="text3750-9"><tspan
sodipodi:role="line"
id="tspan3748-3"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125">$\to \{a\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

@@ -0,0 +1,632 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_6.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="408.21983"
inkscape:cy="319.65343"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0"
cx="67.201363"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125"
id="text3750-9"><tspan
sodipodi:role="line"
id="tspan3748-3"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125">$\to \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="text4280-6"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="tspan2630">return $\{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7"
cx="67.201363"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073"
id="text3750-3-6"><tspan
sodipodi:role="line"
id="tspan3748-2-0"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073">$\to \{\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,654 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_7.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="553.45515"
inkscape:cy="346.80022"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0"
cx="67.201363"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125"
id="text3750-9"><tspan
sodipodi:role="line"
id="tspan3748-3"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125">$\to \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="text4280-6"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="tspan2630">return $\{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7"
cx="67.201363"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073"
id="text3750-3-6"><tspan
sodipodi:role="line"
id="tspan3748-2-0"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403"
id="text3707-5-3-7"><tspan
sodipodi:role="line"
id="tspan3705-4-6-5"
style="fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583"
x="134.97845"
y="132.58472"
id="text3899"><tspan
sodipodi:role="line"
id="tspan3897"
style="stroke-width:0.264583"
x="134.97845"
y="132.58472">;</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

@@ -0,0 +1,671 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_8.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.4734708"
inkscape:cx="448.94001"
inkscape:cy="322.36811"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0"
cx="67.201363"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125"
id="text3750-9"><tspan
sodipodi:role="line"
id="tspan3748-3"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125">$\to \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="text4280-6"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="tspan2630">return $\{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7"
cx="67.201363"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073"
id="text3750-3-6"><tspan
sodipodi:role="line"
id="tspan3748-2-0"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073">$\to \{\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0-6"
cx="174.36296"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="179.81555"
y="127.6125"
id="text3750-9-1"><tspan
sodipodi:role="line"
id="tspan3748-3-8"
style="fill:#000000;stroke-width:0.264583"
x="179.81555"
y="127.6125">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403"
id="text3707-5-3-7"><tspan
sodipodi:role="line"
id="tspan3705-4-6-5"
style="fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583"
x="134.97845"
y="132.58472"
id="text3899"><tspan
sodipodi:role="line"
id="tspan3897"
style="stroke-width:0.264583"
x="134.97845"
y="132.58472">;</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

@@ -0,0 +1,699 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1000"
height="600"
viewBox="0 0 264.58333 158.75"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="latticeB_9.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="664.65036"
inkscape:cy="366.63745"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer2" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-8" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-75-7-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-9-3-2" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-93-1-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-6-8-7" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-9-7-2-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-1-0-6-4" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
sodipodi:insensitive="true">
<rect
style="fill:#ffffff;stroke:none;stroke-width:0.999998;stop-color:#000000"
id="rect288"
width="262.58151"
height="156.82782"
x="0.77790999"
y="0.93738818" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442"
id="text951"><tspan
sodipodi:role="line"
id="tspan949"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="99.307442">$\{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893"
id="text1005"><tspan
sodipodi:role="line"
id="tspan1003"
style="fill:#000000;stroke-width:0.264583"
x="164.56372"
y="13.151893">$\{a,b,c\}$</tspan></text>
<g
id="g1175"
transform="translate(51.996784,3.5774043)">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698"
id="text1009"><tspan
sodipodi:role="line"
id="tspan1007"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="67.008698">$\{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166"
id="text1009-3"><tspan
sodipodi:role="line"
id="tspan1007-6"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="67.017166">$\{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698"
id="text1009-7"><tspan
sodipodi:role="line"
id="tspan1007-5"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="67.008698">$\{c\}$</tspan></text>
</g>
<g
id="g1183"
transform="translate(51.996784,1.0317046)"
style="fill:#000000">
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526"
id="text1117"><tspan
sodipodi:role="line"
id="tspan1115"
style="fill:#000000;stroke-width:0.264583"
x="112.90984"
y="40.841526">$\{a,c\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526"
id="text1117-3"><tspan
sodipodi:role="line"
id="tspan1115-5"
style="fill:#000000;stroke-width:0.264583"
x="49.27084"
y="40.841526">$\{a,b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526"
id="text1117-6"><tspan
sodipodi:role="line"
id="tspan1115-2"
style="fill:#000000;stroke-width:0.264583"
x="176.20593"
y="40.841526">$\{b,c\}$</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 153.33622,90.367682 118.34198,73.428915"
id="path1300" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9)"
d="M 177.46016,90.367682 212.4544,73.428915"
id="path1300-2" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93)"
d="M 153.33622,61.655656 118.34198,44.716889"
id="path1300-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7)"
d="M 177.46016,61.655656 212.4544,44.716889"
id="path1300-2-6" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1)"
d="M 118.34198,61.655656 153.33622,44.716889"
id="path1300-0-7" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2)"
d="M 212.4544,61.655656 177.46016,44.716889"
id="path1300-2-6-9" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-93-1-4)"
d="M 118.34198,34.227412 153.33622,17.288645"
id="path1300-0-7-5" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-7-2-8)"
d="M 212.4544,34.227412 177.46016,17.288645"
id="path1300-2-6-9-0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75)"
d="m 228.52843,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-2)"
d="m 101.90418,61.091809 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7)"
d="m 165.29305,89.571762 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-9-75-7-1)"
d="m 165.29305,32.445235 0.33313,-12.554874 m -0.33313,12.554874 0.33313,-12.554874"
id="path1300-2-2-6-9"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663"
cx="147.35568"
cy="95.24971"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3"
cx="176.97627"
cy="68.155472"
r="2.7302806" />
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1"
cx="18.004833"
cy="39.402473"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0"
cx="18.004833"
cy="30.371933"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6"
cx="18.004833"
cy="21.341394"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217"
id="text3707"><tspan
sodipodi:role="line"
id="tspan3705"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="13.702217">$write(\{a\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637"
id="text3750"><tspan
sodipodi:role="line"
id="tspan3748"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="24.042637">$\sqsupseteq \{a\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087"
id="text3750-3"><tspan
sodipodi:role="line"
id="tspan3748-2"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="33.02087">$\not\sqsupseteq \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523"
id="text3750-0"><tspan
sodipodi:role="line"
id="tspan3748-6"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="41.972523">$\not\sqsupseteq \{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-1-4"
cx="18.004833"
cy="90.979645"
r="2.7302806" />
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-5"
cx="18.004833"
cy="81.949104"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-2"
cx="18.004833"
cy="72.918564"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381"
id="text3707-5"><tspan
sodipodi:role="line"
id="tspan3705-4"
style="fill:#000000;stroke-width:0.264583"
x="6.9525447"
y="65.279381">$write(\{b\})$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403"
id="text3707-5-3"><tspan
sodipodi:role="line"
id="tspan3705-4-6"
style="fill:#000000;stroke-width:0.264583"
x="59.340172"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804"
id="text3750-7"><tspan
sodipodi:role="line"
id="tspan3748-4"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="75.619804">$\not\sqsupseteq \{b\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038"
id="text3750-3-4"><tspan
sodipodi:role="line"
id="tspan3748-2-3"
style="fill:#000000;stroke-width:0.264583"
x="23.457415"
y="84.598038">$\sqsupseteq \{b\} \to$ OK</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969"
id="text3750-0-0"><tspan
sodipodi:role="line"
id="tspan3748-6-7"
style="fill:#999999;stroke-width:0.264583"
x="23.457415"
y="93.54969">$\not\sqsupseteq \{b\}$</tspan></text>
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6"
cx="118.63729"
cy="67.630196"
r="2.7302806" />
<circle
style="fill:#800080;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0"
cx="67.201363"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125"
id="text3750-9"><tspan
sodipodi:role="line"
id="tspan3748-3"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="127.6125">$\to \{a\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="text4280-6"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="62.764446"
y="146.3129"
id="tspan2630">return $\{a\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7"
cx="67.201363"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073"
id="text3750-3-6"><tspan
sodipodi:role="line"
id="tspan3748-2-0"
style="fill:#000000;stroke-width:0.264583"
x="72.653946"
y="136.59073">$\to \{\}$</tspan></text>
<circle
style="fill:#ff0000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-6-6-0-6"
cx="174.36296"
cy="124.91125"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="179.81555"
y="127.6125"
id="text3750-9-1"><tspan
sodipodi:role="line"
id="tspan3748-3-8"
style="fill:#000000;stroke-width:0.264583"
x="179.81555"
y="127.6125">$\to \{\}$</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403"
id="text3707-5-3-7"><tspan
sodipodi:role="line"
id="tspan3705-4-6-5"
style="fill:#000000;stroke-width:0.264583"
x="162.7999"
y="118.94403">$read()$:</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583"
x="134.97845"
y="132.58472"
id="text3899"><tspan
sodipodi:role="line"
id="tspan3897"
style="stroke-width:0.264583"
x="134.97845"
y="132.58472">;</tspan></text>
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="169.92604"
y="146.3129"
id="text4280-6-7"><tspan
sodipodi:role="line"
style="fill:#000000;stroke-width:0.264583"
x="169.92604"
y="146.3129"
id="tspan2630-9">return $\{b\}$</tspan></text>
<circle
style="fill:#008000;stroke:none;stroke-width:0.499999;stroke-dasharray:none;stop-color:#000000"
id="path3663-3-0-7-2"
cx="174.36296"
cy="133.94179"
r="2.7302806" />
<text
xml:space="preserve"
style="font-size:8.46667px;line-height:1.25;font-family:sans-serif;fill:#000000;stroke-width:0.264583"
x="179.81555"
y="136.59073"
id="text3750-3-6-0"><tspan
sodipodi:role="line"
id="tspan3748-2-0-2"
style="fill:#000000;stroke-width:0.264583"
x="179.81555"
y="136.59073">$\to \{b\}$</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Some files were not shown because too many files have changed in this diff Show More