Skip to content

Lab Course SoSe2025 - Pentagon Domain #1740

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

Open
wants to merge 198 commits into
base: master
Choose a base branch
from
Open

Conversation

feniup
Copy link
Contributor

@feniup feniup commented May 7, 2025

Lab Course: Static Analysis with Goblint

In this lab course we try to actively contribute to the Goblint codebase by integrating new abstract domain.

In the current iteration, the focus is on the development of the pentagon domain (Pntg), which combines interval analysis with symbolic relational constraints of the form $x < y$. This hybrid approach offers greater precision than traditional interval analysis while maintaining lower complexity compared to more expressive domains like the octagon domain.

@michael-schwarz michael-schwarz added student-job relational Relational analyses (Apron, affeq, lin2var) feature labels May 7, 2025
Comment on lines 10 to 14
let hash (z: t) =
match z with
| PosInfty -> failwith "ZExt.pow: TODO"
| NegInfty -> failwith "ZExt.pow: TODO"
| Arb(z) -> Z.hash z;;
Copy link
Member

Choose a reason for hiding this comment

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

I am bit surprised your analysis works at all, given it will fail if any PosInfinity or NegInfinity appears in an abstract value. What precisely is your plan for how you use them?

tests/unit/dune Outdated
Comment on lines 32 to 34
; See: https://github.com/ocaml/dune/issues/4383#issuecomment-805107435.
; TODO: Remove workaround with dune 3.0, where this should get fixed.
Copy link
Member

Choose a reason for hiding this comment

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

I don't think the entire comment needs to be repeated.

Comment on lines +3 to +5
(* Note:
There are currently no tests independent of apron.
*)
Copy link
Member

Choose a reason for hiding this comment

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

If they are not independent of apron, why are they called No-Apron?

) |>
assert_equal expected

let noop _ = assert_bool "" true
Copy link
Member

Choose a reason for hiding this comment

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

?

Comment on lines 47 to 48
let narrow (i1: t) (i2: t) =
meet i1 i2
Copy link
Member

@michael-schwarz michael-schwarz Jul 17, 2025

Choose a reason for hiding this comment

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

Could you elaborate on why setting narrow to meet is ok here, i.e., why the domain does not have (quasi-)infinite (i.e., of length 2^64 or something) descending chains?

Comment on lines 152 to 153
let narrow (i1: t) (i2: t) =
inter i1 i2
Copy link
Member

Choose a reason for hiding this comment

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

Same question as above for narrow.

*)
module Intv =
struct
include ZExtOps
Copy link
Member

Choose a reason for hiding this comment

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

This is almost a lattice except you have named (some) operations differently? Any reasons for that?


type t = (ZExt.t * ZExt.t) [@@deriving eq, hash, ord]

let to_string ((lb, ub): t) = Printf.sprintf "[%s,%s]" (StringUtils.int32_bound_str lb) (StringUtils.int32_bound_str ub)
Copy link
Member

Choose a reason for hiding this comment

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

Why Int32?

| ZExt.PosInfty -> failwith "This should not happen :)"
| ZExt.NegInfty -> (
if Z.abs coeff = Z.one then
if List.length l >= 2 then

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: semgrep.list-length-compare-n Warning

computing list length is inefficient for length comparison, use compare_length_with instead
Comment on lines 946 to 947
"Failed to convert cil expression: exception %s"
(SharedFunctions.show_unsupported_cilExp exn),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is where at least on my computer the memory overflow happens; can you do without the call to show_unsupported_cilExp ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess we can remove this call. iirc we only put this in for debugging purposes.

PS: How did you recognize it as the cause?

Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. I started goblint/pentagon with the command from an SV-Comp OUT OF MEMORY
  2. Waited for the memory usage to build up, without progress in the eval counter
  3. pressed ctr-c
  4. inspected the stacktrace for the uppermost occurance of a line from the pentagon implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this consistent, i.e., does redoing those steps always result in that spot? It might just be a coincidence that the Ctrl-C interrupt happened right at that call.

Nevertheless, I will do some experiments later today and check it out.

Copy link
Member

Choose a reason for hiding this comment

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

It seems to be d_plainexp in the CIL Pretty printer. We've had similar problems with recursive printers in the past.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AHHH now I can see it.
I miss interpreted the calls to the Pretty module and just "waved them off", as I thought they were needed to produce the output when specifying ./goblint -v.

You are right. d_plainexp starts a long chain of calls.

I just simply removed the lines for a simple test and it seems to make the cut. Wow, I really did not anticipate that easy of a fix! That's great 😄

Comment on lines 941 to 957
let (str, res) =
match Convert.tcons1_of_cil_exp ask t t.env e negate no_ov with
| exception Convert.Unsupported_CilExp exn -> (
(
Printf.sprintf
"Failed to convert cil expression: exception %s"
(SharedFunctions.show_unsupported_cilExp exn),
t
)
)
| tcons -> (
(
StringUtils.string_of_tcons1 tcons,
assert_constraint ask t tcons negate no_ov
)
)
in
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should go into the tracing part

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature in progress relational Relational analyses (Apron, affeq, lin2var) student-job
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants