From 471fc10988f4f74be6e6fe25cb3c8d4eacce4932 Mon Sep 17 00:00:00 2001 From: "Hsieh, Chiao" <chsieh16@illinois.edu> Date: Thu, 1 Sep 2022 23:01:47 -0500 Subject: [PATCH] Add Jupyter note book for parsing results --- out/load_dtree_synth_json.ipynb | 177 ++++++++++++++++++++++++++++++++ out/plot_feature_vectors.ipynb | 134 ++++++++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 out/load_dtree_synth_json.ipynb create mode 100644 out/plot_feature_vectors.ipynb diff --git a/out/load_dtree_synth_json.ipynb b/out/load_dtree_synth_json.ipynb new file mode 100644 index 0000000..71b880f --- /dev/null +++ b/out/load_dtree_synth_json.ipynb @@ -0,0 +1,177 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import numpy as np\n", + "import pickle\n", + "import z3\n", + "\n", + "STATE_DIM = 3\n", + "PERC_DIM = 2\n", + "\n", + "filename = \"dtree_synth.4x10.out.json\"\n", + "\n", + "with open(filename, \"r\") as f:\n", + " data = json.load(f)\n", + "\n", + "found_dtree = [dict(part=entry[\"part\"], **entry[\"result\"]) for entry in data if entry[\"status\"] == \"found\"]\n", + "print(len(found_dtree))\n", + "\n", + "found, not_found, spur = 0, 0, 0\n", + "repeated_neg = 0\n", + "other = 0\n", + "for entry in data:\n", + " if entry[\"status\"] == \"found\":\n", + " found += 1\n", + " elif entry[\"status\"] == \"not found\":\n", + " not_found +=1\n", + " elif entry[\"status\"] == \"exception\":\n", + " if \"spurious cexs\" in entry[\"result\"]:\n", + " spur += 1\n", + " elif \"repeated\" in entry[\"result\"]:\n", + " repeated_neg += 1\n", + " else:\n", + " other += 1\n", + "print(found, not_found, spur, repeated_neg, other)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def z3_float64_const_to_real(v: float) -> z3.RatNumRef:\n", + " return z3.simplify(\n", + " z3.fpToReal(z3.FPVal(v, z3.Float64()))\n", + " )\n", + "\n", + "def in_part(state_arr, part_arr):\n", + " assert part_arr.shape == (len(state_arr), 2)\n", + " lb_arr, ub_arr = part_arr.T\n", + " return np.all(lb_arr <= state_arr) and np.all(state_arr <= ub_arr)\n", + "\n", + "def calc_precision(part, z3_expr) -> float:\n", + " def in_z3_expr(sample, z3_expr) -> bool:\n", + " assert len(sample) == STATE_DIM + PERC_DIM\n", + " state_subs_map = [(z3.Real(f\"x_{i}\"), z3_float64_const_to_real(sample[i])) for i in range(STATE_DIM)]\n", + " perc_subs_map = [(z3.Real(f\"z_{i}\"), z3_float64_const_to_real(sample[i+STATE_DIM])) for i in range(PERC_DIM)]\n", + " sub_map = state_subs_map + perc_subs_map\n", + " val = z3.simplify(z3.substitute(z3_expr, *sub_map))\n", + " assert z3.is_bool(val)\n", + " if z3.is_false(val):\n", + " return False\n", + " elif z3.is_true(val):\n", + " return True\n", + " else:\n", + " raise RuntimeError(f\"Cannot validate negative example {sample} by substitution\")\n", + "\n", + " pkl_name = \"../data/800_truths-uniform_partition_4x20-1.2m-pi_12-one_straight_road-2021-10-27-08-49-17.bag.pickle\"\n", + " with open(pkl_name, \"rb\") as f:\n", + " pkl_data = pickle.load(f)\n", + " truth_samples_seq = pkl_data[\"truth_samples\"]\n", + "\n", + " part_arr = np.asfarray(part)\n", + " num_pos, num_neg, num_nan = 0, 0, 0\n", + " for _, ss in truth_samples_seq:\n", + " for s in ss:\n", + " state_arr = np.asfarray(s[0:3])\n", + " if not in_part(state_arr, part_arr):\n", + " continue\n", + " # else:\n", + " if np.any(np.isnan(s)):\n", + " num_nan += 1\n", + " elif in_z3_expr(s, z3_expr):\n", + " num_pos += 1\n", + " else:\n", + " num_neg += 1\n", + " return num_pos, num_neg, num_nan" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def visitor(e, seen):\n", + " if e in seen:\n", + " return\n", + " seen[e] = True\n", + " yield e\n", + " if z3.is_app(e):\n", + " for ch in e.children():\n", + " for e in visitor(ch, seen):\n", + " yield e\n", + " return\n", + " if z3.is_quantifier(e):\n", + " for e in visitor(e.body(), seen):\n", + " yield e\n", + " return" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for result in found_dtree:\n", + " print(result['part'])\n", + " decls = {vname: z3.Real(vname) for vname in [\"x_0\", \"x_1\", \"x_2\", \"z_0\", \"z_1\"]}\n", + " smt2_str = f\"(assert {result['formula']})\"\n", + "\n", + " z3_assertions = z3.parse_smt2_string(smt2_str, decls=decls)\n", + " z3_expr:z3.ExprRef = z3_assertions[0]\n", + " # print(\"#Atomic Predicates:\", sum(z3.is_le(e) or z3.is_ge(e) for e in visitor(z3_expr, {})))\n", + " # print(z3_expr)\n", + "\n", + " # Calculate the number of paths on a binary tree by adding one more path\n", + " # when there is an ite or a disjunction (due to simplification on ite).\n", + " # FIXME does not work if an ite expression is a common sub-expression of two paths.\n", + " num_paths = 1\n", + " for e in visitor(z3_expr, {}):\n", + " if z3.is_or(e) or z3.is_app_of(e, z3.Z3_OP_ITE):\n", + " num_paths += 1\n", + "\n", + " print(\"#Paths:\", num_paths)\n", + "\n", + " num_pos, num_neg, num_nan = calc_precision(result['part'], z3_expr)\n", + " print(f\"pos: {num_pos}; neg: {num_neg}; nan: {num_nan}\")\n", + " print(\"precision (pos/(pos+neg)):\", num_pos / (num_pos + num_neg) )\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.10 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/out/plot_feature_vectors.ipynb b/out/plot_feature_vectors.ipynb new file mode 100644 index 0000000..d7a98f8 --- /dev/null +++ b/out/plot_feature_vectors.ipynb @@ -0,0 +1,134 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ast\n", + "import csv\n", + "import itertools\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pathlib\n", + "import re\n", + "\n", + "X_LIM = np.inf\n", + "X_ARR = np.array([-X_LIM, X_LIM])\n", + "\n", + "Y_LIM = 1.2\n", + "NUM_Y_PARTS = 4\n", + "Y_ARR = np.linspace(-Y_LIM, Y_LIM, NUM_Y_PARTS + 1)\n", + "\n", + "YAW_LIM = np.pi / 12\n", + "NUM_YAW_PARTS = 10\n", + "YAW_ARR = np.linspace(-YAW_LIM, YAW_LIM, NUM_YAW_PARTS + 1)\n", + "\n", + "PARTITION = (X_ARR, Y_ARR, YAW_ARR)\n", + "BOUND_LIST = list(list(zip(x_arr[:-1], x_arr[1:])) for x_arr in PARTITION)\n", + "PART_LIST = list(itertools.product(*BOUND_LIST))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from numpy import arange\n", + "from sympy import continued_fraction\n", + "\n", + "\n", + "csv_path_list = list(pathlib.Path(\".\").glob(\"part-???-pre.data\"))\n", + "csv_path_list.sort()\n", + "for csv_path in csv_path_list:\n", + " m = re.match(\"^part-(?P<partid>\\d+)-pre.data$\", csv_path.name)\n", + " partid = int(m[\"partid\"])\n", + " part_bnd = np.asfarray(PART_LIST[partid])\n", + "\n", + " # Reset the plot\n", + " plt.gca().clear()\n", + " plt.gca().set_title(\n", + " f\"x bound: {part_bnd[0]} (m)\\n\"\n", + " f\"y bound: {part_bnd[1]} (m)\\n\"\n", + " f\"θ bound: {np.rad2deg(part_bnd[2])} (deg)\"\n", + " )\n", + "\n", + " pos_fvs, neg_fvs = [], []\n", + "\n", + " with open(csv_path, 'r') as csvfile:\n", + " csvreader = csv.reader(csvfile)\n", + " for entry in csvreader:\n", + " if entry[2].lower() == \"true\":\n", + " pos_fvs.append(tuple(ast.literal_eval(e) for e in entry[0:2]))\n", + " else:\n", + " assert entry[2].lower() == \"false\"\n", + " neg_fvs.append(tuple(ast.literal_eval(e) for e in entry[0:2]))\n", + " print(f\"File: {csv_path.name}; #pos: {len(pos_fvs)}; #neg: {len(neg_fvs)}\")\n", + "\n", + " pos_fv_arr = np.asfarray(pos_fvs)\n", + " plt.scatter(pos_fv_arr[:, 0], pos_fv_arr[:, 1], c=\"g\", marker=\"o\", s=1)\n", + "\n", + " neg_fv_arr = np.asfarray(neg_fvs)\n", + " plt.scatter(neg_fv_arr[:, 0], neg_fv_arr[:, 1], c=\"r\", marker=\"x\", s=1)\n", + "\n", + " # dx = np.linspace(-1, 0.5,500)\n", + " # dy = np.linspace(-0.3, 0.5, 500)\n", + " # x,y = np.meshgrid(dx,dy)\n", + " # if partid == 16:\n", + " # region = (-3486699801877165/72057594037927936 < 1*y) & \\\n", + " # ((2774949835903621/36028797018963968 >= (1*x + -1*y))\n", + " # &(-649018808849943/1125899906842624 < (1*x + -1*y))\n", + " # &( (4806281874582455/288230376151711744 >= (1*x + 1*y))\n", + " # | (2006731648131879/288230376151711744 >= 1*y)\n", + " # )\n", + " # )\n", + " # if partid == 0:\n", + " # region = ((y>-0.008467263) & (x+y>-0.7293049)).astype(int)\n", + " # plt.gca().set_xlim(-1, 1)\n", + " # plt.gca().set_xlim(-2.2, 0.2)\n", + " # elif partid == 9:\n", + " # region = (((x+y<=-1.141609) & (y>0.09126037)) | ((x+y>-1.141609) & (y>-0.1772965))).astype(int)\n", + " # plt.gca().set_xlim(-2.5, 2.5)\n", + " # plt.gca().set_ylim(-0.42, 0.25)\n", + " # elif partid == 17: \n", + " # region = ((y>-0.0121161) & (y<=0.02008105) & (x+y>-0.6796197) & (x+y<=0.05748017)).astype(int)\n", + " # plt.gca().set_xlim(-1, 1)\n", + " # plt.gca().set_ylim(-0.25, 0.25)\n", + " # else:\n", + " # pass\n", + " # plt.imshow( region, \n", + " # extent=(x.min(),x.max(),y.min(),y.max()),origin=\"lower\", cmap=\"Greys\", alpha = 0.3)\n", + " plt.savefig(csv_path.name + \".png\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.10 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} -- GitLab