New Page
Chapter 1: The Virtual Laboratory — Linux Mint & Logic
Overview
Every serious engineering project begins with a reliable workspace. Before we write a single Prolog clause or a single Go function, we need an environment that is consistent, isolated, secure, and reproducible. This chapter is devoted entirely to that foundation. We are going to provision a Linux Mint 22.x Cinnamon virtual machine on a Proxmox host, install SWI-Prolog 10.x, configure VS Code with the appropriate extensions, and verify the entire stack is working with a small but real first program.
This is not a "hello world" chapter in the dismissive sense. The decisions we make here — the VM configuration, the network topology, the way we install software — will echo through every chapter that follows. We will explain *why*why we are making each choice, particularly around security, because the homelab environment that most readers of this book are working in is not a toy. It is, or will become, a genuinely powerful orchestration system, and systems that have real power deserve real security from day one.
By the end of this chapter, the environment will be ready to support every tutorial in Parts I through III of this book.
1.1 The Case for This Stack: Proxmox, Mint, and the Security Argument
Before we touch the Proxmox web interface, it is worth spending a few pages on *why*why we have assembled this particular combination of tools. The choice of Proxmox as the hypervisor, Linux Mint 22.x as the development guest, and SWI-Prolog paired with Go as the programming environment is not arbitrary. Each decision carries an architectural rationale, and the most important of those rationales is security.
1.1.1 Why Proxmox
Proxmox Virtual Environment (PVE) is an open-source, enterprise-grade hypervisor built on Debian and KVM. It is the hypervisor of choice for the serious homelab because it provides a level of control, observability, and network segmentation that consumer-grade tools like VirtualBox simply cannot match. On Proxmox, every VM lives inside a clearly defined network bridge. We can place our logic development VM on a VLAN that has no outbound internet access except through a controlled gateway, which is exactly the kind of isolation we want for a machine that will eventually be running automated system orchestration tasks.
Readers who are running VMware Workstation Pro or XCP-ng (the Xen Community Edition) will find that the concepts translate directly. The Proxmox-specific steps — creating a VM through the web UI, attaching a disk image, configuring the network bridge — all have direct equivalents in those environments. Where Proxmox-specific CLI commands appear in this chapter, the equivalent VMware `vmrun`vmrun or XCP-ng `xe`xe commands will be noted.
1.1.2 Why Linux Mint 22.x Cinnamon
Linux Mint 22.x, based on Ubuntu 24.04 LTS, provides a stable, long-term-supported foundation with a desktop environment that is genuinely comfortable to use. The Cinnamon desktop is relevant here not because we are building desktop applications, but because we are building a *development laboratory*laboratory. Having a functioning file manager, a taskbar, and a GUI text editor available while we are learning the fundamentals of Prolog means that we can focus our cognitive energy on the *logic*logic, not on memorising terminal commands for tasks that a file manager handles in three seconds.
This comfort is a pedagogical asset, not a compromise. Later in this book, when we migrate to a headless Debian 13 server, we will do so from a position of confidence. The terminal will not feel alien because we will have been using it steadily throughout Parts I through III. The desktop will simply fall away because we no longer need it.
Mint 22.x also has a more straightforward path to installing SWI-Prolog 10.x than a bare Debian system at this stage of the 10.x release cycle, which matters practically for a reader who is setting this up for the first time.
1.1.3 Why SWI-Prolog and Go — The Security Architecture Argument
This point deserves a full treatment because it is one of the genuine advantages of this stack that is rarely articulated clearly in introductory materials.
The software supply chain has become one of the primary vectors for malicious code in the 2020s. The Python ecosystem, despite its enormous productivity advantages, has been the target of sustained, sophisticated typosquatting campaigns. An attacker registers `requets`requets instead of `requests`requests, or `colourama`colourama instead of `colorama`colorama, and waits for a developer to make a single keystroke error in a `pip command. The result can be credential theft, backdoor installation, or ransomware deployment. This is not a hypothetical; it has happened hundreds of documented times, and the sheer size of PyPI (over 500,000 packages as of 2026) makes comprehensive auditing practically impossible.install`install
The SWI-Prolog ecosystem works differently. The primary package mechanism is the **SWI-Prolog Pack system**system, which is small, curated, and predominantly composed of packages written by researchers and engineers who publish their identity alongside their work. As of 2026, there are roughly 400 packs in the official registry. Every pack we use in this book will be examined, its source code will be referenced, and we will explain what it does before we install it. There is no equivalent of `pip install some- followed by a silent import of 47 transitive dependencies.package`package
The Go ecosystem has a similar characteristic. Go modules are imported by their full repository path (`github.com/author/), which makes it significantly harder to conduct a typosquatting attack — there is no central registry where a near-identical name can be quietly registered. The Go toolchain also performs cryptographic verification of module downloads against a transparency log (package`package`sum.golang.), meaning that a package cannot be silently replaced on a server after a developer has verified it.org`org
This does not mean that Prolog and Go are immune to supply chain attacks. Nothing is immune. But the combination of a small, curated package ecosystem (Prolog) and cryptographic module verification (Go) makes this stack measurably more resistant to the class of attacks that have plagued Python-based systems. This is one of the reasons we are using it, and it is a reason we will return to when we discuss security policy enforcement in the Prolog knowledge base in later chapters.
1.2 Provisioning the VM on Proxmox
We will now walk through the complete process of creating and configuring the Linux Mint 22.x VM on Proxmox. These instructions assume Proxmox VE 8.x, which is the current stable release. The web interface described here is accessed via `https://<proxmox-host-ip>:.8006`8006
1.2.1 Downloading the Linux Mint 22.x ISO
The first step is to get the installation ISO onto the Proxmox host. We always download ISOs directly from the official source and verify the checksum before use. This is not paranoia; it is standard operational practice.
https://www.linuxmint.com/download.phpSelect **Linux Mint 22.x "Wilma"** (or the current 22.x point release), **Cinnamon Edition**Edition, 64-bit. Download the `. file.iso`iso
On the same download page, there is a link to the SHA256 checksums file. Download that as well. On a Linux or macOS terminal, verify the download:
sha256sum linuxmint-22.x-cinnamon-64bit.isoCompare the output against the checksum in the downloaded `. file. They must match exactly. If they do not, discard the ISO and download again. We do not proceed with an unverified ISO.sha256sum`sha256sum
Uploading the ISO to Proxmox**
In the Proxmox web interface:
- In the left panel, select your node (e.g.,
`pve`pve). - Expand the node and select a storage pool that supports ISO images — typically
`local`local. - Select
**ISOImages**Images from the content panel. - Click
**Upload**Upload and select the verified`.file.iso`iso
Alternatively, if the Proxmox host has internet access, we can use the **Download from URL**URL option, pasting the direct download URL from the Linux Mint website. However, be aware that this bypasses our local checksum verification step. If using this method, download the ISO to a local path on the Proxmox host afterwards and verify it via the Proxmox shell:
# Access the Proxmox shell via the web UI: Node > Shell1.2.2 Creating the Virtual Machine
In the Proxmox web interface, click **Create VM**VM in the top-right corner. We will go through each tab of the creation wizard.
General Tab**
- Node: Select your Proxmox node.
- VM
ID**ID: Accept the auto-generated ID, or assign a meaningful one (e.g.,`200`200for the Mint development VM). - Name:
`mint-logic-— a descriptive name that will appear in the Proxmox panel.lab`lab
OS Tab**
- ISO
image**image: Select the Linux Mint 22.x ISO we uploaded. - Guest OS
Type**Type:`Linux` - Version:
`6.x - 2.6Kernel`
Linux
System Tab**
- Machine:
`q35`q35— this is the modern PC chipset emulation and is preferred over the older`i440fx`i440fxfor any VM created in 2024 or later. It provides better PCIe support and is required for some UEFI features. - BIOS:
`OVMF (UEFI)— we use UEFI rather than legacy BIOS. Add an EFI disk when prompted (Proxmox will offer this automatically when OVMF is selected). Store it on the same storage pool as the main disk.` - SCSI
Controller**Controller:`VirtIO SCSI— this is the high-performance paravirtualised storage controller. Do not use the legacy IDE or SATA options for a new VM.single`single - Qemu
Agent**Agent: Check this box. We will install the QEMU guest agent inside the VM later, which allows Proxmox to report accurate IP addresses, perform clean shutdowns, and freeze the filesystem for consistent snapshots.
Disks Tab**
- Bus/
Device**Device:`SCSI, using the VirtIO SCSI controller we selected above.0`0 - Storage: Select your preferred storage pool.
- Disk
size**size:`80GB`80GBminimum. For a development machine that will accumulate Prolog knowledge bases, Go module caches, and log files across Parts I through III, 80GB is comfortable. If storage is plentiful, 120GB is better. - Cache:
`Write— this provides the best performance for a development VM. On a production system we would considerback`back`Writefor data safety, but for a development lab where we are taking regular Proxmox snapshots, write-back performance is the priority.through`through - Discard: Enable this if the underlying storage pool is an SSD or NVMe. It allows the guest to communicate TRIM operations to the host, keeping the disk image thin.
CPU Tab**
- Sockets:
`1` - Cores:
`4`4— four cores is the minimum comfortable allocation for running SWI-Prolog, a Go process, and a VS Code instance simultaneously. If the Proxmox host has the cores to spare,`6`6or`8`8is noticeably smoother. - Type:
`host`host— this passes the host CPU's full feature set to the VM, including AVX2 and other extensions that modern compilers (including the Go toolchain) can use. Do not use the default`kvm64`kvm64type for a development machine; it presents a very minimal CPU profile.
1
Memory Tab**
- Memory:
`8192(8GB) minimum. SWI-Prolog's strength is in-memory reasoning over large knowledge bases. Giving the VM adequate RAM from the start means we will not need to revisit this setting halfway through Part II when our knowledge bases start growing.MB`MB`16384(16GB) is ideal if the host can support it.MB`MB - Ballooning: Can be left enabled for flexibility, but for a dedicated logic development VM with a fixed memory allocation, disabling it (by unchecking
**BallooningDevice**Device) gives more predictable performance.
Network Tab**
- Bridge: Select the bridge that corresponds to your development VLAN or network segment. On a homelab Proxmox setup, this is typically
`vmbr0`vmbr0for the primary LAN. If a dedicated VLAN for lab VMs has been configured (e.g., VLAN 10), select that bridge and enter the VLAN tag. - Model:
`VirtIO (paravirt)— always use VirtIO for network adapters in KVM-based VMs. It provides significantly better throughput than the emulated Intel or Realtek adapters.` - Firewall: Check the Proxmox firewall box. We will configure specific rules below.
Confirm Tab**
Review the summary. Do **not**not check "Start after created" — we have one more step before the first boot.
Click **Finish**Finish.
1.2.3 Proxmox Firewall Configuration
Before starting the VM for the first time, we configure the Proxmox firewall for it. Select the newly created VM in the left panel, then navigate to **Firewall > Options**Options.
- Set
**Firewall**Firewall:`Yes`Yes(enabled) - Set
**InputPolicy**Policy:`DROP` - Set
**OutputPolicy**Policy:`ACCEPT`
DROP
ACCEPT
| Direction | Action | Protocol | Destination Port | Comment |
|---|---|---|---|---|
| IN | ACCEPT | TCP | 22 | SSH (for remote terminal access) |
| IN | ACCEPT | TCP | 5900-5910 | VNC (Proxmox console) |
Everything else inbound is dropped by default. We add more rules as needed when specific services are configured. This is the principle of *least privilege*privilege applied to network access: if a port has no defined, justified purpose, it is closed.
> **Note for VMware/XCP-ng
users**users: The equivalent of the Proxmox VM-level firewall in VMware Workstation is a combination of the host-level Windows Firewall and the VMware virtual network adapter settings. In XCP-ng, network policies are managed at the vSwitch level or using Open vSwitch (OVS) rules. The principle is identical regardless of platform — restrict inbound access to only what is required.
1.2.4 Adding the QEMU Guest Agent Channel
In the Proxmox web interface, with the VM selected, go to **Hardware > Add > VirtIO Serial Port**Port. This creates a communication channel that the QEMU guest agent inside the VM will use. Without this, the guest agent cannot communicate with Proxmox even after it is installed inside the VM.
1.2.5 Enabling 3D Acceleration
For the Cinnamon desktop to perform well, we need to enable the virtual GPU's 3D acceleration. In the Proxmox web interface, select the VM and go to **Hardware**Hardware. If a **Display**Display device is listed, click on it and edit it. Set the type to **VirtIO-GPU**GPU and ensure **3D acceleration**acceleration is checked. If no Display device is listed, add one via **Hardware > Add > Display Device**Device.
This requires that the Proxmox host has the `virtio- packages available, which are included in Proxmox VE 8.x by default. Without 3D acceleration, the Cinnamon desktop compositor will fall back to software rendering, which makes the desktop noticeably sluggish on animations and window transitions.gl`gl
1.3 Installing Linux Mint 22.x
With the VM configured, we start it. In Proxmox, right-click the VM and select **Start**Start, then open the **Console**Console (the noVNC console in the web browser is fine for installation; we will switch to SSH once the system is up).
The VM will boot from the ISO into the Linux Mint live environment.
1.3.1 The Live Environment Check
Before running the installer, it is worth spending two minutes in the live environment to confirm that the virtual hardware is being detected correctly:
- Open the
**Files**Files application and confirm the filesystem is accessible. - Open a
**Terminal**Terminal and run`glxinfo | grep "OpenGL renderer". If 3D acceleration is working, this should report a VirtIO or llvmpipe renderer rather than a software fallback.` - Check network connectivity:
`ip addr— the VirtIO network adapter should have received a DHCP address.show`show
If any of these checks fail, the most common cause is a missing or mis-configured virtual hardware device in the Proxmox VM settings. Shut down, correct the settings, and restart.
1.3.2 Running the Installer
Double-click **Install Linux Mint**Mint on the desktop.
Work through the installer wizard:
Language: Select the appropriate language.
Keyboard Layout**Layout: Select and test the keyboard layout.
Multimedia Codecs**Codecs: Check **Install multimedia codecs**codecs. This installs the `ubuntu-restricted- package set, which includes the codec support needed for the Cinnamon desktop to function fully. There is no disadvantage to including this.extras`extras
Installation Type**Type: Select **Erase disk and install Linux Mint**Mint. Since this is a fresh VM with no prior data on the 80GB virtual disk, this is the correct option. There is no need to manually partition the disk at this stage.
>If manual partitioning is preferred (for example, to create a separate
`/partition), the installer provides a "Something else" option. For the purposes of this book, the default automatic partitioning is sufficient. A separatehome`home`/partition does make it marginally easier to reinstall the OS without losing home directory data, but with Proxmox snapshots available, this is less important than it would be on physical hardware.home`home
Timezone: Set correctly. This matters for log timestamps, which we will be examining in Part II when we build the `/var/ parser.log`log
User Account**Account:
- Your
name**name: Use a real or plausible name. - Computer
name**name:`mint-logic-— consistent with the Proxmox VM name.lab`lab - Username: Choose a short, lowercase username (e.g.,
`logicdev`logicdev). This will appear in all terminal prompts and file paths throughout the book. - Password: Use a strong password. This is a development machine, not a throwaway container. Since it will eventually be running automated processes with real system permissions, the initial account password matters.
- Require password to log
in**in: Yes. - Do
**not**not enable automatic login.
Click **Continue**Continue and allow the installation to complete. The installer will copy the system, install bootloader (GRUB for UEFI), and ask to restart.
When prompted, click **Restart Now**Now. The console will display a message to remove the installation media. In Proxmox, the ISO is automatically detached on shutdown when the **Remove ISO after install**install option was set, or we can manually detach it: VM > Hardware > CD/DVD Drive > Edit > select "Do not use any media".
1.3.3 First Boot and Initial Configuration
On first boot, the system will load into the Cinnamon desktop and display the **Welcome Screen**Screen. Close it for now; we will return to it briefly in a moment.
Install the QEMU Guest Agent**
Open a terminal (`Ctrl+Alt+ or via the application menu) and run:T`T
sudo apt updateReturn to the Proxmox web interface. The VM's IP address should now appear in the **Summary**Summary tab. This confirms the guest agent is communicating correctly.
Update the System**
sudo apt update && sudo apt upgrade -yThis will pull the latest package updates for the Ubuntu 24.04 LTS base that Mint 22.x is built upon. On a fresh install there are typically several security updates available. Apply them all.
After the upgrade completes, reboot:
sudo rebootConfigure SSH Access**
For day-to-day work, the Proxmox noVNC console is functional but not pleasant for extended coding sessions. SSH into the VM from the host machine or another terminal gives a much better experience. On the VM:
sudo apt install openssh-server -yCheck the VM's IP address:
ip addr showNote the IP on the `ens18`ens18 or `eth0`eth0 interface (the name depends on the Proxmox network configuration). From the Proxmox host or another machine on the same network:
ssh logicdev@<vm-ip>For improved security, disable password authentication and use SSH key authentication instead. If a public key has already been configured on the homelab:
On the VM:
mkdir -p ~/.sshThen edit the SSH daemon configuration:
sudo nano /etc/ssh/sshd_configFind and set (or add) these lines:
PasswordAuthentication noRestart SSH:
sudo systemctl restart sshFrom this point forward, all terminal work in this book can be performed over SSH. The Proxmox console remains available as a fallback if SSH access is lost.
Take a Proxmox Snapshot**
Before installing any additional software, take a snapshot of the VM in its clean state. This is a habit that will save hours of reinstallation work when an experimental package or configuration change breaks something.
In the Proxmox web interface:
Snapshots in Proxmox are instantaneous for VMs on ZFS or LVM-thin storage. On directory storage, they are slightly slower. Either way, this takes under a minute and provides a clean rollback point.
1.4 Installing SWI-Prolog 10.x
With the base system in a clean, snapshotted state, we now install SWI-Prolog. The version matters significantly here. SWI-Prolog 10.x is the current stable development series as of 2026, and it includes several features — most notably the native Dict type, improved string handling, and the tabling infrastructure — that are central to the work in this book. We do not want to accidentally install the older 9.x or 8.x version that may appear in the Ubuntu/Mint default package repositories.
1.4.1 Checking the Default Repository Version
First, let us see what version the Mint package repository offers:
apt-cache show swi-prolog | grep VersionIf this returns a version below `10., we need to use an alternative installation source. As of mid-2026, the Ubuntu 24.04 LTS repository may still carry an older stable version. We will use the official SWI-Prolog PPA to ensure we get 10.x.0`0
1.4.2 Installing via the SWI-Prolog PPA
The SWI-Prolog project maintains an official PPA (Personal Package Archive) for Ubuntu-based systems. This is the recommended installation method for Mint 22.x.
sudo apt install software-properties-common -y> **Security note on
PPAs**PPAs: A PPA is a third-party package repository. Before adding any PPA, it is good practice to verify its ownership. The`swi-prolog/PPA is maintained by the SWI-Prolog project itself and has been in continuous operation since SWI-Prolog's early Ubuntu packaging work. The GPG key added bystable`stable`add-apt-ensures that packages from this PPA are signed by the PPA owner. If at any pointrepository`repository`apt`aptreports a GPG key error for this PPA, stop and investigate before proceeding.
Verify the installation:
swipl --versionThe output should show a version in the `10.x. series, for example:x`x
SWI-Prolog version 10.x.x for x86_64-linux1.4.3 The First Terminal Conversation
Let us confirm that the engine is working correctly with a direct interactive session. This is not yet a meaningful logic program; it is a system check.
Start the SWI-Prolog interactive top-level (the REPL):
swipl
```bash
The prompt changes to:
Welcome to SWI-Prolog (threaded, 64 bits, version 10.x.x)The `?- is the query prompt. Type the following and press Enter:`
?- write('Logic laboratory is operational.'), nl.The engine should respond:
Logic laboratory is operational.Then:
?- current_prolog_flag(version, V).This queries the engine for its own version flag. The response will be:
V = 10XXYY.where `10XXYY`10XXYY encodes the major, minor, and patch version as a single integer. For SWI-Prolog 10.2.3, this would be `100203`100203. This confirms we are running a 10.x engine.
Exit the REPL:
?- halt.Take another snapshot: `01-swi-prolog-.installed`installed
1.4.4 Understanding the SWI-Prolog Directory Layout
When SWI-Prolog is installed via the PPA, its files are distributed across standard Linux filesystem locations. Understanding this layout is important for the work ahead.
which swiplKey directories:
| Path | Contents |
|---|---|
/usr/bin/ |
Main executable |
/usr/lib/swi-prolog/ |
Libraries, boot files, C libraries |
/usr/lib/swi-prolog/library/ |
The standard library of built-in Prolog predicates |
~/.local/share/swi-prolog/pack/ |
Packs installed by the current user (we will use this in later chapters) |
/usr/share/doc/swi-prolog/ |
Installed documentation |
The most important of these during early development is the `library/ directory. Every time we use a directive like ``:- use_module(library(lists)). in a Prolog source file, the engine looks here. Understanding that ``library(lists) corresponds to a physical file ``/usr/lib/swi-prolog/library/lists. demystifies the module system considerably.pl`pl
1.5 Installing Go
Go (Golang) will be introduced in depth in Part III of this book. However, we install it now for two reasons. First, we want to take a snapshot of the complete development environment as a single, known-good baseline. Second, several of the system utilities referenced in the VS Code setup below are written in Go, and having the Go toolchain available from the start avoids installation interruptions later.
1.5.1 Choosing the Installation Method
There are three common ways to install Go on an Ubuntu-based system:
- The
`golang-package from the Ubuntu repository.go`go - The official Go binary distribution from
`go..dev`dev snap install.go`go
We use method 2. The Ubuntu repository package is often one or two minor versions behind the current stable release, and Go minor versions frequently include performance improvements and new standard library features that we will use. The `snap`snap version works, but adds a layer of indirection that is unnecessary on a VM we control directly.
1.5.2 Installing the Go Toolchain
On the VM terminal:
# Replace the URL and filename with the current stable release if newerNow configure the shell environment. Open the profile file for the current user:
nano ~/.bashrcAdd these lines at the end:
# Go toolchainApply the changes to the current session:
source ~/.bashrcVerify:
go versionA note on GOPATH**GOPATH: In Go 1.11 and later, the module system (`go ) has largely replaced the older mod`mod`GOPATH`GOPATH-based project layout for new code. However, `GOPATH`GOPATH still determines where Go installs binaries built with `go , so it remains relevant. We set it to install`install`~/ which is the conventional default.go`go
1.6 Configuring VS Code
The integrated development environment we use throughout this book is Visual Studio Code. It is free, open-source, and has an exceptional extension ecosystem for both Prolog and Go. The key requirement is the combination of the **Prolog Language Server Protocol (LSP)** extension and the **Go extension**extension, which together provide inline error checking, code completion, and the ability to run Prolog and Go code side by side.
1.6.1 Installing VS Code
sudo apt install wget gpg -yVS Code can be opened from the application menu or by typing `code`code in the terminal.
1.6.2 Installing the Prolog LSP Extension
The Prolog Language Server Protocol extension connects VS Code to a running SWI-Prolog LSP server, providing real-time syntax checking, predicate completion, and documentation hover. Open VS Code and:
- Press
`Ctrl+Shift+to open the Extensions panel.X`X - Search for
**"VSC-Prolog"**— the extension by Arthur Wang. - Click
**Install**Install.
Once installed, open VS Code's settings (`Ctrl+,) and search for ``prolog`prolog. Configure:
- Prolog: Executable
Path**Path:`/usr/bin/swipl` - Prolog:
Dialect**Dialect:`swi`
swi
The extension will start a background LSP server the first time a `. file is opened. If it does not start automatically, the most common cause is that pl`pl`swipl`swipl is not in the path that VS Code uses. Confirm by opening the VS Code integrated terminal (`Ctrl+`` ) and running ``which .swipl`swipl
1.6.3 Installing the Go Extension
- In the Extensions panel, search for
**"Go"**— the extension by the Go Team at Google. - Click
**Install**Install.
After installation, VS Code will display a notification: "The 'Go' extension recommends installing additional tools." Click **Install All**All. This installs several Go tools into `$GOPATH/:bin`bin
gopls— the Go Language Serverdlv— the Delve debuggerstaticcheck— a static analysis toolgotools— formatting and import management
These tools require the Go toolchain to be in the path, which we configured in section 1.5.2. If the "Install All" operation fails, open the VS Code integrated terminal and confirm that `go returns correctly.version`version
1.6.4 Setting Up the Workspace Layout
We will use a consistent workspace layout throughout all parts of this book. Create the following directory structure in the home directory:
mkdir -p ~/logic-lab/{prolog,go,shared,logs,knowledge-bases}| Directory | Purpose |
|---|---|
~/logic-lab/prolog/ |
All . source files |
~/logic-lab/go/ |
All Go module directories |
~/logic-lab/shared/ |
Data files shared between Prolog and Go (JSON, CSV) |
~/logic-lab/logs/ |
Log files for the DCG parser tutorials in Part II |
~/logic-lab/knowledge-bases/ |
Standalone KB files that grow throughout the book |
Open VS Code and add this directory as a workspace: