|
|
|
@ -19,28 +19,41 @@ fn backup_file_path(file_path: &std::path::Path) -> Result<std::path::PathBuf, a
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn find_conjecture<'a>(project: &'a ask_dracula::Project) -> Option<(ask_dracula::project::StatementKind, &'a foliage::Formula)> |
|
|
|
|
fn find_conjecture<'a, 'input>(project: &'a ask_dracula::Project<'input>) -> Option<&'a ask_dracula::project::Statement<'input>> |
|
|
|
|
{ |
|
|
|
|
if let Some(lemmas) = project.statements.get(&ask_dracula::project::StatementKind::Lemma) |
|
|
|
|
for block in &project.blocks |
|
|
|
|
{ |
|
|
|
|
if let Some(lemma) = lemmas.first() |
|
|
|
|
if let ask_dracula::project::Block::Statement(ref statement) = block |
|
|
|
|
{ |
|
|
|
|
return Some((ask_dracula::project::StatementKind::Lemma, lemma)); |
|
|
|
|
if statement.kind == ask_dracula::project::StatementKind::Lemma |
|
|
|
|
|| statement.kind == ask_dracula::project::StatementKind::Conjecture |
|
|
|
|
{ |
|
|
|
|
return Some(statement) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let Some(conjectures) = project.statements.get(&ask_dracula::project::StatementKind::Conjecture) |
|
|
|
|
None |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn find_conjecture_mut<'a, 'input>(project: &'a mut ask_dracula::Project<'input>) -> Option<&'a mut ask_dracula::project::Statement<'input>> |
|
|
|
|
{ |
|
|
|
|
for block in &mut project.blocks |
|
|
|
|
{ |
|
|
|
|
if let Some(conjecture) = conjectures.first() |
|
|
|
|
if let ask_dracula::project::Block::Statement(ref mut statement) = block |
|
|
|
|
{ |
|
|
|
|
return Some((ask_dracula::project::StatementKind::Conjecture, conjecture)); |
|
|
|
|
if statement.kind == ask_dracula::project::StatementKind::Lemma |
|
|
|
|
|| statement.kind == ask_dracula::project::StatementKind::Conjecture |
|
|
|
|
{ |
|
|
|
|
return Some(statement) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
None |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum VampireResult |
|
|
|
|
enum ProofResult |
|
|
|
|
{ |
|
|
|
|
ProofNotFound, |
|
|
|
|
Refutation, |
|
|
|
@ -48,7 +61,7 @@ enum VampireResult
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn run_vampire<I, S>(input: &str, arguments: Option<I>) |
|
|
|
|
-> Result<VampireResult, ask_dracula::Error> |
|
|
|
|
-> Result<ProofResult, ask_dracula::Error> |
|
|
|
|
where I: IntoIterator<Item = S>, S: AsRef<std::ffi::OsStr> |
|
|
|
|
{ |
|
|
|
|
let mut vampire = std::process::Command::new("vampire"); |
|
|
|
@ -59,6 +72,8 @@ fn run_vampire<I, S>(input: &str, arguments: Option<I>)
|
|
|
|
|
None => &mut vampire, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//eprintln!("{}", input);
|
|
|
|
|
|
|
|
|
|
let mut vampire = vampire |
|
|
|
|
.stdin(std::process::Stdio::piped()) |
|
|
|
|
.stdout(std::process::Stdio::piped()) |
|
|
|
@ -89,7 +104,7 @@ fn run_vampire<I, S>(input: &str, arguments: Option<I>)
|
|
|
|
|
|
|
|
|
|
if proof_not_found_regex.is_match(stdout) |
|
|
|
|
{ |
|
|
|
|
return Ok(VampireResult::ProofNotFound); |
|
|
|
|
return Ok(ProofResult::ProofNotFound); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return Err(ask_dracula::Error::new_run_vampire( |
|
|
|
@ -100,7 +115,7 @@ fn run_vampire<I, S>(input: &str, arguments: Option<I>)
|
|
|
|
|
|
|
|
|
|
if refutation_regex.is_match(stdout) |
|
|
|
|
{ |
|
|
|
|
return Ok(VampireResult::Refutation); |
|
|
|
|
return Ok(ProofResult::Refutation); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Err(ask_dracula::Error::new_interpret_vampire_output(stdout.to_string(), stderr.to_string())) |
|
|
|
@ -121,52 +136,60 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
|
|
|
|
let (_, mut project) = ask_dracula::parse::project(&file_content) |
|
|
|
|
.map_err(|_| "couldn’t parse input file")?; |
|
|
|
|
|
|
|
|
|
match find_conjecture(&project) |
|
|
|
|
let conjecture = find_conjecture(&project); |
|
|
|
|
|
|
|
|
|
let vampire_result = match conjecture |
|
|
|
|
{ |
|
|
|
|
None => |
|
|
|
|
{ |
|
|
|
|
eprintln!("no lemma or conjecture found, nothing to do"); |
|
|
|
|
return Ok(()); |
|
|
|
|
}, |
|
|
|
|
Some(ref conjecture) => |
|
|
|
|
{ |
|
|
|
|
eprintln!("verifying conjecture: {}", conjecture.formula); |
|
|
|
|
|
|
|
|
|
let tptp_content = format!("{}", ask_dracula::format_tptp::display_project_with_conjecture_tptp(&project, conjecture)); |
|
|
|
|
|
|
|
|
|
run_vampire(&tptp_content, matches.values_of("vampire_arguments").map(|value| value))? |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let conjecture = find_conjecture_mut(&mut project).unwrap(); |
|
|
|
|
|
|
|
|
|
match vampire_result |
|
|
|
|
{ |
|
|
|
|
ProofResult::ProofNotFound => |
|
|
|
|
{ |
|
|
|
|
println!("proof not found"); |
|
|
|
|
Ok(()) |
|
|
|
|
}, |
|
|
|
|
Some((ref statement_kind, ref conjecture)) => |
|
|
|
|
ProofResult::Refutation => |
|
|
|
|
{ |
|
|
|
|
eprintln!("verifying conjecture: {}", conjecture); |
|
|
|
|
println!("conjecture proven"); |
|
|
|
|
|
|
|
|
|
let tptp_content = format!("{}", ask_dracula::format_tptp::display_project_with_conjecture_tptp(&project, (statement_kind.clone(), conjecture))); |
|
|
|
|
conjecture.kind = ask_dracula::project::StatementKind::Axiom; |
|
|
|
|
let replace_statement_kind_regex = regex::Regex::new(r"(conjecture|lemma)").unwrap(); |
|
|
|
|
let new_text = replace_statement_kind_regex.replace(conjecture.original_text, "axiom"); |
|
|
|
|
conjecture.original_text = &new_text; |
|
|
|
|
|
|
|
|
|
match run_vampire(&tptp_content, matches.values_of("vampire_arguments").map(|value| value))? |
|
|
|
|
{ |
|
|
|
|
VampireResult::ProofNotFound => |
|
|
|
|
{ |
|
|
|
|
println!("proof not found"); |
|
|
|
|
Ok(()) |
|
|
|
|
}, |
|
|
|
|
VampireResult::Refutation => |
|
|
|
|
{ |
|
|
|
|
println!("conjecture proven"); |
|
|
|
|
|
|
|
|
|
let axiom = project.statements.get_mut(statement_kind).unwrap().remove(0); |
|
|
|
|
project.statements.entry(ask_dracula::project::StatementKind::Axiom).or_insert_with(Vec::new).push(axiom); |
|
|
|
|
|
|
|
|
|
let backup_file_path = backup_file_path(file_path)?; |
|
|
|
|
|
|
|
|
|
// Make backup of old file
|
|
|
|
|
std::fs::rename(file_path, backup_file_path) |
|
|
|
|
.map_err(|error| ask_dracula::Error::new_write_file(file_path.to_owned(), error))?; |
|
|
|
|
|
|
|
|
|
// Write updated version of the file
|
|
|
|
|
let file_content = format!("{}", project); |
|
|
|
|
std::fs::write(file_path, &file_content) |
|
|
|
|
.map_err(|error| ask_dracula::Error::new_write_file(file_path.to_owned(), error))?; |
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
}, |
|
|
|
|
VampireResult::Satisfiable => |
|
|
|
|
{ |
|
|
|
|
println!("conjecture disproven"); |
|
|
|
|
Ok(()) |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
let backup_file_path = backup_file_path(file_path)?; |
|
|
|
|
|
|
|
|
|
// Make backup of old file
|
|
|
|
|
std::fs::rename(file_path, backup_file_path) |
|
|
|
|
.map_err(|error| ask_dracula::Error::new_write_file(file_path.to_owned(), error))?; |
|
|
|
|
|
|
|
|
|
// Write updated version of the file
|
|
|
|
|
let file_content = format!("{}", project); |
|
|
|
|
std::fs::write(file_path, &file_content) |
|
|
|
|
.map_err(|error| ask_dracula::Error::new_write_file(file_path.to_owned(), error))?; |
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
}, |
|
|
|
|
ProofResult::Satisfiable => |
|
|
|
|
{ |
|
|
|
|
println!("conjecture disproven"); |
|
|
|
|
Ok(()) |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|