Current imitation learning approaches, predominantly based on deep neural networks (DNNs), offer efficient mechanisms for learning driving policies from real-world datasets. However, they suffer from inherent limitations in interpretability and generalizability—issues of critical importance in safety-critical domains such as autonomous driving. In this paper, we introduce Symbolic Imitation Learning (SIL), a novel framework that leverages Inductive Logic Programming (ILP) to derive explainable and generalizable driving policies from synthetic datasets. We evaluate SIL on real-world HighD and NGSim datasets, comparing its performance with state-of-the-art neural imitation learning methods using metrics such as collision rate, lane change efficiency, and average speed. The results indicate that SIL significantly enhances policy transparency while maintaining strong performance across varied driving conditions. These findings highlight the potential of integrating ILP into imitation learning to promote safer and more reliable autonomous systems.
In order to extract the bias.pl, bk.pl, and exs.pl files for each action in Safety, Efficiecy, and Smoothness categories, the bias_bk_exs_generator.py in dataset-generation/ is used to generate files.
There are other file which can help with extracting scenarios from the HighD dataset: dataset-generation/extract_examples.py.
In order to add noise to the dataset labels, we refer to flip_labels.py.
This directory contains subfolders corresponding to different semantic tasks. Each of these contains further subfolders that each represent a specific scenario or rule-learning target.
Each lowest-level folder contains three files:
bias.pl— bias settings for the rule learner (e.g., allowed predicates, head predicate)bk.pl— background knowledge (domain facts/rules)exs.pl— labeled examples (positive/negative)- (Optionally, after rule extraction,
extracted_rules.pl— the result file with learned rules)
Below is a current snapshot of the actual directory structure under data/:
data/
├── fatal_lane_changing/
│ ├── RLC/
│ │ ├── bias.pl
│ │ ├── bk.pl
│ │ ├── exs.pl
│ │ └── extracted_rules.pl
│ ├── LLC/
│ │ ├── bias.pl
│ │ ├── bk.pl
│ │ ├── exs.pl
│ │ └── extracted_rules.pl
├── risky_lane_changing/
│ ├── LK/
│ │ ├── bias.pl
│ │ ├── bk.pl
│ │ ├── exs.pl
│ │ └── extracted_rules.pl
│ ├── RLC/
│ │ ├── bias.pl
│ │ ├── bk.pl
│ │ ├── exs.pl
│ │ └── extracted_rules.pl
│ ├── LLC/
│ │ ├── bias.pl
│ │ ├── bk.pl
│ │ ├── exs.pl
│ │ └── extracted_rules.pl
Note: Only a subset of files and directories are shown due to search result limitations. For the complete structure, see the data/ directory in GitHub.
- Each task (like
LK,LLC,RLC, etc.) contains the input files (bias.pl,bk.pl,exs.pl) and may containextracted_rules.plonce rule extraction is complete. - This structure can be extended as you add more tasks or categories.
- Popper (GitHub): Install Popper following the instructions in its repository.
- SWI-Prolog: Popper requires SWI-Prolog.
- Python (with PySwip): Install PySwip (
pip install pyswip) for Python-Prolog interaction.
PopperSWI-PrologPython >=3.6PySwip(pip install pyswip)
-
Navigate to the Target Directory
Example:cd data/risky_lane_changing/LK -
Prepare Popper Input
Popper expects three files:bk.pl,bias.pl, andexs.pl(already provided in each folder). -
Run Popper
Assuming Popper is cloned and set up:swipl path/to/popper/popper.pl --bk=bk.pl --bias=bias.pl --exs=exs.pl
This will print the learned rules to the console.
-
Save the Rules
Copy the output (the learned rule(s)) and save it inextracted_rules.plinside the same folder.
Example:increase_velocity :- ego_velocity_is_legal, front_is_free; front_velocity_is_bigger, front_distance_is_safe, ego_velocity_is_legal.
-
Repeat for Each Setting
Repeat the above steps for every subfolder (e.g.,data/risky_lane_changing/LLC,data/fatal_lane_changing/RLC, etc.).
You can use PySwip to interact with Prolog and the learned rules from Python. Example usage:
from pyswip import Prolog
prolog = Prolog()
prolog.consult("bk.pl")
prolog.consult("extracted_rules.pl")
# Query using the learned rule
results = list(prolog.query("increase_velocity(X)"))
print(results)After doing all the settings, to see how the SIL framework performs at on the HighD dataset, run train.py file.
For more information regarding how to connect PySwip to Python, see the Safe-Reinforcement-Learning-using-Symbolic-Logical-Programming-for-Autonomous-Highway-Driving repository.
This allows you to use the background knowledge and extracted rules directly in your Python code.
- Make sure Popper and SWI-Prolog are correctly installed and accessible from your command line.
- If you wish to automate extraction for all datasets, consider writing a shell or Python script to iterate through all task/subtask folders.
- For more details on Popper usage, see the Popper repository.
- For more details on PySwip, see the PySwip repository.
If you update your workflow or use additional scripts, please update this README to reflect your actual process!