-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verusport #3
Verusport #3
Conversation
import string_hash_map axiomatization
add deep views
verus/lcf/README.md
Outdated
Term types are enums that have 2 variants: | ||
1. Const(Const) | ||
2. Var(String) | ||
|
||
Its spec versions for SpecTerm are: | ||
1. Const(SpecConst) | ||
2. Var(Seq<char>) | ||
|
||
Functions that can be used on Term types: | ||
1. (in impl DeepView for Term) open spec fn deep_view(&self) -> Self::V | ||
2. (in impl Clone for Term) fn clone(&self) -> (res: Self) | ||
3. (in impl PartialEq for Term) fn eq(&self, other: &Self) -> (res: bool) | ||
4. pub open spec fn spec_complete_subst(self, s: SpecSubst) -> bool | ||
5. pub open spec fn spec_concrete(self) -> bool | ||
6. pub open spec fn spec_subst(self, s: SpecSubst) -> (res: SpecTerm) | ||
7. pub fn term_eq(&self, other: &Self) -> (res: bool) | ||
8. pub fn complete_subst(self, s: &Subst) -> (res: bool) | ||
9. pub fn concrete(self) -> (res: bool) | ||
10. pub fn subst(self, s: &Subst) -> (res: Term) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure that documentation like this makes sense in the README. It's a copy of the code, and the code itself is a more authoritative description of the types and methods. We can also auto-generate API descriptions using the documentation generators from Rust and Verus.
What we need at this level is a concise conceptual description of what the datatypes are and the role they play. That is, the higher-level thought process that you can't see directly in the code itself.
This same comment applies to all the sections under Data types of Kernel
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed---we don't need this list of function signatures. Instead, it would be good to have some description of what each data type represents in the kernel, similar to what you have in Prop
. For example, for Term
, you could say that it represents the Datalog notion of a term, i.e., the arguments to a Datalog atom.
|
||
## Rule | ||
|
||
Rules are the equivalent to rules in Datalog. A Rule in the kernel with no body is equivalent to a fact in Datalog. In this datalog line of code: connected(a, b) :- edge(a, b). ---- connected(a, b) :- edge(a, b) is a Rule that is also a rule in Datalog. In this datalog line of code: edge("x", "y"). ---- edge("x", "y"). is a Rule that is a fact in Datalog because it only has a head and no body. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you looked at the rendered markdown? I suspect paragraphs like these will not come out right. You need to wrap things in code
markers as appropriate.
|
||
## Purpose | ||
|
||
The purpose of this verified kernel is to encode a RuleSet corresponding to a set of Datalog rules and encode a set of facts( rules without bodies) in order to solve Datalog predicates. The major goal of this kernel is to one day encode a set of rules of criteria for verifiable X.509 web certificate fields and sets of facts corresponding to the fields' values in order to produce a theorem if the proof tree corresponding to these rules and facts is valid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap paragraphs to a reasonable line width.
verus/lcf/README.md
Outdated
@@ -0,0 +1,396 @@ | |||
## Verified Kernel in Dafny |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally in this document, I think it makes sense to remove documentation that's just a copy of the code itself. Please keep it to a description of the high-level concepts that aid the understanding of the code.
verus/lcf/src/verusport.rs
Outdated
impl DeepView for Const { | ||
type V = SpecConst; | ||
|
||
// function deep_view allows for reasoning about spec-level data structures and types while in exec mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also suggest avoiding comments like this. Verus developers should know what deep_view
is. It's the job of Verus documentation to explain that, not your code.
verus/lcf/src/verusport.rs
Outdated
} | ||
|
||
impl Term { | ||
// function proves equality for Term types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd avoid prefixing your comments with function ...
. Just say // Check equality for terms
.
verus/lcf/src/verusport.rs
Outdated
{ | ||
match self { | ||
SpecProp::App(h, args) => { | ||
//map_values calls spec_subst on all SpecTerm items in args and stores in new sequence |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best to avoid verbatim descriptions of the code. Prefer something like // Apply substitution to arguments
, or avoid it altogether since it's quite simple.
verus/lcf/src/verusport.rs
Outdated
|
||
//spec function checks whether valid SpecProp types are concrete and are equal | ||
pub open spec fn spec_valid(self) -> bool { | ||
if self.spec_symbolic() == true || self.spec_concrete() == false { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can avoid comparisons with booleans.
x == true
can just be x
and x == false
is !x
.
verus/lcf/src/verusport.rs
Outdated
} | ||
//if all properties were satisfied | ||
|
||
if flag == true { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe do if !flag { return Err(()) }
and then the rest of the code can be indented one less.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this is great work! It's really exciting that you have been able to port the kernel over to Verus. I've left a few comments, mostly stylistic/to do with comments and text descriptions in your code. I also noted some TODO items that I think are worth addressing at some point, but I think we can merge this before those are done.
verus/lcf/README.md
Outdated
Term types are enums that have 2 variants: | ||
1. Const(Const) | ||
2. Var(String) | ||
|
||
Its spec versions for SpecTerm are: | ||
1. Const(SpecConst) | ||
2. Var(Seq<char>) | ||
|
||
Functions that can be used on Term types: | ||
1. (in impl DeepView for Term) open spec fn deep_view(&self) -> Self::V | ||
2. (in impl Clone for Term) fn clone(&self) -> (res: Self) | ||
3. (in impl PartialEq for Term) fn eq(&self, other: &Self) -> (res: bool) | ||
4. pub open spec fn spec_complete_subst(self, s: SpecSubst) -> bool | ||
5. pub open spec fn spec_concrete(self) -> bool | ||
6. pub open spec fn spec_subst(self, s: SpecSubst) -> (res: SpecTerm) | ||
7. pub fn term_eq(&self, other: &Self) -> (res: bool) | ||
8. pub fn complete_subst(self, s: &Subst) -> (res: bool) | ||
9. pub fn concrete(self) -> (res: bool) | ||
10. pub fn subst(self, s: &Subst) -> (res: Term) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed---we don't need this list of function signatures. Instead, it would be good to have some description of what each data type represents in the kernel, similar to what you have in Prop
. For example, for Term
, you could say that it represents the Datalog notion of a term, i.e., the arguments to a Datalog atom.
verus/lcf/README.md
Outdated
|
||
## Prop | ||
|
||
Props are the heads of rules that are used in rulesets for mk_thm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that Prop
s don't just appear in rule heads, they are also the bodies of rules---they correspond to the Datalog notion of an "atom" or "predicate".
verus/lcf/README.md
Outdated
## Prop | ||
|
||
Props are the heads of rules that are used in rulesets for mk_thm. | ||
In this datalog line of code: connected(a, b) :- edge(a, b). ---- connected(a, b) is the Prop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edge(a,b)
would also be represented with a Prop
here
verus/lcf/README.md
Outdated
|
||
## Ruleset | ||
|
||
A RuleSet is a set of Rules in our kernel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add that we use RuleSet
to encompass all of the rules from the Datalog program that we start with, and relate it to valid
for Proof
.
verus/lcf/README.md
Outdated
|
||
|
||
## Thm | ||
Theorems (thm) are used in our kernel as the final result that we are producing and want to run Ok on. If the theorem is valid, Ok will be returned, and if it is invalid, Err will be returned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean by "run Ok on" here. The Ok
is a constructor from the Result
type, which is used in mk_thm
to tell us whether we successfully constructed a Thm
or not. The key thing about Thm
is that if it is well-formed, then we know that there exists a valid proof tree for the atom denoted by val
.
; | ||
Prop::App(h.clone(), v) | ||
}, | ||
Prop::Eq(x, y) => Prop::Eq(x.clone().subst(s), y.clone().subst(s)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the clone
calls here required?
proof { | ||
assert_seqs_equal!(v.deep_view(), self.body.deep_view().map_values(|p: SpecProp| p.spec_subst(s.deep_view()))); | ||
} | ||
; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this semicolon
{ | ||
let mut v = Vec::<Prop>::new(); | ||
//assertion uses forall statement to show the two positions of deep_view are the same result | ||
assert(forall|k: int| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, this assertion could be factored into a lemma. For now, a comment would be helpful.
verus/lcf/src/kernel.rs
Outdated
closed spec fn deep_view(&self) -> Self::V; | ||
} | ||
|
||
//#[verifier::external_body] needed due to postocondition failing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would note here that we add this axiom because of an issue with Verus: verus-lang/verus#1222
That way, if/when that issue is resolved, someone reading this code can corroborate and work on replacing the axiom with an actual definition.
forall|j: int| #![auto] 0 <= j < args.len() ==> args[j].deep_view().spec_wf(rs.deep_view()), | ||
ensures | ||
//ensures block specifies conditions that must be met in order for the thm to be valid at termination | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These conditions are a little complicated---it would be nice to have a plain-language, high-level description of what they mean. For instance, the first one says that if we provide "reasonable" arguments (the substitution is complete for the rule in question, we have the right number of proofs for the arguments, and those proofs prove the atoms in the body of the rule), then mk_thm
will produce a valid Thm
for that Prop
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this is great work! It's really exciting that you have been able to port the kernel over to Verus. I've left a few comments, mostly stylistic/to do with comments and text descriptions in your code. I also noted some TODO items that I think are worth addressing at some point, but I think we can merge this before those are done.
Updates to codebase:
I added the files for TmpStringHashMap, Verusport, README.md, and main.rs. In README.md, all major information was included, and I tried to be as thorough as possible. Verusport contains a toy example as the end for an edge connectivity problem, but we need to work on tst_connected_thm later due to verification errors.