mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 19:52:29 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			129 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			129 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)
 |