Files

1 line
60 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "assert-kth/flames", "files": {"raw-validation-results/sb-heists/inference-single-turn-deepseek.ipynb": {"8dadcf88b53331dd1dd1d2be4dfb54f21ebf7a95": {"t": 1785745512.0114388, "n": 17721, "h": "fcb5e11e0a1ad825", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"86039af7\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"# Requires: pip install openai python-dotenv\\n\",\n \"import os, time, re, json\\n\",\n \"from typing import Optional\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"\\n\",\n \"load_dotenv()\\n\",\n \"\\n\",\n \"try:\\n\",\n \" from openai import OpenAI\\n\",\n \"except Exception as e:\\n\",\n \" raise RuntimeError(\\\"Install the OpenAI SDK first: pip install openai\\\") from e\\n\",\n \"\\n\",\n \"DEEPSEEK_API_KEY = os.environ.get(\\\"DEEPSEEK_API_KEY\\\", \\\"\\\")\\n\",\n \"DEEPSEEK_BASE_URL = os.environ.get(\\\"DEEPSEEK_BASE_URL\\\", \\\"https://api.deepseek.com\\\")\\n\",\n \"DEEPSEEK_MODEL = os.environ.get(\\\"DEEPSEEK_MODEL\\\", \\\"deepseek-chat\\\") # or your preferred\\n\",\n \"\\n\",\n \"if not DEEPSEEK_API_KEY:\\n\",\n \" raise RuntimeError(\\\"Please set DEEPSEEK_API_KEY in your environment (or .env).\\\")\\n\",\n \"\\n\",\n \"client = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\\n\",\n \"\\n\",\n \"def _chat_once(prefix: str, suffix: str, temperature=0.8, top_p=0.95, max_tokens=128) -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Sends a single chat completion asking for ONLY the Solidity predicate (no require(...);).\\n\",\n \" Uses a FIM-like instruction by giving prefix/suffix and a <FILL_ME> placeholder.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" prompt = (\\n\",\n \" \\\"You are filling a single-line Solidity predicate to go inside require(...).\\\\n\\\"\\n\",\n \" \\\"Given a source split into PREFIX and SUFFIX around a placeholder `require(<FILL_ME>);`, \\\"\\n\",\n \" \\\"produce ONLY the predicate expression for the require (no semicolon, no backticks, no commentary).\\\\n\\\"\\n\",\n \" \\\"Examples:\\\\n\\\"\\n\",\n \" \\\" - Output like: msg.sender == owner\\\\n\\\"\\n\",\n \" \\\" - NOT like: require(msg.sender == owner);\\\\n\\\"\\n\",\n \" \\\" - NOT like: ```solidity ... ```\\\\n\\\"\\n\",\n \" \\\"\\\\n\\\"\\n\",\n \" \\\"PREFIX:\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" f\\\"{prefix}\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" \\\"SUFFIX:\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" f\\\"{suffix}\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" )\\n\",\n \" resp = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"Return only the Solidity predicate expression.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt},\\n\",\n \" ],\\n\",\n \" temperature=temperature,\\n\",\n \" top_p=top_p,\\n\",\n \" max_tokens=max_tokens,\\n\",\n \" stop=None,\\n\",\n \" )\\n\",\n \" return (resp.choices[0].message.content or \\\"\\\").strip()\\n\",\n \"\\n\",\n \"def _extract_predicate(text: str) -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Normalize model output to a single-line predicate:\\n\",\n \" - Strip code fences/backticks/semicolons\\n\",\n \" - If it accidentally returned require(...), extract the (...)\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" t = text.strip()\\n\",\n \" t = re.sub(r\\\"^```[a-zA-Z]*\\\\s*\\\", \\\"\\\", t).strip()\\n\",\n \" t = re.sub(r\\\"```$\\\", \\\"\\\", t).strip()\\n\",\n \" # require(...) wrapper?\\n\",\n \" m = re.search(r\\\"require\\\\s*\\\\(\\\\s*(.+?)\\\\s*\\\\)\\\\s*;?\\\\s*$\\\", t, flags=re.S)\\n\",\n \" if m:\\n\",\n \" return m.group(1).strip()\\n\",\n \" # strip trailing semicolon if present\\n\",\n \" t = re.sub(r\\\";+$\\\", \\\"\\\", t).strip()\\n\",\n \" # collapse lines\\n\",\n \" t = \\\" \\\".join(t.splitlines()).strip()\\n\",\n \" return t\\n\",\n \"\\n\",\n \"def deepseek_generate_fim(prefix: str, suffix: str) -> str:\\n\",\n \" # lightweight retry/backoff\\n\",\n \" delays = [0, 1, 2, 4]\\n\",\n \" for d in delays:\\n\",\n \" if d: time.sleep(d)\\n\",\n \" try:\\n\",\n \" raw = _chat_once(prefix, suffix)\\n\",\n \" return _extract_predicate(raw)\\n\",\n \" except Exception:\\n\",\n \" if d == delays[-1]:\\n\",\n \" raise\\n\",\n \" continue\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"8be587ac\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Injection utilities: build masked prefix/suffix at a location (single-turn)\\n\",\n \"import validation_library as veri\\n\",\n \"\\n\",\n \"def _insert_mask_at_line(src: str, line_no_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert `require(<FILL_ME>);` BEFORE 1-based line_no_1based.\\n\",\n \" Returns (prefix, suffix, indent_str).\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" lines = src.splitlines()\\n\",\n \" idx = max(0, min(len(lines), line_no_1based - 1))\\n\",\n \" # Determine indentation: use target line's indentation if exists\\n\",\n \" if 0 <= idx < len(lines):\\n\",\n \" m = re.match(r\\\"^(\\\\s*)\\\", lines[idx])\\n\",\n \" indent = m.group(1) if m else indent_fallback\\n\",\n \" else:\\n\",\n \" indent = indent_fallback\\n\",\n \" masked = f\\\"{indent}require(<FILL_ME>);\\\"\\n\",\n \" prefix = \\\"\\\\n\\\".join(lines[:idx] + [masked])\\n\",\n \" suffix = \\\"\\\\n\\\".join(lines[idx:])\\n\",\n \" return prefix, suffix, indent\\n\",\n \"\\n\",\n \"def _insert_mask_at_function_entry(src: str, vl_line_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert mask as the first statement of the function that contains vl_line_1based.\\n\",\n \" Uses veri.find_function_bounds to resolve the function block.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" pre_line_0based, post_line_0based = veri.find_function_bounds(src, vl_line_1based) # returns 0-based\\n\",\n \" # we want to insert just after the opening brace -> typical pre = opening brace line\\n\",\n \" insert_at = pre_line_0based + 1 # 1-based\\n\",\n \" return _insert_mask_at_line(src, insert_at, indent_fallback=indent_fallback)\\n\",\n \"\\n\",\n \"def _insert_mask_at_function_exit(src: str, vl_line_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert mask just before the closing brace of the function that contains vl_line_1based.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" pre_line_0based, post_line_0based = veri.find_function_bounds(src, vl_line_1based)\\n\",\n \" insert_at = post_line_0based + 1 # convert to 1-based\\n\",\n \" return _insert_mask_at_line(src, insert_at, indent_fallback=indent_fallback)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"b773c049\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Core: single-turn synthesizer for {V, alpha, omega}\\n\",\n \"def synthesize_require_statement(\\n\",\n \" contract_text: str,\\n\",\n \" line_no: int, # VL reference line (1-based)\\n\",\n \" injection: str = \\\"V\\\", # \\\"V\\\" (target line), \\\"alpha\\\" (function entry), \\\"omega\\\" (function exit)\\n\",\n \" indent_fallback: str = \\\" \\\",\\n\",\n \" extra_hint: Optional[str] = None,\\n\",\n \") -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Returns ONLY the predicate (no semicolon). We will wrap as require({pred});\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" if injection == \\\"V\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_line(contract_text, line_no, indent_fallback)\\n\",\n \" elif injection == \\\"alpha\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_function_entry(contract_text, line_no, indent_fallback)\\n\",\n \" elif injection == \\\"omega\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_function_exit(contract_text, line_no, indent_fallback)\\n\",\n \" else:\\n\",\n \" raise ValueError(\\\"injection must be one of: 'V', 'alpha', 'omega'\\\")\\n\",\n \"\\n\",\n \" if extra_hint:\\n\",\n \" prefix = f\\\"// Hint: {extra_hint}\\\\n\\\" + prefix\\n\",\n \"\\n\",\n \" predicate = deepseek_generate_fim(prefix, suffix)\\n\",\n \" return predicate\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"19c25c07\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Seed loader (auto from your aggregated VL artifact)\\n\",\n \"# This replaces the previous seed_contracts-based cell.\\n\",\n \"\\n\",\n \"import os, json\\n\",\n \"from collections import defaultdict\\n\",\n \"\\n\",\n \"# We’ll auto-pick one of these paths unless SEED_VL_JSON is set.\\n\",\n \"CANDIDATES = [\\n\",\n \" os.environ.get(\\\"SEED_VL_JSON\\\", \\\"\\\").strip(),\\n\",\n \" \\\"reports/aggregated/DeepSeek/contract_VL.json\\\",\\n\",\n \" \\\"reports/aggregated/DeepSeek/contracts_VL.json\\\",\\n\",\n \" \\\"reports/aggregated/contract_VL.json\\\",\\n\",\n \"]\\n\",\n \"\\n\",\n \"seed_path = next((p for p in CANDIDATES if p and os.path.exists(p)), None)\\n\",\n \"if not seed_path:\\n\",\n \" raise RuntimeError(\\n\",\n \" \\\"Could not find a VL seed JSON. \\\"\\n\",\n \" \\\"Set SEED_VL_JSON to your file or generate reports/aggregated/DeepSeek/contract_VL.json first.\\\"\\n\",\n \" )\\n\",\n \"\\n\",\n \"with open(seed_path, \\\"r\\\", encoding=\\\"utf-8\\\") as f:\\n\",\n \" raw = json.load(f)\\n\",\n \"\\n\",\n \"# raw is expected to be: { name: [ [contract_text, { 'VL':[line, guard], 'pre':[line, ''], 'post':[line, ''] } ], ... ] }\\n\",\n \"# (Tuples become lists in JSON; guards may be empty strings.)\\n\",\n \"contracts_with_results = defaultdict(list)\\n\",\n \"\\n\",\n \"def _read_line_pair(x):\\n\",\n \" # Accept [line, guard] or just line\\n\",\n \" if isinstance(x, list) and x:\\n\",\n \" return int(x[0]), (x[1] if len(x) > 1 else \\\"\\\")\\n\",\n \" if isinstance(x, int):\\n\",\n \" return int(x), \\\"\\\"\\n\",\n \" return None, \\\"\\\"\\n\",\n \"\\n\",\n \"loaded = 0\\n\",\n \"for name, entries in raw.items():\\n\",\n \" for entry in entries:\\n\",\n \" # entry may be [contract_text, annotations] or a dict with same fields\\n\",\n \" if isinstance(entry, list) and len(entry) == 2:\\n\",\n \" contract_text, ann = entry\\n\",\n \" elif isinstance(entry, dict):\\n\",\n \" contract_text = entry.get(\\\"contract\\\") or entry.get(\\\"contract_text\\\") or entry.get(\\\"0\\\")\\n\",\n \" ann = entry.get(\\\"annotations\\\") or entry.get(\\\"1\\\") or {k: entry.get(k) for k in (\\\"VL\\\",\\\"pre\\\",\\\"post\\\")}\\n\",\n \" else:\\n\",\n \" continue\\n\",\n \"\\n\",\n \" if not isinstance(contract_text, str) or not contract_text.strip():\\n\",\n \" continue\\n\",\n \"\\n\",\n \" vl_line, vl_guard = _read_line_pair((ann or {}).get(\\\"VL\\\"))\\n\",\n \" pre_line, pre_guard = _read_line_pair((ann or {}).get(\\\"pre\\\"))\\n\",\n \" post_line, post_guard = _read_line_pair((ann or {}).get(\\\"post\\\"))\\n\",\n \"\\n\",\n \" # Fallback: recompute pre/post lines if missing using your helper\\n\",\n \" if not isinstance(vl_line, int) or vl_line <= 0:\\n\",\n \" continue\\n\",\n \" try:\\n\",\n \" pre0, post0 = veri.find_function_bounds(contract_text, vl_line) # 0-based\\n\",\n \" if not isinstance(pre_line, int) or pre_line <= 0:\\n\",\n \" pre_line = pre0 + 1 # store function-start (brace) line (0-based+1)\\n\",\n \" # We actually insert at first statement; later logic uses VL+injection to compute exact spot.\\n\",\n \" if not isinstance(post_line, int) or post_line <= 0:\\n\",\n \" post_line = post0 + 1 # closing brace line (0-based+1)\\n\",\n \" except Exception:\\n\",\n \" continue\\n\",\n \"\\n\",\n \" contracts_with_results[name].append((\\n\",\n \" contract_text,\\n\",\n \" {\\n\",\n \" \\\"VL\\\": (vl_line, vl_guard or \\\"\\\"),\\n\",\n \" \\\"pre\\\": (pre_line, pre_guard or \\\"\\\"),\\n\",\n \" \\\"post\\\":(post_line, post_guard or \\\"\\\"),\\n\",\n \" }\\n\",\n \" ))\\n\",\n \" loaded += 1\\n\",\n \"\\n\",\n \"print(f\\\"[seed] Loaded {loaded} contract entries from {seed_path}\\\")\\n\",\n \"len(contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"a8d85734\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Output directory for SINGLE-TURN results\\n\",\n \"os.makedirs(\\\"reports/isolated/DeepSeek\\\", exist_ok=True)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"8461a3bb\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% SINGLE-TURN: Vulnerable-line (V) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_V = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"VL single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" # SINGLE-TURN: use ORIGINAL contract (no prior injections)\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"V\\\")\\n\",\n \" results_V.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, vl_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"VL\\\"]\\n\",\n \"results_V += [''] * (len(all_contracts) - len(results_V))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, vl_line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_V, mapping), flat_entries):\\n\",\n \" annotations[\\\"VL\\\"] = (vl_line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"# Minimal VL-only drop (single-turn)\\n\",\n \"import validation_library as veri\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contract_VL_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"b1b01a15\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% SINGLE-TURN: PRE (alpha) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_alpha = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"PRE single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" pre_line, _ = annotations[\\\"pre\\\"]\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"alpha\\\")\\n\",\n \" results_alpha.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, pre_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"pre\\\"]\\n\",\n \"results_alpha += [''] * (len(all_contracts) - len(results_alpha))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_alpha, mapping), flat_entries):\\n\",\n \" line, _ = annotations[\\\"pre\\\"]\\n\",\n \" annotations[\\\"pre\\\"] = (line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contract_PV_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"91ca75eb\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% SINGLE-TURN: POST (omega) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_omega = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"POST single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" post_line, _ = annotations[\\\"post\\\"]\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"omega\\\")\\n\",\n \" results_omega.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, post_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"post\\\"]\\n\",\n \"results_omega += [''] * (len(all_contracts) - len(results_omega))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_omega, mapping), flat_entries):\\n\",\n \" annotations[\\\"post\\\"] = (line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contracts_PVP_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"51f5b999\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# This just shows the three locations we populated for the first item.\\n\",\n \"one_key = next(iter(contracts_with_results.keys()))\\n\",\n \"first_contract, ann = contracts_with_results[one_key][0]\\n\",\n \"ann\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"abfe553d\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \"Python 3\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.9.6\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n"}, "1e1ff481d6bab2cd767f66f16db8e0973afbd683": {"t": 1785753754.053595, "n": 17721, "h": "fcb5e11e0a1ad825", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"86039af7\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"# Requires: pip install openai python-dotenv\\n\",\n \"import os, time, re, json\\n\",\n \"from typing import Optional\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"\\n\",\n \"load_dotenv()\\n\",\n \"\\n\",\n \"try:\\n\",\n \" from openai import OpenAI\\n\",\n \"except Exception as e:\\n\",\n \" raise RuntimeError(\\\"Install the OpenAI SDK first: pip install openai\\\") from e\\n\",\n \"\\n\",\n \"DEEPSEEK_API_KEY = os.environ.get(\\\"DEEPSEEK_API_KEY\\\", \\\"\\\")\\n\",\n \"DEEPSEEK_BASE_URL = os.environ.get(\\\"DEEPSEEK_BASE_URL\\\", \\\"https://api.deepseek.com\\\")\\n\",\n \"DEEPSEEK_MODEL = os.environ.get(\\\"DEEPSEEK_MODEL\\\", \\\"deepseek-chat\\\") # or your preferred\\n\",\n \"\\n\",\n \"if not DEEPSEEK_API_KEY:\\n\",\n \" raise RuntimeError(\\\"Please set DEEPSEEK_API_KEY in your environment (or .env).\\\")\\n\",\n \"\\n\",\n \"client = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\\n\",\n \"\\n\",\n \"def _chat_once(prefix: str, suffix: str, temperature=0.8, top_p=0.95, max_tokens=128) -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Sends a single chat completion asking for ONLY the Solidity predicate (no require(...);).\\n\",\n \" Uses a FIM-like instruction by giving prefix/suffix and a <FILL_ME> placeholder.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" prompt = (\\n\",\n \" \\\"You are filling a single-line Solidity predicate to go inside require(...).\\\\n\\\"\\n\",\n \" \\\"Given a source split into PREFIX and SUFFIX around a placeholder `require(<FILL_ME>);`, \\\"\\n\",\n \" \\\"produce ONLY the predicate expression for the require (no semicolon, no backticks, no commentary).\\\\n\\\"\\n\",\n \" \\\"Examples:\\\\n\\\"\\n\",\n \" \\\" - Output like: msg.sender == owner\\\\n\\\"\\n\",\n \" \\\" - NOT like: require(msg.sender == owner);\\\\n\\\"\\n\",\n \" \\\" - NOT like: ```solidity ... ```\\\\n\\\"\\n\",\n \" \\\"\\\\n\\\"\\n\",\n \" \\\"PREFIX:\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" f\\\"{prefix}\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" \\\"SUFFIX:\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" f\\\"{suffix}\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" )\\n\",\n \" resp = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"Return only the Solidity predicate expression.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt},\\n\",\n \" ],\\n\",\n \" temperature=temperature,\\n\",\n \" top_p=top_p,\\n\",\n \" max_tokens=max_tokens,\\n\",\n \" stop=None,\\n\",\n \" )\\n\",\n \" return (resp.choices[0].message.content or \\\"\\\").strip()\\n\",\n \"\\n\",\n \"def _extract_predicate(text: str) -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Normalize model output to a single-line predicate:\\n\",\n \" - Strip code fences/backticks/semicolons\\n\",\n \" - If it accidentally returned require(...), extract the (...)\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" t = text.strip()\\n\",\n \" t = re.sub(r\\\"^```[a-zA-Z]*\\\\s*\\\", \\\"\\\", t).strip()\\n\",\n \" t = re.sub(r\\\"```$\\\", \\\"\\\", t).strip()\\n\",\n \" # require(...) wrapper?\\n\",\n \" m = re.search(r\\\"require\\\\s*\\\\(\\\\s*(.+?)\\\\s*\\\\)\\\\s*;?\\\\s*$\\\", t, flags=re.S)\\n\",\n \" if m:\\n\",\n \" return m.group(1).strip()\\n\",\n \" # strip trailing semicolon if present\\n\",\n \" t = re.sub(r\\\";+$\\\", \\\"\\\", t).strip()\\n\",\n \" # collapse lines\\n\",\n \" t = \\\" \\\".join(t.splitlines()).strip()\\n\",\n \" return t\\n\",\n \"\\n\",\n \"def deepseek_generate_fim(prefix: str, suffix: str) -> str:\\n\",\n \" # lightweight retry/backoff\\n\",\n \" delays = [0, 1, 2, 4]\\n\",\n \" for d in delays:\\n\",\n \" if d: time.sleep(d)\\n\",\n \" try:\\n\",\n \" raw = _chat_once(prefix, suffix)\\n\",\n \" return _extract_predicate(raw)\\n\",\n \" except Exception:\\n\",\n \" if d == delays[-1]:\\n\",\n \" raise\\n\",\n \" continue\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"8be587ac\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Injection utilities: build masked prefix/suffix at a location (single-turn)\\n\",\n \"import validation_library as veri\\n\",\n \"\\n\",\n \"def _insert_mask_at_line(src: str, line_no_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert `require(<FILL_ME>);` BEFORE 1-based line_no_1based.\\n\",\n \" Returns (prefix, suffix, indent_str).\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" lines = src.splitlines()\\n\",\n \" idx = max(0, min(len(lines), line_no_1based - 1))\\n\",\n \" # Determine indentation: use target line's indentation if exists\\n\",\n \" if 0 <= idx < len(lines):\\n\",\n \" m = re.match(r\\\"^(\\\\s*)\\\", lines[idx])\\n\",\n \" indent = m.group(1) if m else indent_fallback\\n\",\n \" else:\\n\",\n \" indent = indent_fallback\\n\",\n \" masked = f\\\"{indent}require(<FILL_ME>);\\\"\\n\",\n \" prefix = \\\"\\\\n\\\".join(lines[:idx] + [masked])\\n\",\n \" suffix = \\\"\\\\n\\\".join(lines[idx:])\\n\",\n \" return prefix, suffix, indent\\n\",\n \"\\n\",\n \"def _insert_mask_at_function_entry(src: str, vl_line_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert mask as the first statement of the function that contains vl_line_1based.\\n\",\n \" Uses veri.find_function_bounds to resolve the function block.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" pre_line_0based, post_line_0based = veri.find_function_bounds(src, vl_line_1based) # returns 0-based\\n\",\n \" # we want to insert just after the opening brace -> typical pre = opening brace line\\n\",\n \" insert_at = pre_line_0based + 1 # 1-based\\n\",\n \" return _insert_mask_at_line(src, insert_at, indent_fallback=indent_fallback)\\n\",\n \"\\n\",\n \"def _insert_mask_at_function_exit(src: str, vl_line_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert mask just before the closing brace of the function that contains vl_line_1based.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" pre_line_0based, post_line_0based = veri.find_function_bounds(src, vl_line_1based)\\n\",\n \" insert_at = post_line_0based + 1 # convert to 1-based\\n\",\n \" return _insert_mask_at_line(src, insert_at, indent_fallback=indent_fallback)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"b773c049\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Core: single-turn synthesizer for {V, alpha, omega}\\n\",\n \"def synthesize_require_statement(\\n\",\n \" contract_text: str,\\n\",\n \" line_no: int, # VL reference line (1-based)\\n\",\n \" injection: str = \\\"V\\\", # \\\"V\\\" (target line), \\\"alpha\\\" (function entry), \\\"omega\\\" (function exit)\\n\",\n \" indent_fallback: str = \\\" \\\",\\n\",\n \" extra_hint: Optional[str] = None,\\n\",\n \") -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Returns ONLY the predicate (no semicolon). We will wrap as require({pred});\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" if injection == \\\"V\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_line(contract_text, line_no, indent_fallback)\\n\",\n \" elif injection == \\\"alpha\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_function_entry(contract_text, line_no, indent_fallback)\\n\",\n \" elif injection == \\\"omega\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_function_exit(contract_text, line_no, indent_fallback)\\n\",\n \" else:\\n\",\n \" raise ValueError(\\\"injection must be one of: 'V', 'alpha', 'omega'\\\")\\n\",\n \"\\n\",\n \" if extra_hint:\\n\",\n \" prefix = f\\\"// Hint: {extra_hint}\\\\n\\\" + prefix\\n\",\n \"\\n\",\n \" predicate = deepseek_generate_fim(prefix, suffix)\\n\",\n \" return predicate\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"19c25c07\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Seed loader (auto from your aggregated VL artifact)\\n\",\n \"# This replaces the previous seed_contracts-based cell.\\n\",\n \"\\n\",\n \"import os, json\\n\",\n \"from collections import defaultdict\\n\",\n \"\\n\",\n \"# We’ll auto-pick one of these paths unless SEED_VL_JSON is set.\\n\",\n \"CANDIDATES = [\\n\",\n \" os.environ.get(\\\"SEED_VL_JSON\\\", \\\"\\\").strip(),\\n\",\n \" \\\"reports/aggregated/DeepSeek/contract_VL.json\\\",\\n\",\n \" \\\"reports/aggregated/DeepSeek/contracts_VL.json\\\",\\n\",\n \" \\\"reports/aggregated/contract_VL.json\\\",\\n\",\n \"]\\n\",\n \"\\n\",\n \"seed_path = next((p for p in CANDIDATES if p and os.path.exists(p)), None)\\n\",\n \"if not seed_path:\\n\",\n \" raise RuntimeError(\\n\",\n \" \\\"Could not find a VL seed JSON. \\\"\\n\",\n \" \\\"Set SEED_VL_JSON to your file or generate reports/aggregated/DeepSeek/contract_VL.json first.\\\"\\n\",\n \" )\\n\",\n \"\\n\",\n \"with open(seed_path, \\\"r\\\", encoding=\\\"utf-8\\\") as f:\\n\",\n \" raw = json.load(f)\\n\",\n \"\\n\",\n \"# raw is expected to be: { name: [ [contract_text, { 'VL':[line, guard], 'pre':[line, ''], 'post':[line, ''] } ], ... ] }\\n\",\n \"# (Tuples become lists in JSON; guards may be empty strings.)\\n\",\n \"contracts_with_results = defaultdict(list)\\n\",\n \"\\n\",\n \"def _read_line_pair(x):\\n\",\n \" # Accept [line, guard] or just line\\n\",\n \" if isinstance(x, list) and x:\\n\",\n \" return int(x[0]), (x[1] if len(x) > 1 else \\\"\\\")\\n\",\n \" if isinstance(x, int):\\n\",\n \" return int(x), \\\"\\\"\\n\",\n \" return None, \\\"\\\"\\n\",\n \"\\n\",\n \"loaded = 0\\n\",\n \"for name, entries in raw.items():\\n\",\n \" for entry in entries:\\n\",\n \" # entry may be [contract_text, annotations] or a dict with same fields\\n\",\n \" if isinstance(entry, list) and len(entry) == 2:\\n\",\n \" contract_text, ann = entry\\n\",\n \" elif isinstance(entry, dict):\\n\",\n \" contract_text = entry.get(\\\"contract\\\") or entry.get(\\\"contract_text\\\") or entry.get(\\\"0\\\")\\n\",\n \" ann = entry.get(\\\"annotations\\\") or entry.get(\\\"1\\\") or {k: entry.get(k) for k in (\\\"VL\\\",\\\"pre\\\",\\\"post\\\")}\\n\",\n \" else:\\n\",\n \" continue\\n\",\n \"\\n\",\n \" if not isinstance(contract_text, str) or not contract_text.strip():\\n\",\n \" continue\\n\",\n \"\\n\",\n \" vl_line, vl_guard = _read_line_pair((ann or {}).get(\\\"VL\\\"))\\n\",\n \" pre_line, pre_guard = _read_line_pair((ann or {}).get(\\\"pre\\\"))\\n\",\n \" post_line, post_guard = _read_line_pair((ann or {}).get(\\\"post\\\"))\\n\",\n \"\\n\",\n \" # Fallback: recompute pre/post lines if missing using your helper\\n\",\n \" if not isinstance(vl_line, int) or vl_line <= 0:\\n\",\n \" continue\\n\",\n \" try:\\n\",\n \" pre0, post0 = veri.find_function_bounds(contract_text, vl_line) # 0-based\\n\",\n \" if not isinstance(pre_line, int) or pre_line <= 0:\\n\",\n \" pre_line = pre0 + 1 # store function-start (brace) line (0-based+1)\\n\",\n \" # We actually insert at first statement; later logic uses VL+injection to compute exact spot.\\n\",\n \" if not isinstance(post_line, int) or post_line <= 0:\\n\",\n \" post_line = post0 + 1 # closing brace line (0-based+1)\\n\",\n \" except Exception:\\n\",\n \" continue\\n\",\n \"\\n\",\n \" contracts_with_results[name].append((\\n\",\n \" contract_text,\\n\",\n \" {\\n\",\n \" \\\"VL\\\": (vl_line, vl_guard or \\\"\\\"),\\n\",\n \" \\\"pre\\\": (pre_line, pre_guard or \\\"\\\"),\\n\",\n \" \\\"post\\\":(post_line, post_guard or \\\"\\\"),\\n\",\n \" }\\n\",\n \" ))\\n\",\n \" loaded += 1\\n\",\n \"\\n\",\n \"print(f\\\"[seed] Loaded {loaded} contract entries from {seed_path}\\\")\\n\",\n \"len(contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"a8d85734\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Output directory for SINGLE-TURN results\\n\",\n \"os.makedirs(\\\"reports/isolated/DeepSeek\\\", exist_ok=True)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"8461a3bb\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% SINGLE-TURN: Vulnerable-line (V) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_V = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"VL single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" # SINGLE-TURN: use ORIGINAL contract (no prior injections)\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"V\\\")\\n\",\n \" results_V.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, vl_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"VL\\\"]\\n\",\n \"results_V += [''] * (len(all_contracts) - len(results_V))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, vl_line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_V, mapping), flat_entries):\\n\",\n \" annotations[\\\"VL\\\"] = (vl_line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"# Minimal VL-only drop (single-turn)\\n\",\n \"import validation_library as veri\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contract_VL_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"b1b01a15\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% SINGLE-TURN: PRE (alpha) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_alpha = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"PRE single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" pre_line, _ = annotations[\\\"pre\\\"]\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"alpha\\\")\\n\",\n \" results_alpha.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, pre_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"pre\\\"]\\n\",\n \"results_alpha += [''] * (len(all_contracts) - len(results_alpha))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_alpha, mapping), flat_entries):\\n\",\n \" line, _ = annotations[\\\"pre\\\"]\\n\",\n \" annotations[\\\"pre\\\"] = (line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contract_PV_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"91ca75eb\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% SINGLE-TURN: POST (omega) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_omega = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"POST single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" post_line, _ = annotations[\\\"post\\\"]\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"omega\\\")\\n\",\n \" results_omega.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, post_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"post\\\"]\\n\",\n \"results_omega += [''] * (len(all_contracts) - len(results_omega))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_omega, mapping), flat_entries):\\n\",\n \" annotations[\\\"post\\\"] = (line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contracts_PVP_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"51f5b999\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# This just shows the three locations we populated for the first item.\\n\",\n \"one_key = next(iter(contracts_with_results.keys()))\\n\",\n \"first_contract, ann = contracts_with_results[one_key][0]\\n\",\n \"ann\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"abfe553d\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \"Python 3\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.9.6\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n"}, "a317e12fe6f706ae86f1043e9e812657cfa3c0d9": {"t": 1785753755.5528023, "n": 19024, "h": "a110caf50ddec4b7", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"id\": \"86039af7\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"# Requires: pip install openai python-dotenv\\n\",\n \"import os, time, re, json\\n\",\n \"from typing import Optional\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"\\n\",\n \"load_dotenv()\\n\",\n \"\\n\",\n \"try:\\n\",\n \" from openai import OpenAI\\n\",\n \"except Exception as e:\\n\",\n \" raise RuntimeError(\\\"Install the OpenAI SDK first: pip install openai\\\") from e\\n\",\n \"\\n\",\n \"DEEPSEEK_API_KEY = os.environ.get(\\\"DEEPSEEK_API_KEY\\\", \\\"\\\")\\n\",\n \"DEEPSEEK_BASE_URL = os.environ.get(\\\"DEEPSEEK_BASE_URL\\\", \\\"https://api.deepseek.com\\\")\\n\",\n \"DEEPSEEK_MODEL = os.environ.get(\\\"DEEPSEEK_MODEL\\\", \\\"deepseek-chat\\\") # or your preferred\\n\",\n \"\\n\",\n \"if not DEEPSEEK_API_KEY:\\n\",\n \" raise RuntimeError(\\\"Please set DEEPSEEK_API_KEY in your environment (or .env).\\\")\\n\",\n \"\\n\",\n \"client = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\\n\",\n \"\\n\",\n \"def _chat_once(prefix: str, suffix: str, temperature=0.8, top_p=0.95, max_tokens=128) -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Sends a single chat completion asking for ONLY the Solidity predicate (no require(...);).\\n\",\n \" Uses a FIM-like instruction by giving prefix/suffix and a <FILL_ME> placeholder.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" prompt = (\\n\",\n \" \\\"You are filling a single-line Solidity predicate to go inside require(...).\\\\n\\\"\\n\",\n \" \\\"Given a source split into PREFIX and SUFFIX around a placeholder `require(<FILL_ME>);`, \\\"\\n\",\n \" \\\"produce ONLY the predicate expression for the require (no semicolon, no backticks, no commentary).\\\\n\\\"\\n\",\n \" \\\"Examples:\\\\n\\\"\\n\",\n \" \\\" - Output like: msg.sender == owner\\\\n\\\"\\n\",\n \" \\\" - NOT like: require(msg.sender == owner);\\\\n\\\"\\n\",\n \" \\\" - NOT like: ```solidity ... ```\\\\n\\\"\\n\",\n \" \\\"\\\\n\\\"\\n\",\n \" \\\"PREFIX:\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" f\\\"{prefix}\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" \\\"SUFFIX:\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" f\\\"{suffix}\\\\n\\\"\\n\",\n \" \\\"-----\\\\n\\\"\\n\",\n \" )\\n\",\n \" resp = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"Return only the Solidity predicate expression.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt},\\n\",\n \" ],\\n\",\n \" temperature=temperature,\\n\",\n \" top_p=top_p,\\n\",\n \" max_tokens=max_tokens,\\n\",\n \" stop=None,\\n\",\n \" )\\n\",\n \" return (resp.choices[0].message.content or \\\"\\\").strip()\\n\",\n \"\\n\",\n \"def _extract_predicate(text: str) -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Normalize model output to a single-line predicate:\\n\",\n \" - Strip code fences/backticks/semicolons\\n\",\n \" - If it accidentally returned require(...), extract the (...)\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" t = text.strip()\\n\",\n \" t = re.sub(r\\\"^```[a-zA-Z]*\\\\s*\\\", \\\"\\\", t).strip()\\n\",\n \" t = re.sub(r\\\"```$\\\", \\\"\\\", t).strip()\\n\",\n \" # require(...) wrapper?\\n\",\n \" m = re.search(r\\\"require\\\\s*\\\\(\\\\s*(.+?)\\\\s*\\\\)\\\\s*;?\\\\s*$\\\", t, flags=re.S)\\n\",\n \" if m:\\n\",\n \" return m.group(1).strip()\\n\",\n \" # strip trailing semicolon if present\\n\",\n \" t = re.sub(r\\\";+$\\\", \\\"\\\", t).strip()\\n\",\n \" # collapse lines\\n\",\n \" t = \\\" \\\".join(t.splitlines()).strip()\\n\",\n \" return t\\n\",\n \"\\n\",\n \"def deepseek_generate_fim(prefix: str, suffix: str) -> str:\\n\",\n \" # lightweight retry/backoff\\n\",\n \" delays = [0, 1, 2, 4]\\n\",\n \" for d in delays:\\n\",\n \" if d: time.sleep(d)\\n\",\n \" try:\\n\",\n \" raw = _chat_once(prefix, suffix)\\n\",\n \" return _extract_predicate(raw)\\n\",\n \" except Exception:\\n\",\n \" if d == delays[-1]:\\n\",\n \" raise\\n\",\n \" continue\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 5,\n \"id\": \"8be587ac\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Injection utilities: build masked prefix/suffix at a location (single-turn)\\n\",\n \"import validation_library as veri\\n\",\n \"\\n\",\n \"def _insert_mask_at_line(src: str, line_no_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert `require(<FILL_ME>);` BEFORE 1-based line_no_1based.\\n\",\n \" Returns (prefix, suffix, indent_str).\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" lines = src.splitlines()\\n\",\n \" idx = max(0, min(len(lines), line_no_1based - 1))\\n\",\n \" # Determine indentation: use target line's indentation if exists\\n\",\n \" if 0 <= idx < len(lines):\\n\",\n \" m = re.match(r\\\"^(\\\\s*)\\\", lines[idx])\\n\",\n \" indent = m.group(1) if m else indent_fallback\\n\",\n \" else:\\n\",\n \" indent = indent_fallback\\n\",\n \" masked = f\\\"{indent}require(<FILL_ME>);\\\"\\n\",\n \" prefix = \\\"\\\\n\\\".join(lines[:idx] + [masked])\\n\",\n \" suffix = \\\"\\\\n\\\".join(lines[idx:])\\n\",\n \" return prefix, suffix, indent\\n\",\n \"\\n\",\n \"def _insert_mask_at_function_entry(src: str, vl_line_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert mask as the first statement of the function that contains vl_line_1based.\\n\",\n \" Uses veri.find_function_bounds to resolve the function block.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" pre_line_0based, post_line_0based = veri.find_function_bounds(src, vl_line_1based) # returns 0-based\\n\",\n \" # we want to insert just after the opening brace -> typical pre = opening brace line\\n\",\n \" insert_at = pre_line_0based + 1 # 1-based\\n\",\n \" return _insert_mask_at_line(src, insert_at, indent_fallback=indent_fallback)\\n\",\n \"\\n\",\n \"def _insert_mask_at_function_exit(src: str, vl_line_1based: int, indent_fallback=\\\" \\\"):\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Insert mask just before the closing brace of the function that contains vl_line_1based.\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" pre_line_0based, post_line_0based = veri.find_function_bounds(src, vl_line_1based)\\n\",\n \" insert_at = post_line_0based + 1 # convert to 1-based\\n\",\n \" return _insert_mask_at_line(src, insert_at, indent_fallback=indent_fallback)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 6,\n \"id\": \"b773c049\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Core: single-turn synthesizer for {V, alpha, omega}\\n\",\n \"def synthesize_require_statement(\\n\",\n \" contract_text: str,\\n\",\n \" line_no: int, # VL reference line (1-based)\\n\",\n \" injection: str = \\\"V\\\", # \\\"V\\\" (target line), \\\"alpha\\\" (function entry), \\\"omega\\\" (function exit)\\n\",\n \" indent_fallback: str = \\\" \\\",\\n\",\n \" extra_hint: Optional[str] = None,\\n\",\n \") -> str:\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" Returns ONLY the predicate (no semicolon). We will wrap as require({pred});\\n\",\n \" \\\"\\\"\\\"\\n\",\n \" if injection == \\\"V\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_line(contract_text, line_no, indent_fallback)\\n\",\n \" elif injection == \\\"alpha\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_function_entry(contract_text, line_no, indent_fallback)\\n\",\n \" elif injection == \\\"omega\\\":\\n\",\n \" prefix, suffix, _ = _insert_mask_at_function_exit(contract_text, line_no, indent_fallback)\\n\",\n \" else:\\n\",\n \" raise ValueError(\\\"injection must be one of: 'V', 'alpha', 'omega'\\\")\\n\",\n \"\\n\",\n \" if extra_hint:\\n\",\n \" prefix = f\\\"// Hint: {extra_hint}\\\\n\\\" + prefix\\n\",\n \"\\n\",\n \" predicate = deepseek_generate_fim(prefix, suffix)\\n\",\n \" return predicate\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 10,\n \"id\": \"19c25c07\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"[seed] Loaded 170 contract entries from reports/aggregated/DeepSeek/contract_VL.json\\n\"\n ]\n },\n {\n \"data\": {\n \"text/plain\": [\n \"130\"\n ]\n },\n \"execution_count\": 10,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"# %% Seed loader (auto from your aggregated VL artifact)\\n\",\n \"# This replaces the previous seed_contracts-based cell.\\n\",\n \"\\n\",\n \"import os, json\\n\",\n \"from collections import defaultdict\\n\",\n \"\\n\",\n \"# We’ll auto-pick one of these paths unless SEED_VL_JSON is set.\\n\",\n \"CANDIDATES = [\\n\",\n \" os.environ.get(\\\"SEED_VL_JSON\\\", \\\"\\\").strip(),\\n\",\n \" \\\"reports/aggregated/DeepSeek/contract_VL.json\\\",\\n\",\n \" \\\"reports/aggregated/DeepSeek/contracts_VL.json\\\",\\n\",\n \" \\\"reports/aggregated/contract_VL.json\\\",\\n\",\n \"]\\n\",\n \"\\n\",\n \"seed_path = next((p for p in CANDIDATES if p and os.path.exists(p)), None)\\n\",\n \"if not seed_path:\\n\",\n \" raise RuntimeError(\\n\",\n \" \\\"Could not find a VL seed JSON. \\\"\\n\",\n \" \\\"Set SEED_VL_JSON to your file or generate reports/aggregated/DeepSeek/contract_VL.json first.\\\"\\n\",\n \" )\\n\",\n \"\\n\",\n \"with open(seed_path, \\\"r\\\", encoding=\\\"utf-8\\\") as f:\\n\",\n \" raw = json.load(f)\\n\",\n \"\\n\",\n \"# raw is expected to be: { name: [ [contract_text, { 'VL':[line, guard], 'pre':[line, ''], 'post':[line, ''] } ], ... ] }\\n\",\n \"# (Tuples become lists in JSON; guards may be empty strings.)\\n\",\n \"contracts_with_results = defaultdict(list)\\n\",\n \"\\n\",\n \"def _read_line_pair(x):\\n\",\n \" # Accept [line, guard] or just line\\n\",\n \" if isinstance(x, list) and x:\\n\",\n \" return int(x[0]), (x[1] if len(x) > 1 else \\\"\\\")\\n\",\n \" if isinstance(x, int):\\n\",\n \" return int(x), \\\"\\\"\\n\",\n \" return None, \\\"\\\"\\n\",\n \"\\n\",\n \"loaded = 0\\n\",\n \"for name, entries in raw.items():\\n\",\n \" for entry in entries:\\n\",\n \" # entry may be [contract_text, annotations] or a dict with same fields\\n\",\n \" if isinstance(entry, list) and len(entry) == 2:\\n\",\n \" contract_text, ann = entry\\n\",\n \" elif isinstance(entry, dict):\\n\",\n \" contract_text = entry.get(\\\"contract\\\") or entry.get(\\\"contract_text\\\") or entry.get(\\\"0\\\")\\n\",\n \" ann = entry.get(\\\"annotations\\\") or entry.get(\\\"1\\\") or {k: entry.get(k) for k in (\\\"VL\\\",\\\"pre\\\",\\\"post\\\")}\\n\",\n \" else:\\n\",\n \" continue\\n\",\n \"\\n\",\n \" if not isinstance(contract_text, str) or not contract_text.strip():\\n\",\n \" continue\\n\",\n \"\\n\",\n \" vl_line, vl_guard = _read_line_pair((ann or {}).get(\\\"VL\\\"))\\n\",\n \" pre_line, pre_guard = _read_line_pair((ann or {}).get(\\\"pre\\\"))\\n\",\n \" post_line, post_guard = _read_line_pair((ann or {}).get(\\\"post\\\"))\\n\",\n \"\\n\",\n \" # Fallback: recompute pre/post lines if missing using your helper\\n\",\n \" if not isinstance(vl_line, int) or vl_line <= 0:\\n\",\n \" continue\\n\",\n \" try:\\n\",\n \" pre0, post0 = veri.find_function_bounds(contract_text, vl_line) # 0-based\\n\",\n \" if not isinstance(pre_line, int) or pre_line <= 0:\\n\",\n \" pre_line = pre0 + 1 # store function-start (brace) line (0-based+1)\\n\",\n \" # We actually insert at first statement; later logic uses VL+injection to compute exact spot.\\n\",\n \" if not isinstance(post_line, int) or post_line <= 0:\\n\",\n \" post_line = post0 + 1 # closing brace line (0-based+1)\\n\",\n \" except Exception:\\n\",\n \" continue\\n\",\n \"\\n\",\n \" contracts_with_results[name].append((\\n\",\n \" contract_text,\\n\",\n \" {\\n\",\n \" \\\"VL\\\": (vl_line, vl_guard or \\\"\\\"),\\n\",\n \" \\\"pre\\\": (pre_line, pre_guard or \\\"\\\"),\\n\",\n \" \\\"post\\\":(post_line, post_guard or \\\"\\\"),\\n\",\n \" }\\n\",\n \" ))\\n\",\n \" loaded += 1\\n\",\n \"\\n\",\n \"print(f\\\"[seed] Loaded {loaded} contract entries from {seed_path}\\\")\\n\",\n \"len(contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 11,\n \"id\": \"a8d85734\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# %% Output directory for SINGLE-TURN results\\n\",\n \"os.makedirs(\\\"reports/isolated/DeepSeek\\\", exist_ok=True)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 12,\n \"id\": \"8461a3bb\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"VL single-turn: 0%| | 0/130 [00:00<?, ?it/s]\"\n ]\n },\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"VL single-turn: 100%|██████████| 130/130 [10:31<00:00, 4.86s/it]\\n\"\n ]\n }\n ],\n \"source\": [\n \"# %% SINGLE-TURN: Vulnerable-line (V) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_V = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"VL single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" # SINGLE-TURN: use ORIGINAL contract (no prior injections)\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"V\\\")\\n\",\n \" results_V.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, vl_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"VL\\\"]\\n\",\n \"results_V += [''] * (len(all_contracts) - len(results_V))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, vl_line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_V, mapping), flat_entries):\\n\",\n \" annotations[\\\"VL\\\"] = (vl_line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"# Minimal VL-only drop (single-turn)\\n\",\n \"import validation_library as veri\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contract_VL_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 13,\n \"id\": \"b1b01a15\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"PRE single-turn: 100%|██████████| 130/130 [10:24<00:00, 4.81s/it]\\n\"\n ]\n }\n ],\n \"source\": [\n \"# %% SINGLE-TURN: PRE (alpha) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_alpha = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"PRE single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" pre_line, _ = annotations[\\\"pre\\\"]\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"alpha\\\")\\n\",\n \" results_alpha.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, pre_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"pre\\\"]\\n\",\n \"results_alpha += [''] * (len(all_contracts) - len(results_alpha))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_alpha, mapping), flat_entries):\\n\",\n \" line, _ = annotations[\\\"pre\\\"]\\n\",\n \" annotations[\\\"pre\\\"] = (line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contract_PV_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 14,\n \"id\": \"91ca75eb\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"POST single-turn: 100%|██████████| 130/130 [10:23<00:00, 4.79s/it]\\n\"\n ]\n }\n ],\n \"source\": [\n \"# %% SINGLE-TURN: POST (omega) inference (original contract only)\\n\",\n \"from tqdm import tqdm\\n\",\n \"\\n\",\n \"all_contracts = []\\n\",\n \"mapping = []\\n\",\n \"results_omega = []\\n\",\n \"\\n\",\n \"for contract_name, entries in tqdm(contracts_with_results.items(), desc=\\\"POST single-turn\\\"):\\n\",\n \" for contract, annotations in entries:\\n\",\n \" vl_line, _ = annotations[\\\"VL\\\"]\\n\",\n \" post_line, _ = annotations[\\\"post\\\"]\\n\",\n \" pred = synthesize_require_statement(contract, line_no=vl_line, injection=\\\"omega\\\")\\n\",\n \" results_omega.append(pred)\\n\",\n \" all_contracts.append(contract)\\n\",\n \" mapping.append((contract_name, contract, post_line))\\n\",\n \"\\n\",\n \"# write back to annotations[\\\"post\\\"]\\n\",\n \"results_omega += [''] * (len(all_contracts) - len(results_omega))\\n\",\n \"flat_entries = [(cn, entry) for cn, es in contracts_with_results.items() for entry in es]\\n\",\n \"\\n\",\n \"for (generated, (contract_name, contract, line)), (_, (existing_contract, annotations)) in \\\\\\n\",\n \" zip(zip(results_omega, mapping), flat_entries):\\n\",\n \" annotations[\\\"post\\\"] = (line, f\\\"require({generated});\\\")\\n\",\n \"\\n\",\n \"veri.print_json_report(\\\"reports/isolated/DeepSeek/contracts_PVP_single.json\\\", contracts_with_results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"51f5b999\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"{'VL': (11, 'require(max > 0);'),\\n\",\n \" 'pre': (11, 'require(salt == 0);'),\\n\",\n \" 'post': (26, 'require(msg.sender == address(this));')}\"\n ]\n },\n \"execution_count\": 15,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"# This just shows the three locations we populated for the first item.\\n\",\n \"one_key = next(iter(contracts_with_results.keys()))\\n\",\n \"first_contract, ann = contracts_with_results[one_key][0]\\n\",\n \"ann\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"abfe553d\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \"Python 3\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.9.6\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n"}}}}