PeshMind - Prolog-based Engine for System & Host Management and INference
This repo is reachable at https://github.com/mmirko/peshmind.git
Prolog-based Engine for System & Host Management and INference Daemon
PeshMind is a network topology discovery and analysis tool that uses Prolog inference to reconstruct LAN network topology based solely on MAC addresses observed by network switches. The system combines a Go-based CLI application with a Prolog reasoning engine to identify network connections, internal/edge switches, and potential ghost switches in the network infrastructure.
Table of Contents
- Features
- Architecture
- Prerequisites
- Installation
- Configuration
- Usage
- Prolog Inference Rules
- Configuration File Format
- License
Features
- Automatic Network Topology Discovery: Infers network connections from MAC address tables
- Prolog-based Reasoning: Uses logical inference to determine switch relationships and connectivity
- Ghost Switch Detection: Identifies switches that exist in the network but are not directly managed
- Network Visualization: Generates DOT files for graphical network topology representation
- Simulation Mode: Test and validate network topologies using simulated switch data
- Multiple Switch Models Support: Currently supports HP-Aruba and HP-Aruba-Press switches
- RESTful Prolog Engine: Serves Prolog queries via HTTP using Pengines
Architecture
PeshMind consists of three main components:
- Go CLI Application: Manages switches, fetches data, and interacts with the Prolog engine
- Prolog Inference Engine: Analyzes MAC address relationships and infers network topology
- Knowledge Base: Stores switch and MAC address data in Prolog facts
The system workflow:
- Fetch MAC address tables from physical switches
- Convert switch data to Prolog facts (
switch/1,switchname/2,seen/3) - Load facts into Prolog engine with inference rules
- Query the engine to discover topology, connectivity, and ghost switches
- Visualize results using DOT graphs
Prerequisites
- Go: Version 1.23.3 or higher
- SWI-Prolog: Required for the Prolog inference engine
- Expect: Used for automated switch SSH sessions (included in templates)
- Graphviz (optional): For rendering DOT files to images
Installing Dependencies
Ubuntu/Debian
sudo apt-get update
sudo apt-get install swi-prolog expect graphviz
macOS
brew install swi-prolog expect graphviz
Fedora/RHEL
sudo dnf install pl expect graphviz
Installation
- Clone the repository:
git clone https://github.com/mmirko/peshmind.git
cd peshmind
- Build the application:
go build -o peshmind
- (Optional) Install globally:
sudo cp peshmind /usr/local/bin/
Configuration
Create a peshmind.json configuration file in your working directory:
{
"debug": true,
"endpoint": "http://localhost:3030/pengine",
"switches": {
"switch-01": {
"name": "switch-01",
"mac": "aabbccddeeff",
"description": "Core Switch Floor 1",
"ip": "192.168.1.10",
"username": "admin",
"password": "ask",
"model": "HP-Aruba",
"port": 48,
"extraports": [],
"data": ""
}
}
}
Configuration Fields
- debug: Enable verbose output
- endpoint: URL of the Prolog Pengines HTTP endpoint
- switches: Dictionary of switch configurations
- name: Unique switch identifier
- mac: Switch MAC address (without separators)
- description: Human-readable description
- ip: Management IP address
- username: SSH username
- password: SSH password (use “ask” for interactive input)
- model: Switch model (
HP-ArubaorHP-Aruba-Press) - port: Number of physical ports
- extraports: Additional ports to monitor
- data: Internal field for fetched data
Usage
List Switches
Display all configured switches:
peshmind list
Update Switch Data
Fetch MAC address tables from switches and save to knowledge base:
# Update a specific switch
peshmind update --switch switch-01
# Update all switches
peshmind update --switch all
The command will:
- Prompt for admin password if configured as “ask”
- Connect to switch via SSH
- Fetch MAC address table
- Parse and convert to Prolog facts
- Save to
kbpool/<switch-name>.pl
Serve Prolog Engine
Start the Prolog inference engine with HTTP endpoint:
peshmind serve --kbpool kbpool
This will:
- Check for SWI-Prolog installation
- Create consolidated knowledge base (
data.pl) - Start Prolog HTTP server on port 3030
- Wait for queries via Pengines interface
Press Ctrl+C to stop the server.
Query the Network
Query the running Prolog engine for network topology information:
# Find all switches
peshmind query "switch(X)"
# Find switch names
peshmind query "switchname(X,Name)"
# Find directly connected switches
peshmind query "directn(Switch1,Switch2)"
# Find switches with specific relationships
peshmind query "directpn(X,Y,PortX,PortY)"
# Detect ghost switches
peshmind query "ghostn(X,Y)"
# Identify edge switches
peshmind query "edgeswitchn(X)"
# Identify internal switches
peshmind query "internalswitchn(X)"
Generate Network Topology Visualization
Generate a DOT file representing the physical network topology:
peshmind dot > network.dot
Render to image:
dot -Tpng network.dot -o network.png
# or
neato -Tpng network.dot -o network.png
The DOT output includes:
- Switches in clusters with their ports
- Physical connections between ports
- Ghost switches (unmanaged intermediate switches)
- Color-coded representation
Simulate Network Topology
Test and validate network topologies using simulation mode:
# Basic simulation
peshmind simulate --simname simpool/topology4.dot
# With DOT visualization output
peshmind simulate --simname simpool/topology4.dot --emit-dot topology4-sim.dot
# With Prolog facts output
peshmind simulate --simname simpool/topology4.dot --output topology4.pl
# Control generation percentage (for testing partial networks)
peshmind simulate --simname simpool/topology4.dot --sim-generate-percentage 75
Simulation topology files use DOT format with special attributes:
ghost="true": Mark ghost switchesport="N": Specify connection portmac="...": MAC address for ghost switches
Prolog Inference Rules
The system uses several Prolog predicates to infer network topology:
Base Facts
switch(MacAddr): Declares a switch existsswitchname(MacAddr, Name): Associates a MAC address with a switch nameseen(SwitchMac, DeviceMac, Port): Records that a switch saw a MAC address on a specific port
Inferred Predicates
far(X,Y): Two switches are separated by an intermediate switchdirect(X,Y): Two switches are directly connected (not far)directp(X,Y,PortX,PortY): Direct connection with specific port informationghost(X,Y): Unmanaged switch detected between X and Yinternalswitch(X): Switch connected to multiple other switchesedgeswitch(X): Switch connected to only one other switch (access layer)edgeswitchp(X,Port): Edge switch with specific port
All predicates have *n variants that use switch names instead of MAC addresses (e.g., directn/2, ghostn/2).
License
Copyright © 2026 Mirko Mariotti mirko@mirkomariotti.it
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.