isabelle_client/
process.rs1use std::{
2 collections::HashMap,
3 io,
4 path::PathBuf,
5 process::{Output, Stdio},
6};
7use tokio::process::Command;
8
9#[derive(Default)]
11pub struct ProcessArgs {
12 pub theories: Vec<String>,
14 pub session_dirs: Vec<String>,
16 pub logic: Option<String>,
18 pub options: HashMap<String, String>,
21}
22
23impl ProcessArgs {
24 pub fn load_theories(ths: &[String]) -> Self {
25 Self {
26 theories: ths.to_vec(),
27 ..Default::default()
28 }
29 }
30}
31
32pub async fn batch_process(
50 args: &ProcessArgs,
51 current_dir: Option<&PathBuf>,
52) -> io::Result<Output> {
53 let mut isabelle_cmd = Command::new("isabelle");
54
55 isabelle_cmd
56 .arg("process")
57 .stderr(Stdio::piped())
58 .stdout(Stdio::piped());
59
60 if let Some(cd) = current_dir {
61 isabelle_cmd.current_dir(cd);
62 }
63
64 for t in &args.theories {
65 isabelle_cmd.arg("-T").arg(t);
66 }
67 for d in &args.session_dirs {
68 isabelle_cmd.arg("-d").arg(d);
69 }
70
71 if let Some(l) = &args.logic {
72 isabelle_cmd.arg("-l").arg(l);
73 }
74
75 for (k, v) in args.options.iter() {
76 isabelle_cmd.arg("-o").arg(format!("{}={}", k, v));
77 }
78
79 isabelle_cmd.spawn()?.wait_with_output().await
80}
81
82#[derive(Default)]
84pub struct OptionsBuilder {
85 options: HashMap<String, String>,
86}
87
88impl From<OptionsBuilder> for HashMap<String, String> {
89 fn from(val: OptionsBuilder) -> Self {
91 val.options
92 }
93}
94
95impl OptionsBuilder {
96 pub fn new() -> Self {
97 Self {
98 ..Default::default()
99 }
100 }
101
102 fn add_int_option(&mut self, k: &str, v: isize) -> &mut Self {
103 self.options.insert(k.to_owned(), v.to_string());
104 self
105 }
106
107 fn add_bool_option(&mut self, k: &str, v: bool) -> &mut Self {
108 self.options.insert(k.to_owned(), v.to_string());
109 self
110 }
111
112 fn add_real_option(&mut self, k: &str, v: f32) -> &mut Self {
113 self.options
114 .insert(k.to_owned(), v.to_string().to_lowercase());
115 self
116 }
117
118 pub fn threads(&mut self, threads: isize) -> &mut Self {
120 self.add_int_option("threads", threads)
121 }
122
123 pub fn thread_stack_limit(&mut self, limit: f32) -> &mut Self {
125 self.add_real_option("threads_stack_limit", limit)
126 }
127
128 pub fn parallel_limit(&mut self, limit: isize) -> &mut Self {
130 self.add_int_option("parallel_limit", limit)
131 }
132
133 pub fn parallel_proofs(&mut self, limit: isize) -> &mut Self {
135 self.add_int_option("parallel_proofs", limit)
136 }
137
138 pub fn timeout_scale(&mut self, scale: f32) -> &mut Self {
140 self.add_real_option("timeout_scale", scale)
141 }
142
143 pub fn record_proofs(&mut self, level: isize) -> &mut Self {
147 self.add_int_option("record_proofs", level)
148 }
149
150 pub fn quick_and_dirty(&mut self, flag: bool) -> &mut Self {
152 self.add_bool_option("quick_and_dirty", flag)
153 }
154
155 pub fn skip_proofs(&mut self, flag: bool) -> &mut Self {
157 self.add_bool_option("skip_proofs", flag)
158 }
159
160 pub fn timeout(&mut self, limit: f32) -> &mut Self {
164 self.add_real_option("timeout", limit)
165 }
166
167 pub fn timeout_build(&mut self, flag: bool) -> &mut Self {
169 self.add_bool_option("timeout_build", flag)
170 }
171
172 pub fn process_output_limit(&mut self, limit: isize) -> &mut Self {
174 self.add_int_option("process_output_limit", limit)
175 }
176
177 pub fn process_output_tail(&mut self, tail: isize) -> &mut Self {
179 self.add_int_option("process_output_tail", tail)
180 }
181
182 pub fn pide_reports(&mut self, flag: bool) -> &mut Self {
186 self.add_bool_option("pide_reports", flag)
187 }
188
189 pub fn build_pide_reports(&mut self, flag: bool) -> &mut Self {
191 self.add_bool_option("build_pide_reports", flag)
192 }
193}