folproof
Version:
A first-order logic proof verifier
184 lines (181 loc) • 5.91 kB
HTML
<html>
<head>
<title>FOLProof First-Order Logic Checker</title>
<link rel="stylesheet" href="http://getbootstrap.com/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="http://getbootstrap.com/assets/css/docs.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type='text/javascript' src='folproof-parser.js'></script>
<script type='text/javascript' src='folproof-web.js'></script>
<script type='text/javascript' src='folproof-verifier.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var debugMode = true;
$("#parentheses").bind("click change", function() { $("#proof-input").keyup(); });
$("#proof-input").keyup(function(v) {
var proof = $(this).val();
var paren = $("#parentheses").val();
try {
parser.trace = function() { if (console && console.log) console.log(arguments); };
var ast = parser.parse(proof);
var result = folproof.Verifier.verifyFromAST(ast);
$("#result").text(result.message);
if (!result.valid) {
var str = "<p>Step: " + result.errorStep;
if (result.errorSrcLine)
str += ", Src Line: " + result.errorSrcLoc.first_line;
str += "</p>";
$("#result").append(str);
$("#result-box").css({ background: "", 'border-left' : "", color : "" });
} else {
$("#result-box").css({ background: "#ccffcc", 'border-left' : "3px solid green", color : "" });
}
} catch (err) {
$("#result").text(err);
$("#result-box").css({ background: "", 'border-left' : "", color : "" });
//throw err;
}
var html = folproofWeb.render(ast, { parentheses : paren });
$("#render-panel").empty().append(html);
});
$("#proof-input").keyup(); // force invocation on load
$("button.examples").click(function() {
var i = $(this).val();
var proof = $("#proof-input");
proof.val($("#example" + i).text().substr(1))
proof.keyup();
});
});
</script>
<style type='text/css' rel='stylesheet'>
#proof-input { height: 32em; width: 100%; font-family: monospace;}
#render-panel { height: 21em; font-family: monospace; }
#result-box { height: 7em; margin-top: 0.8em;}
.justification { width: 50%; float: right; }
.FOL-box, .simple-box { border: 1px solid black; border-radius: 3px; padding: 2px;}
.folproof-error { color: red; font-weight: bold; }
.lineno { display: block; float: left; width: 1.8em; }
.rule { clear: both; }
#examples { display: none; }
</style>
</head>
<body>
<div class='container'>
<div class='row'>
<div class='col-md-12'>
<h1>FOLProof</h1>
<h4>Javascript First-Order Logic Proof Checker</h4>
Source: <a href='https://github.com/cdibbs/folproof/tree/master' title='folproof source on github'>https://github.com/cdibbs/folproof/tree/master</a>
<div class='bs-callout bs-callout-info'>
<h4>Instructions:</h4>
<p>
Enter your proof in the input box, below. As you type, the formatted proof
will appear on the right, along with a validation status, beneath that. To learn
the syntax, try playing with the examples, below, or see the
<a href='//github.com/cdibbs/folproof/blob/gh-pages/docs/language.md'>language reference.</a>
</p>
<p>
<strong>Note:</strong> Please be sure you have a modern browser, and that
Javascript is enabled.
</p>
<strong>Examples:<strong>
<button class='examples' value='0'>HW3 Problem 5</button>
<button class='examples' value='1'>HW3 Problem 4</button>
<button class='examples' value='2'>HW3 Problem 7</button>
<button class='examples' value='3'>Page 115</button>
</div>
</div>
</div>
<div class='row'>
<div id='leftcol' class='col-md-6'>
<textarea id='proof-input'>
1 A.x(P(x) -> ~Q(x)) : premise
2 | E.x(P(x) and Q(x)) : assumption
|| with x0
3 || P(x0) and Q(x0) : assumption
4 || P(x0) : and elim1 3
5 || P(x0) -> ~Q(x0) : A.x/x0 elim 1
6 || ~Q(x0) : -> e 5,4
7 || Q(x0) : and elim2 3
8 || contradiction : not elim 6,7
---
9 | contradiction : E.x/x0 elim 2,3-8
---
10 ~(E.x(P(x) and Q(x))) : not introduction 2-9
</textarea>
</div>
<div id='rightcol' class='col-md-6'>
</div>
<div id='rightcol' class='col-md-6'>
<div id='render-panel' class='highlight'>
</div>
<div id='options'>
<label>
Parentheses:
<select id='parentheses'>
<option value='minimal'>Minimal (order-of-ops overrides)</option>
<option value='user' selected='selected'>User-defined</option>
<option value='explicit'>Explicit order-of-ops</option>
</select>
</label>
</div>
<div id='result-box' class='bs-callout bs-callout-warning'>
<h4>Result:</h4>
<div id='result'>
</div>
</div>
</div>
</div>
</div>
<!-- these are hidden by CSS style rules... -->
<div id='examples'>
<div id='example0'>
1 A.x(P(x) -> ~Q(x)) : premise
2 | E.x(P(x) and Q(x)) : assumption
|| with x0
3 || P(x0) and Q(x0) : assumption
4 || P(x0) : and elim1 3
5 || P(x0) -> ~Q(x0) : A.x/x0 elim 1
6 || ~Q(x0) : -> e 5,4
7 || Q(x0) : and elim2 3
8 || contradiction : not elim 6,7
---
9 | contradiction : E.x/x0 elim 2,3-8
---
10 ~(E.x(P(x) and Q(x))) : not introduction 2-9
</div>
<div id='example1'>
# Extraneous step #s in the src are ignored. Be careful.
1 A.x(P(x,z))
| with y0
2 | P(y0,z) : A.x/y0 e 1
---
3 A.y(P(y,z)) : A.y/y0 i 2-2
</div>
<div id='example2'>
# Sloppy syntax is fine :-)
P(a)
| with x0
|| a = x0 : assumption
|| P(x0) : = e 2,1
-
| a = x0 -> P(x0) : -> i 2-3
-
A.x(a=x->P(x)) : A.x/x0 i 2-4
</div>
<div id='example3'>
1 A.x(Q(x) -> R(x)) : premise
2 E.x(P(x) and Q(x)) : premise
| with x0
3 | P(x0) and Q(x0) : assumption
4 | Q(x0) -> R(x0) : A.x/x0 e 1
5 | Q(x0) : and e2 3
6 | R(x0) : -> e 4,5
7 | P(x0) : and e1 3
8 | P(x0) and R(x0) : and i 7,6
9 | E.x(P(x) and R(x)) : E.x/x0 i 8
---
10 E.x(P(x) and R(x)) : E.x/x0 e 2, 3-9
</div>
</div>
</body>
</html>