Assign keyboard mnemonics to a list of options. Given a set of options in a menu, we want to assign a mnemonic to every option such that there are not two options with the same mnemonic. The solution has to meet the following constraints:
- Each option must have a mnemonic.
- An option cannot have more than one mnemonic.
- A given character cannot be a mnemonic of two different options.
The problem can be reduced to a SAT. This repository includes the formalization and the implementation. It uses Z3's bindings in TypeScript.
Each option i in the menu has a set of characters associated with it, a set called 1 is "Undo",
The task is to determine whether a particular character c is the mnemonic for a specific i.
The menu with
Here,
Let's consider options "undo", "copy", "mod" which can be written as:
Uu1, Un1, Ud1, Uo1
Uc2, Uo2, Up2, Uy2
Um3, Uo3, Ud3
graph TD
A[Menu Options] --> B["Option 1: Chars(1) = {u, n, d, o}"]
A --> C["Option 2: Chars(2) = {c, o, p, y}"]
A --> D["Option 3: Chars(3) = {m, o, d}"]
B --> |Mnemonic: U| E["U(u,1) = True"]
C --> |Mnemonic: Y| F["U(y,2) = True"]
D --> |Mnemonic: D| G["U(d,3) = True"]
This constraint ensures that every option has at least one character assigned as its mnemonic. Formally, for each option i, at least one of the Boolean variables true:
Formalization according to our example:
If a character is chosen, no other character for the same option can be a mnemonic. Formally, for each option i and each character c in Chars(i), if true, then all
other characters t in Chars(i) must have false:
Formalization according to our example:
This constraint ensures that no single character is used as the mnemonic for more than one option. Formally, for each option i and each character c in Chars(i), if true, then c
cannot be the mnemonic for any other option j where j ≠ i:
Formalization according to our example:
OS X & Linux:
Install Node with asdf (version manager):
asdf install
Install dependencies:
npm installDefine options in index.ts:
// Menu options
const OPTIONS = ["cut", "copy", "cost"];Run program:
npm startThe program will print the answers:
Starting...
Problem was determined to be sat in 252 ms
---- Result: option [mnemonic] ----
cut u
copy y
mod d
For more details on the problem and the implementation, visit the blogpost.
Assignment from "Static Program Analysis and Constraint Solving" at Universidad Complutense de Madrid. Prof. Manuel Montenegro.