mirror of
https://github.com/Z3Prover/z3
synced 2025-04-04 16:44:07 +00:00
130 lines
3.6 KiB
Python
130 lines
3.6 KiB
Python
# Copyright (c) Microsoft Corporation 2015
|
|
"""
|
|
Tactic documentation generator script
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
import subprocess
|
|
|
|
BUILD_DIR='../build'
|
|
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
|
|
OUTPUT_DIRECTORY = os.path.join(os.getcwd(), 'api')
|
|
|
|
def doc_path(path):
|
|
return os.path.join(SCRIPT_DIR, path)
|
|
|
|
is_doc = re.compile("Tactic Documentation")
|
|
is_doc_end = re.compile("\-\-\*\/")
|
|
is_tac_name = re.compile("## Tactic (.*)")
|
|
is_simplifier = re.compile("ADD_SIMPLIFIER\(.*\"([^\"]*)\".*,.*\"([^\"]*)\".*,.*\"([^\"]*)\"\.*\)")
|
|
|
|
def is_ws(s):
|
|
return all([0 for ch in s if ch != ' ' and ch != '\n'])
|
|
|
|
def extract_params(ous, tac):
|
|
z3_exe = BUILD_DIR + "/z3"
|
|
out = subprocess.Popen([z3_exe, f"-tacticsmd:{tac}"], stdout=subprocess.PIPE).communicate()[0]
|
|
if not out:
|
|
return
|
|
out = out.decode(sys.getdefaultencoding())
|
|
if is_ws(out):
|
|
return
|
|
ous.write("### Parameters\n\n")
|
|
for line in out:
|
|
ous.write(line.replace("\r",""))
|
|
ous.write("\n")
|
|
|
|
def generate_tactic_doc(ous, f, ins):
|
|
tac_name = None
|
|
for line in ins:
|
|
m = is_tac_name.search(line)
|
|
if m:
|
|
tac_name = m.group(1)
|
|
if is_doc_end.search(line):
|
|
if tac_name:
|
|
extract_params(ous, tac_name)
|
|
break
|
|
ous.write(line)
|
|
|
|
def extract_tactic_doc(ous, f):
|
|
with open(f) as ins:
|
|
for line in ins:
|
|
if is_doc.search(line):
|
|
generate_tactic_doc(ous, f, ins)
|
|
|
|
def generate_simplifier_doc(ous, name, desc):
|
|
ous.write("## Simplifier [" + name + "](https://microsoft.github.io/z3guide/docs/strategies/summary/#tactic-" + name + ")\n")
|
|
ous.write("### Description\n" + desc + "\n")
|
|
|
|
|
|
def extract_simplifier_doc(ous, f):
|
|
with open(f) as ins:
|
|
for line in ins:
|
|
m = is_simplifier.search(line)
|
|
if m:
|
|
generate_simplifier_doc(ous, m.group(1), m.group(2))
|
|
|
|
def find_tactic_name(path):
|
|
with open(path) as ins:
|
|
for line in ins:
|
|
m = is_tac_name.search(line)
|
|
if m:
|
|
return m.group(1)
|
|
print(f"no tactic in {path}")
|
|
return ""
|
|
|
|
def find_simplifier_name(path):
|
|
with open(path) as ins:
|
|
for line in ins:
|
|
m = is_simplifier.search(line)
|
|
if m:
|
|
return m.group(1)
|
|
print(f"no simplifier in {path}")
|
|
return ""
|
|
|
|
def presort_files(find_fn):
|
|
tac_files = []
|
|
for root, dirs, files in os.walk(doc_path("../src")):
|
|
for f in files:
|
|
if f.endswith("~"):
|
|
continue
|
|
if f.endswith("tactic.h") or "simplifiers" in root:
|
|
tac_files += [(f, os.path.join(root, f))]
|
|
tac_files = sorted(tac_files, key = lambda x: find_fn(x[1]))
|
|
return tac_files
|
|
|
|
|
|
def help(ous):
|
|
ous.write("---\n")
|
|
ous.write("title: Tactics Summary\n")
|
|
ous.write("sidebar_position: 6\n")
|
|
ous.write("---\n")
|
|
tac_files = presort_files(find_tactic_name)
|
|
for file, path in tac_files:
|
|
extract_tactic_doc(ous, path)
|
|
|
|
|
|
|
|
def help_simplifier(ous):
|
|
ous.write("---\n")
|
|
ous.write("title: Simplifiers Summary\n")
|
|
ous.write("sidebar_position: 7\n")
|
|
ous.write("---\n")
|
|
tac_files = presort_files(find_simplifier_name)
|
|
for file, path in tac_files:
|
|
extract_simplifier_doc(ous, path)
|
|
|
|
def mk_dir(d):
|
|
if not os.path.exists(d):
|
|
os.makedirs(d)
|
|
|
|
mk_dir(os.path.join(OUTPUT_DIRECTORY, 'md'))
|
|
|
|
with open(OUTPUT_DIRECTORY + "/md/tactics-summary.md",'w') as ous:
|
|
help(ous)
|
|
|
|
with open(OUTPUT_DIRECTORY + "/md/simplifier-summary.md",'w') as ous:
|
|
help_simplifier(ous)
|