Skip to content

Commit 57e23a4

Browse files
"Friendly" output of requirements and features
1 parent 166986f commit 57e23a4

File tree

1 file changed

+65
-22
lines changed

1 file changed

+65
-22
lines changed

notebooks/Alhazen.ipynb

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -605,10 +605,12 @@
605605
" key : The feature key (e.g., the chosen alternative or rule itself).\n",
606606
" '''\n",
607607
"\n",
608-
" def __init__(self, name: str, rule: str, key: str) -> None:\n",
608+
" def __init__(self, name: str, rule: str, key: str, /,\n",
609+
" friendly_name: str = None) -> None:\n",
609610
" self.name = name\n",
610611
" self.rule = rule\n",
611612
" self.key = key\n",
613+
" self._friendly_name = friendly_name or name\n",
612614
" super().__init__()\n",
613615
"\n",
614616
" def __repr__(self) -> str:\n",
@@ -619,6 +621,9 @@
619621
" def name_rep(self) -> str:\n",
620622
" pass\n",
621623
"\n",
624+
" def friendly_name(self) -> str:\n",
625+
" return self._friendly_name\n",
626+
"\n",
622627
" @abstractmethod\n",
623628
" def get_feature_value(self, derivation_tree) -> float:\n",
624629
" '''Returns the feature value for a given derivation tree of an input.'''\n",
@@ -648,8 +653,9 @@
648653
" key : The feature key, equal to the rule attribute for production features,\n",
649654
" or equal to the corresponding alternative for alternative features.\n",
650655
" '''\n",
651-
" def __init__(self, name: str, rule: str, key: str) -> None:\n",
652-
" super().__init__(name, rule, key)\n",
656+
" def __init__(self, name: str, rule: str, key: str,\n",
657+
" friendly_name: str = None) -> None:\n",
658+
" super().__init__(name, rule, key, friendly_name=friendly_name)\n",
653659
"\n",
654660
" def name_rep(self) -> str:\n",
655661
" if self.rule == self.key:\n",
@@ -709,8 +715,8 @@
709715
" e.g., 'num(<integer>)'\n",
710716
" rule : The production rule.\n",
711717
" '''\n",
712-
" def __init__(self, name: str, rule: str) -> None:\n",
713-
" super().__init__(name, rule, rule)\n",
718+
" def __init__(self, name: str, rule: str, friendly_name: str = None) -> None:\n",
719+
" super().__init__(name, rule, rule, friendly_name=friendly_name)\n",
714720
"\n",
715721
" def name_rep(self) -> str:\n",
716722
" return f\"num({self.key})\"\n",
@@ -766,7 +772,11 @@
766772
" features.append(ExistenceFeature(f\"exists({rule})\", rule, rule))\n",
767773
" # add all alternatives\n",
768774
" for count, expansion in enumerate(grammar[rule]):\n",
769-
" features.append(ExistenceFeature(f\"exists({rule}@{count})\", rule, expansion))\n",
775+
" name = f\"exists({rule}@{count})\"\n",
776+
" friendly_name = f\"{rule} == {repr(expansion)}\"\n",
777+
" feature = ExistenceFeature(name, rule, expansion,\n",
778+
" friendly_name=friendly_name)\n",
779+
" features.append(feature)\n",
770780
"\n",
771781
" return features"
772782
]
@@ -825,7 +835,11 @@
825835
" for key in derivable_chars:\n",
826836
" # Check if derivable chars contain only numeric chars\n",
827837
" if len(derivable_chars[key] - numeric_chars) == 0:\n",
828-
" features.append(NumericInterpretation(f\"num({key})\", key))\n",
838+
" name = f\"num({key})\"\n",
839+
" friendly_name = f\"{key}\"\n",
840+
"\n",
841+
" features.append(NumericInterpretation(f\"num({key})\", key,\n",
842+
" friendly_name=friendly_name))\n",
829843
"\n",
830844
" return features"
831845
]
@@ -849,6 +863,15 @@
849863
"get_all_features(CALC_GRAMMAR)"
850864
]
851865
},
866+
{
867+
"cell_type": "code",
868+
"execution_count": null,
869+
"metadata": {},
870+
"outputs": [],
871+
"source": [
872+
"[f.friendly_name() for f in get_all_features(CALC_GRAMMAR)] "
873+
]
874+
},
852875
{
853876
"cell_type": "markdown",
854877
"metadata": {},
@@ -2161,7 +2184,25 @@
21612184
" self.value = value\n",
21622185
"\n",
21632186
" def __str__(self):\n",
2164-
" return f\"Requirement({self.feature.name} {self.quant} {self.value})\""
2187+
" return f\"Requirement({self.feature.name} {self.quant} {self.value})\"\n",
2188+
"\n",
2189+
" def __repr__(self):\n",
2190+
" return f\"Requirement({self.feature.name}, {self.quant}, {self.value})\"\n",
2191+
"\n",
2192+
" def friendly(self):\n",
2193+
" def value(x):\n",
2194+
" try:\n",
2195+
" return float(x)\n",
2196+
" except Exception:\n",
2197+
" return None\n",
2198+
"\n",
2199+
" if isinstance(self.feature, ExistenceFeature):\n",
2200+
" if value(self.value) > 0:\n",
2201+
" return f\"{self.feature.friendly_name()}\"\n",
2202+
" elif value(self.value) < 0:\n",
2203+
" return f\"not {self.feature.friendly_name()}\"\n",
2204+
"\n",
2205+
" return f\"{self.feature.friendly_name()} {self.quant} {self.value}\""
21652206
]
21662207
},
21672208
{
@@ -2181,12 +2222,14 @@
21812222
" self.requirements: List[SpecRequirement] = requirements\n",
21822223
"\n",
21832224
" def __str__(self):\n",
2184-
" # Handle first element\n",
2185-
" s = f\"{str(self.requirements[0])}\"\n",
2186-
" for count in range(1, len(self.requirements)):\n",
2187-
" s += (\", \" + str(self.requirements[count]))\n",
2225+
" s = \", \".join(str(r) for r in self.requirements)\n",
2226+
" return f\"InputSpecification({s})\"\n",
21882227
"\n",
2189-
" return f\"InputSpecification({s})\""
2228+
" def friendly(self):\n",
2229+
" return \" and \".join(r.friendly() for r in self.requirements)\n",
2230+
"\n",
2231+
" def __repr__(self):\n",
2232+
" return self.__str__()"
21902233
]
21912234
},
21922235
{
@@ -2339,17 +2382,18 @@
23392382
"metadata": {},
23402383
"source": [
23412384
"We implement a _Grammar-Based Input Generator_ that generates new input samples from a List of `Input Specifications`.\n",
2342-
"The Input Specifications are extracted from the decision tree boundaries in the previous Activity 3: _RequirementExtraction_\n",
2385+
"The Input Specifications are extracted from the decision tree boundaries in the previous Activity 3: _RequirementExtraction_.\n",
2386+
"\n",
23432387
"An Input Specification consists of **1 to n** many predicates or requirements (e.g. feature '>=' value, or 'num(term) <= 13').\n",
2344-
"We generate a new input for each InputSpecification.\n",
2345-
"The new input fulfills all the given requirements of an IputSpecification."
2388+
"We generate a new input for each `InputSpecification`.\n",
2389+
"The new input fulfills all the given requirements of an InputSpecification."
23462390
]
23472391
},
23482392
{
23492393
"cell_type": "markdown",
23502394
"metadata": {},
23512395
"source": [
2352-
"**Info:** For furter details, please refer to <b>Section 4.4 and 4.5</b> of the <a href=\"https://publications.cispa.saarland/3107/7/fse2020-alhazen.pdf\">paper</a> and the Chapter <b><a href=\"https://www.fuzzingbook.org/html/GrammarFuzzer.html\">Efficient Grammar Fuzzing</a></b> in the fuzzingbook."
2396+
"**Info:** For further details, please refer to <b>Section 4.4 and 4.5</b> of the <a href=\"https://publications.cispa.saarland/3107/7/fse2020-alhazen.pdf\">paper</a> and the Chapter <b><a href=\"https://www.fuzzingbook.org/html/GrammarFuzzer.html\">Efficient Grammar Fuzzing</a></b> in the fuzzingbook."
23532397
]
23542398
},
23552399
{
@@ -2679,15 +2723,14 @@
26792723
" self._data.drop(['oracle'], axis=1))\n",
26802724
" print(f\" New input specifications:\")\n",
26812725
" for spec in new_input_specifications:\n",
2682-
" print(f\" {str(spec)}\")\n",
2726+
" print(f\" {spec.friendly()}\")\n",
26832727
"\n",
26842728
" # generate new inputs according to the new input specifications\n",
26852729
" new_samples = generate_samples(self._grammar,\n",
26862730
" new_input_specifications,\n",
26872731
" self._generator_timeout)\n",
26882732
" print(f\" New samples:\")\n",
2689-
" for sample in new_samples:\n",
2690-
" print(f\" {str(sample)}\")\n",
2733+
" print(f\" {\", \".join(new_samples)}\")\n",
26912734
" self._previous_samples = new_samples"
26922735
]
26932736
},
@@ -2749,8 +2792,8 @@
27492792
"metadata": {},
27502793
"outputs": [],
27512794
"source": [
2752-
"all_features = extract_existence(CALC_GRAMMAR) + extract_numeric(CALC_GRAMMAR)\n",
2753-
"all_feature_names = [f.name for f in all_features]"
2795+
"all_features = get_all_features(CALC_GRAMMAR)\n",
2796+
"all_feature_names = [f.friendly_name() for f in all_features]"
27542797
]
27552798
},
27562799
{

0 commit comments

Comments
 (0)