Skip to content
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

Conversation

eobardthawne21p
Copy link

@eobardthawne21p eobardthawne21p commented Aug 1, 2024

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.

verus/lcf/src/verusport.rs Outdated Show resolved Hide resolved
Comment on lines 35 to 53
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)
Copy link
Collaborator

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.

Copy link
Collaborator

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.
Copy link
Collaborator

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.
Copy link
Collaborator

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.

@@ -0,0 +1,396 @@
## Verified Kernel in Dafny
Copy link
Collaborator

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.

impl DeepView for Const {
type V = SpecConst;

// function deep_view allows for reasoning about spec-level data structures and types while in exec mode
Copy link
Collaborator

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.

}

impl Term {
// function proves equality for Term types
Copy link
Collaborator

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.

{
match self {
SpecProp::App(h, args) => {
//map_values calls spec_subst on all SpecTerm items in args and stores in new sequence
Copy link
Collaborator

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.


//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 {
Copy link
Collaborator

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.

}
//if all properties were satisfied

if flag == true {
Copy link
Collaborator

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.

Copy link
Collaborator

@pratapsingh1729 pratapsingh1729 left a 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.

Comment on lines 35 to 53
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)
Copy link
Collaborator

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.


## Prop

Props are the heads of rules that are used in rulesets for mk_thm.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that Props 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".

## 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
Copy link
Collaborator

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


## Ruleset

A RuleSet is a set of Rules in our kernel.
Copy link
Collaborator

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.



## 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.
Copy link
Collaborator

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)),
Copy link
Collaborator

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())));
}
;
Copy link
Collaborator

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|
Copy link
Collaborator

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.

closed spec fn deep_view(&self) -> Self::V;
}

//#[verifier::external_body] needed due to postocondition failing
Copy link
Collaborator

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

Copy link
Collaborator

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.

@pratapsingh1729 pratapsingh1729 self-requested a review August 1, 2024 20:47
Copy link
Collaborator

@pratapsingh1729 pratapsingh1729 left a 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.

@mmcloughlin mmcloughlin changed the base branch from mbm/x-trace-reconstruction to trace-reconstruction August 2, 2024 15:15
@pratapsingh1729 pratapsingh1729 merged commit 4322b16 into secure-foundations:trace-reconstruction Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants