import%20marimo%0A%0A__generated_with%20%3D%20%220.22.4%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20sqlite3%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20os%0A%20%20%20%20import%20re%0A%20%20%20%20import%20logging%0A%20%20%20%20import%20ast%0A%20%20%20%20from%20typing%20import%20Dict%2C%20Any%2C%20Tuple%2C%20List%0A%20%20%20%20from%20CyVer%20import%20SyntaxValidator%0A%20%20%20%20from%20neo4j%20import%20GraphDatabase%2C%20basic_auth%0A%20%20%20%20from%20model_evaluator%20import%20ModelEvaluator%0A%0A%20%20%20%20%23%20Silence%20verbose%20Neo4j%20notifications%0A%20%20%20%20logging.getLogger(%22neo4j%22).setLevel(logging.ERROR)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Any%2C%0A%20%20%20%20%20%20%20%20Dict%2C%0A%20%20%20%20%20%20%20%20GraphDatabase%2C%0A%20%20%20%20%20%20%20%20List%2C%0A%20%20%20%20%20%20%20%20ModelEvaluator%2C%0A%20%20%20%20%20%20%20%20SyntaxValidator%2C%0A%20%20%20%20%20%20%20%20Tuple%2C%0A%20%20%20%20%20%20%20%20ast%2C%0A%20%20%20%20%20%20%20%20basic_auth%2C%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20pd%2C%0A%20%20%20%20%20%20%20%20plt%2C%0A%20%20%20%20%20%20%20%20re%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20Model%20Analysis%3A%20Reasoning%20Performance%0A%0A%20%20%20%20This%20notebook%20analyzes%20the%20performance%20of%20**Qwen%2FQwen3.5-0.8B**%20on%20the%20**LC-QuAD%202.0**%20dataset%20when%20reasoning%20is%20enabled.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Data%20Loading%20and%20Preparation%0A%0A%20%20%20%20We%20retrieve%20cached%20model%20responses%20from%20a%20SQLite%20database%20(%60ai_cache.db%60).%0A%20%20%20%20For%20**Reasoning%20ON**%2C%20we%20parse%20the%20content%20to%20separate%20the%20%60%3Cthink%3E%60%20reasoning%20block%20from%20the%20final%20Cypher%20query.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ModelEvaluator%2C%20pd)%3A%0A%20%20%20%20evaluator%20%3D%20ModelEvaluator(model_name%3D'dummy'%2C%20api_key%3D'')%0A%0A%20%20%20%20%23%20Load%20reasoning%3D1%20data%20with%20all%20fields%0A%20%20%20%20df_reason%20%3D%20evaluator.fetch_cached_responses('Qwen%2FQwen3.5-0.8B'%2C%20'lc-quad-2.0'%2C%20include_reasoning%3D1)%0A%20%20%20%20df_reason.rename(columns%3D%7B'content'%3A%20'full_content'%7D%2C%20inplace%3DTrue)%0A%0A%20%20%20%20def%20_extract_parts(text)%3A%0A%20%20%20%20%20%20%20%20if%20not%20text%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20None%0A%20%20%20%20%20%20%20%20_clean_text%20%3D%20text.replace(%22%3Cthink%3E%22%2C%20%22%22)%0A%20%20%20%20%20%20%20%20before%2C%20sep%2C%20after%20%3D%20_clean_text.partition(%22%3C%2Fthink%3E%22)%0A%20%20%20%20%20%20%20%20before%2C%20after%20%3D%20before.strip()%2C%20after.strip()%0A%0A%20%20%20%20%20%20%20%20if%20not%20before%20or%20not%20sep%20or%20not%20after%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20None%0A%20%20%20%20%20%20%20%20return%20before%2C%20after%0A%0A%20%20%20%20_parts%20%3D%20df_reason%5B'full_content'%5D.apply(_extract_parts)%0A%20%20%20%20invalid_response_count%20%3D%20int(_parts.isna().sum())%0A%20%20%20%20_valid_parts%20%3D%20_parts.dropna()%0A%0A%20%20%20%20%23%20Initialize%20columns%20with%20empty%2FNone%0A%20%20%20%20df_reason%5B'thinking_text'%5D%20%3D%20%22%22%0A%20%20%20%20df_reason%5B'query_text'%5D%20%3D%20%22%22%0A%0A%20%20%20%20%23%20Map%20valid%20parts%20back%20to%20the%20dataframe%0A%20%20%20%20if%20not%20_valid_parts.empty%3A%0A%20%20%20%20%20%20%20%20df_reason%20%3D%20df_reason.loc%5B_valid_parts.index%5D.copy()%0A%20%20%20%20%20%20%20%20df_reason%5B'thinking_text'%5D%20%3D%20_valid_parts.apply(lambda%20x%3A%20x%5B0%5D)%0A%20%20%20%20%20%20%20%20df_reason%5B'query_text'%5D%20%3D%20_valid_parts.apply(lambda%20x%3A%20x%5B1%5D)%0A%0A%20%20%20%20df_reason%5B'thinking_length'%5D%20%3D%20pd.to_numeric(df_reason%5B'thinking_text'%5D.str.len()%2C%20errors%3D'coerce')%0A%20%20%20%20df_reason%5B'query_length'%5D%20%3D%20pd.to_numeric(df_reason%5B'query_text'%5D.str.len()%2C%20errors%3D'coerce')%0A%20%20%20%20return%20df_reason%2C%20invalid_response_count%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Data%20Preview%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20mo)%3A%0A%20%20%20%20_preview%20%3D%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%23%20Preview%3A%20Reasoning%20ON%22)%2C%0A%20%20%20%20%20%20%20%20mo.ui.table(df_reason.head())%0A%20%20%20%20%5D)%0A%20%20%20%20_preview%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20invalid_response_count%2C%20mo)%3A%0A%20%20%20%20if%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_stats_md%20%3D%20mo.md(%22%23%20Missing%20data%20for%20analysis.%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20_s_re%20%3D%20df_reason%5B'query_length'%5D.describe()%0A%20%20%20%20%20%20%20%20_s_th%20%3D%20df_reason%5B'thinking_length'%5D.describe()%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20a%20small%20warning%20string%20if%20there%20are%20invalid%20responses%0A%20%20%20%20%20%20%20%20_invalid_msg%20%3D%20%22%22%0A%20%20%20%20%20%20%20%20if%20invalid_response_count%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_invalid_msg%20%3D%20f%22**Note%3A**%20%7Binvalid_response_count%7D%20responses%20were%20skipped%20because%20they%20were%20missing%20%60%3C%2Fthink%3E%60%20tags.%22%0A%0A%20%20%20%20%20%20%20%20_stats_md%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Summary%20Statistics%3A%20Reasoning%20Performance%0A%0A%20%20%20%20%20%20%20%20This%20table%20analyzes%20the%20character%20lengths%3A%0A%20%20%20%20%20%20%20%20-%20**ON%3A%20Query**%3A%20The%20extracted%20query%20section.%0A%20%20%20%20%20%20%20%20-%20**ON%3A%20Thinking**%3A%20The%20reasoning%20content%20extracted%20from%20%60%3Cthink%3E%60%20tags.%0A%0A%20%20%20%20%20%20%20%20%7C%20Metric%20%7C%20ON%3A%20Query%20%7C%20ON%3A%20Thinking%20%7C%0A%20%20%20%20%20%20%20%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Count**%20%7C%20%7B_s_re%5B'count'%5D%3A.0f%7D%20%7C%20%7B_s_th%5B'count'%5D%3A.0f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Mean**%20%7C%20%7B_s_re%5B'mean'%5D%3A.2f%7D%20%7C%20%7B_s_th%5B'mean'%5D%3A.2f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Median%20(50%25)**%20%7C%20%7B_s_re%5B'50%25'%5D%3A.2f%7D%20%7C%20%7B_s_th%5B'50%25'%5D%3A.2f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Std%20Dev**%20%7C%20%7B_s_re%5B'std'%5D%3A.2f%7D%20%7C%20%7B_s_th%5B'std'%5D%3A.2f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Min**%20%7C%20%7B_s_re%5B'min'%5D%3A.0f%7D%20%7C%20%7B_s_th%5B'min'%5D%3A.0f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Max**%20%7C%20%7B_s_re%5B'max'%5D%3A.0f%7D%20%7C%20%7B_s_th%5B'max'%5D%3A.0f%7D%20%7C%0A%0A%20%20%20%20%20%20%20%20%7B_invalid_msg%7D%0A%20%20%20%20%20%20%20%20%22%22%22)%0A%0A%20%20%20%20_stats_md%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20mo%2C%20pd)%3A%0A%20%20%20%20def%20_get_samples(df%2C%20text_col%2C%20n%3D5)%3A%0A%20%20%20%20%20%20%20%20if%20df.empty%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20pd.DataFrame()%0A%0A%20%20%20%20%20%20%20%20%23%20Ensure%20variety%20by%20dropping%20identical%20queries%20first%0A%20%20%20%20%20%20%20%20_unique_df%20%3D%20df.drop_duplicates(subset%3D%5Btext_col%5D)%0A%20%20%20%20%20%20%20%20_n%20%3D%20min(n%2C%20len(_unique_df))%0A%0A%20%20%20%20%20%20%20%20%23%20Random%20sample%20for%20a%20diverse%20view%0A%20%20%20%20%20%20%20%20return%20_unique_df.sample(n%3D_n%2C%20random_state%3D42)%0A%0A%20%20%20%20_samples_on%20%3D%20_get_samples(df_reason%2C%20'query_text')%0A%0A%20%20%20%20def%20_format_list(samples%2C%20text_col)%3A%0A%20%20%20%20%20%20%20%20if%20samples.empty%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22_No%20samples%20available._%22%0A%0A%20%20%20%20%20%20%20%20items%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20_%2C%20_row%20in%20samples.iterrows()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_question%20%3D%20_row%5B'question'%5D%20if%20'question'%20in%20_row%20else%20%22Unknown%20Question%22%0A%20%20%20%20%20%20%20%20%20%20%20%20_length%20%3D%20int(_row%5B'query_length'%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_text%20%3D%20_row%5Btext_col%5D.strip()%20if%20_row%5Btext_col%5D%20else%20%22%5BEmpty%5D%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Format%20each%20sample%20with%20its%20question%20and%20the%20Cypher%20query%0A%20%20%20%20%20%20%20%20%20%20%20%20_item_md%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22**Question%3A**%20%7B_question%7D%5Cn%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22**Query%20(Length%3A%20%7B_length%7D%20chars)%3A**%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22%60%60%60cypher%5Cn%7B_text%7D%5Cn%60%60%60%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20items.append(_item_md)%0A%0A%20%20%20%20%20%20%20%20return%20%22%5Cn%5Cn---%5Cn%5Cn%22.join(items)%0A%0A%20%20%20%20_content%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%20Random%20Sample%20Queries%0A%0A%20%20%20%20These%20samples%20are%20selected%20at%20random%20from%20the%20dataset%20to%20provide%20a%20diverse%20look%20at%20the%20model's%20output%20quality.%0A%0A%20%20%20%20%23%23%23%20Reasoning%20ON%20(Average%3A%20%7Bdf_reason%5B'query_length'%5D.mean()%20if%20not%20df_reason.empty%20else%200%3A.1f%7D%20chars)%0A%20%20%20%20%7B_format_list(_samples_on%2C%20'query_text')%7D%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20_content%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Distribution%20Analysis%0A%0A%20%20%20%20The%20following%20visualizations%20analyze%20the%20character%20length%20distributions%20of%20the%20generated%20Cypher%20queries%20when%20reasoning%20is%20enabled.%0A%20%20%20%20Note%20that%20we%20only%20measure%20the%20*final%20query*%20length%2C%20excluding%20the%20thinking%20process.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20plt)%3A%0A%20%20%20%20_fig%20%3D%20None%0A%20%20%20%20if%20not%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_l1%2C%20_u1%20%3D%20df_reason%5B'query_length'%5D.quantile(0.05)%2C%20df_reason%5B'query_length'%5D.quantile(0.95)%0A%0A%20%20%20%20%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(10%2C%206))%0A%0A%20%20%20%20%20%20%20%20_ax.hist(df_reason%5B'query_length'%5D%2C%20bins%3D50%2C%20range%3D(_l1%2C%20_u1)%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.6%2C%20label%3D'Reasoning%20ON%20(Extracted%20Query)'%2C%20color%3D'orange'%2C%20edgecolor%3D'darkorange')%0A%0A%20%20%20%20%20%20%20%20_ax.set_title(%22Query%20Length%20Distribution%3A%20Reasoning%20ON%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22Query%20Length%20(characters)%22)%0A%20%20%20%20%20%20%20%20_ax.set_ylabel(%22Frequency%22)%0A%20%20%20%20%20%20%20%20_ax.legend()%0A%20%20%20%20%20%20%20%20_ax.grid(True%2C%20alpha%3D0.3)%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20plt)%3A%0A%20%20%20%20_fig%20%3D%20None%0A%20%20%20%20if%20not%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_u1%20%3D%20df_reason%5B'query_length'%5D.quantile(0.95)%0A%0A%20%20%20%20%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(10%2C%204))%0A%20%20%20%20%20%20%20%20_ax.boxplot(df_reason%5B'query_length'%5D%2C%20vert%3DFalse%2C%20labels%3D%5B'Reasoning%20ON%20(Query)'%5D%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20patch_artist%3DTrue%2C%20boxprops%3Ddict(facecolor%3D'orange'%2C%20alpha%3D0.6))%0A%0A%20%20%20%20%20%20%20%20_ax.set_xlim(0%2C%20_u1)%20%0A%0A%20%20%20%20%20%20%20%20_ax.set_title(%22Response%20Length%20Box%20Plot%20(Reasoning%20ON)%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22Length%20(characters)%22)%0A%20%20%20%20%20%20%20%20_ax.grid(axis%3D'x'%2C%20alpha%3D0.3)%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Thinking%20Process%20Analysis%0A%0A%20%20%20%20When%20reasoning%20is%20enabled%2C%20the%20model%20generates%20a%20%22thinking%22%20chain%20before%20producing%20the%20final%20query.%0A%20%20%20%20Below%20is%20the%20distribution%20of%20the%20length%20(in%20characters)%20of%20these%20reasoning%20paths.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20plt)%3A%0A%20%20%20%20_fig%20%3D%20None%0A%20%20%20%20if%20not%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_l%2C%20_u%20%3D%20df_reason%5B'thinking_length'%5D.quantile(0.05)%2C%20df_reason%5B'thinking_length'%5D.quantile(0.95)%0A%20%20%20%20%20%20%20%20_df_mid%20%3D%20df_reason%5B(df_reason%5B'thinking_length'%5D%20%3E%3D%20_l)%20%26%20(df_reason%5B'thinking_length'%5D%20%3C%3D%20_u)%5D%0A%0A%20%20%20%20%20%20%20%20_fig%2C%20(_ax_hist%2C%20_ax_box)%20%3D%20plt.subplots(nrows%3D2%2C%20ncols%3D1%2C%20figsize%3D(10%2C%2010)%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gridspec_kw%3D%7B'height_ratios'%3A%20%5B3%2C%201%5D%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sharex%3DTrue)%0A%0A%20%20%20%20%20%20%20%20_ax_hist.hist(_df_mid%5B'thinking_length'%5D%2C%20bins%3D50%2C%20color%3D'purple'%2C%20edgecolor%3D'black'%2C%20alpha%3D0.7)%0A%20%20%20%20%20%20%20%20_ax_hist.set_title(%22Distribution%20of%20Thinking%20Length%20(Reasoning%20ON)%22)%0A%20%20%20%20%20%20%20%20_ax_hist.set_ylabel(%22Frequency%22)%0A%20%20%20%20%20%20%20%20_ax_hist.grid(axis%3D'y'%2C%20alpha%3D0.3)%0A%0A%20%20%20%20%20%20%20%20_ax_box.boxplot(df_reason%5B'thinking_length'%5D%2C%20vert%3DFalse%2C%20patch_artist%3DTrue%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20boxprops%3Ddict(facecolor%3D'plum'))%0A%20%20%20%20%20%20%20%20_ax_box.set_xlabel(%22Thinking%20Length%20(characters)%22)%0A%20%20%20%20%20%20%20%20_ax_box.set_yticks(%5B%5D)%0A%20%20%20%20%20%20%20%20_ax_box.grid(axis%3D'x'%2C%20alpha%3D0.3)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Cypher%20Query%20Syntax%20Validation%20(CyVer%20AST)%0A%0A%20%20%20%20We%20validate%20all%20generated%20Cypher%20queries%20using%20**CyVer**'s%20%60SyntaxValidator%60%2C%20which%20uses%20the%20openCypher%20ANTLR%20grammar%20under%20the%20hood%20to%20perform%20real%20AST-based%20syntax%20validation.%0A%0A%20%20%20%20This%20analysis%20determines%20what%20percentage%20of%20the%20model's%20generated%20queries%20are%20syntactically%20invalid.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Any%2C%20Dict%2C%20GraphDatabase%2C%20SyntaxValidator%2C%20Tuple%2C%20basic_auth%2C%20df_reason)%3A%0A%20%20%20%20%23%20Connect%20to%20Neo4j%20(required%20by%20CyVer)%0A%20%20%20%20_uri%3A%20str%20%3D%20%22bolt%3A%2F%2Flocalhost%3A7687%22%0A%20%20%20%20_auth%3A%20Tuple%5Bstr%2C%20str%5D%20%3D%20basic_auth(%22neo4j%22%2C%20%22password-to-kg%22)%0A%20%20%20%20_driver%20%3D%20GraphDatabase.driver(_uri%2C%20auth%3D_auth)%0A%0A%20%20%20%20_validator%3A%20SyntaxValidator%20%3D%20SyntaxValidator(_driver%2C%20check_multilabeled_nodes%3DFalse)%0A%0A%20%20%20%20def%20_validate_query(query_text%3A%20str)%20-%3E%20Dict%5Bstr%2C%20Any%5D%3A%0A%20%20%20%20%20%20%20%20%22%22%22Validate%20a%20single%20Cypher%20query%20using%20CyVer%20SyntaxValidator.%22%22%22%0A%20%20%20%20%20%20%20%20if%20not%20query_text%20or%20not%20isinstance(query_text%2C%20str)%20or%20not%20query_text.strip()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22is_valid%22%3A%20False%2C%20%22error%22%3A%20%22Empty%20or%20None%20query%22%7D%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20CyVer%20returns%20(is_valid%3A%20bool%2C%20metadata%3A%20dict)%0A%20%20%20%20%20%20%20%20%20%20%20%20_is_valid%3A%20bool%0A%20%20%20%20%20%20%20%20%20%20%20%20_metadata%3A%20Dict%5Bstr%2C%20Any%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_is_valid%2C%20_metadata%20%3D%20_validator.validate(query_text.strip())%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22is_valid%22%3A%20_is_valid%2C%20%22error%22%3A%20%22%22%20if%20_is_valid%20else%20str(_metadata)%7D%0A%20%20%20%20%20%20%20%20except%20Exception%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22is_valid%22%3A%20False%2C%20%22error%22%3A%20f%22Exception%3A%20%7Bstr(e)%7D%22%7D%0A%0A%20%20%20%20%23%20---%20Process%20Reasoning%20ON%20Subset%20(up%20to%20100)%20---%0A%20%20%20%20_count_re%3A%20int%20%3D%20min(100%2C%20len(df_reason))%0A%20%20%20%20df_re_sample%20%3D%20df_reason.sample(n%3D_count_re%2C%20random_state%3D42).copy()%20if%20_count_re%20%3E%200%20else%20df_reason.copy()%0A%0A%20%20%20%20_results_re%20%3D%20df_re_sample%5B'query_text'%5D.apply(_validate_query)%0A%20%20%20%20df_re_sample%5B'is_valid'%5D%20%3D%20_results_re.apply(lambda%20x%3A%20x%5B'is_valid'%5D)%0A%20%20%20%20df_re_sample%5B'validation_error'%5D%20%3D%20_results_re.apply(lambda%20x%3A%20x%5B'error'%5D)%0A%0A%20%20%20%20_driver.close()%0A%0A%20%20%20%20%23%20Compute%20Statistics%20for%20Samples%0A%20%20%20%20total_re%3A%20int%20%3D%20len(df_re_sample)%0A%20%20%20%20valid_re%3A%20int%20%3D%20int(df_re_sample%5B'is_valid'%5D.sum())%0A%20%20%20%20invalid_re%3A%20int%20%3D%20total_re%20-%20valid_re%0A%20%20%20%20pct_invalid_re%3A%20float%20%3D%20(invalid_re%20%2F%20total_re%20*%20100)%20if%20total_re%20%3E%200%20else%200.0%0A%20%20%20%20return%20df_re_sample%2C%20invalid_re%2C%20pct_invalid_re%2C%20total_re%2C%20valid_re%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20invalid_re%3A%20int%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20pct_invalid_re%3A%20float%2C%0A%20%20%20%20total_re%3A%20int%2C%0A%20%20%20%20valid_re%3A%20int%2C%0A)%3A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%23%20Validation%20Results%20Summary%20(Subset%20Sample%3A%20n%3D100)%0A%0A%20%20%20%20%7C%20Reasoning%20Mode%20%7C%20Total%20Sample%20%7C%20Valid%20Queries%20%7C%20Invalid%20Queries%20%7C%20%25%20Invalid%20%7C%0A%20%20%20%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%0A%20%20%20%20%7C%20**Reasoning%20ON**%20%7C%20%7Btotal_re%7D%20%7C%20%7Bvalid_re%7D%20%7C%20%7Binvalid_re%7D%20%7C%20**%7Bpct_invalid_re%3A.2f%7D%25**%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_re_sample%2C%20mo)%3A%0A%20%20%20%20%23%20Sample%20invalid%20queries%0A%20%20%20%20%23%20Filter%20only%20rows%20with%20is_valid%3DFalse%0A%20%20%20%20_invalid_on_df%20%3D%20df_re_sample%5Bdf_re_sample%5B'is_valid'%5D%20%3D%3D%20False%5D%0A%20%20%20%20_invalid_on%20%3D%20_invalid_on_df%5B%5B'question'%2C%20'query_text'%2C%20'validation_error'%5D%5D.head(10)%0A%0A%20%20%20%20_display%20%3D%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%23%20Sample%20Invalid%20Queries%3A%20Reasoning%20ON%22)%2C%0A%20%20%20%20%20%20%20%20mo.ui.table(_invalid_on)%20if%20not%20_invalid_on.empty%20else%20mo.md(%22_No%20invalid%20queries%20found._%22)%0A%20%20%20%20%5D)%0A%20%20%20%20_display%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Any%2C%20Dict%2C%20List%2C%20ast%2C%20df_re_sample%2C%20re)%3A%0A%20%20%20%20def%20_clean_error(error_str%3A%20str)%20-%3E%20str%3A%0A%20%20%20%20%20%20%20%20%22%22%22Parse%20stringified%20list%20of%20errors%20and%20aggressively%20group%20by%20core%20category.%22%22%22%0A%20%20%20%20%20%20%20%20if%20not%20error_str%20or%20error_str%20%3D%3D%20%22Empty%20or%20None%20query%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20error_str%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Handle%20CyVer's%20string%20representation%20of%20list%20of%20dicts%0A%20%20%20%20%20%20%20%20%20%20%20%20_data%3A%20List%5BDict%5Bstr%2C%20Any%5D%5D%20%3D%20ast.literal_eval(error_str)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20not%20_data%20or%20not%20isinstance(_data%2C%20list)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20error_str%0A%20%20%20%20%20%20%20%20%20%20%20%20_desc%3A%20str%20%3D%20_data%5B0%5D.get('description'%2C%20'')%0A%20%20%20%20%20%20%20%20%20%20%20%20_desc_lower%3A%20str%20%3D%20_desc.lower()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Broad%20category%20matching%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22invalid%20input%22%20in%20_desc_lower%20or%20%22extraneous%20input%22%20in%20_desc_lower%20or%20%22mismatched%20input%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20Invalid%20or%20unexpected%20input%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22unknown%20function%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20Unknown%20function%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22variable%22%20in%20_desc_lower%20and%20%22not%20defined%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20Variable%20not%20defined%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22type%20mismatch%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20Type%20mismatch%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22return%20can%20only%20be%20used%20at%20the%20end%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20RETURN%20must%20be%20at%20query%20end%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22query%20cannot%20conclude%20with%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20Query%20cannot%20conclude%20with%20clause%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22all%20sub%20queries%20in%20an%20union%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20UNION%20return%20columns%20mismatch%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22missing%22%20in%20_desc_lower%20and%20%22expected%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20Missing%20expected%20token%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Fallback%3A%20remove%20anything%20in%20double%20quotes%20(usually%20query%20extracts)%2C%20then%20take%20text%20before%20colon%0A%20%20%20%20%20%20%20%20%20%20%20%20_clean%3A%20str%20%3D%20re.sub(r'%5C(line%20%5Cd%2B%2C%20column%20%5Cd%2B%20%5C(offset%3A%20%5Cd%2B%5C)%5C)'%2C%20''%2C%20_desc)%0A%20%20%20%20%20%20%20%20%20%20%20%20_clean%20%3D%20re.sub(r'%22.*%3F%22'%2C%20''%2C%20_clean).strip()%0A%20%20%20%20%20%20%20%20%20%20%20%20_clean%20%3D%20_clean.split('%3A')%5B0%5D.strip().replace('%5Cn'%2C%20'%20')%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20_clean%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20_clean%5B0%5D.upper()%20%2B%20_clean%5B1%3A%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Unknown%20Error%20Category%22%0A%0A%20%20%20%20%20%20%20%20except%20(ValueError%2C%20SyntaxError%2C%20Exception)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20error_str%0A%0A%20%20%20%20%23%20Process%20Reasoning%20ON%20errors%0A%20%20%20%20_err_re%20%3D%20df_re_sample%5Bdf_re_sample%5B'is_valid'%5D%20%3D%3D%20False%5D%5B'validation_error'%5D.apply(_clean_error)%0A%0A%20%20%20%20%23%20Global%20ranking%0A%20%20%20%20err_ranking%20%3D%20_err_re.value_counts().head(15)%0A%20%20%20%20return%20(err_ranking%2C)%0A%0A%0A%40app.cell%0Adef%20_(err_ranking%2C%20mo%2C%20plt)%3A%0A%20%20%20%20%23%20Ranking%20Chart%20of%20Common%20Syntax%20Errors%0A%20%20%20%20if%20err_ranking.empty%3A%0A%20%20%20%20%20%20%20%20_fig%20%3D%20mo.md(%22_No%20syntax%20errors%20found%20in%20the%20sample%20subsets._%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(14%2C%208))%0A%0A%20%20%20%20%20%20%20%20%23%20Truncate%20long%20error%20descriptions%20so%20they%20fit%20in%20the%20figure%20margins%0A%20%20%20%20%20%20%20%20_safe_index%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(str(lbl)%5B%3A75%5D%20%2B%20'...')%20if%20len(str(lbl))%20%3E%2075%20else%20str(lbl)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20lbl%20in%20err_ranking.index%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20_plot_series%20%3D%20err_ranking.copy()%0A%20%20%20%20%20%20%20%20_plot_series.index%20%3D%20_safe_index%0A%0A%20%20%20%20%20%20%20%20%23%20Sort%20so%20most%20frequent%20is%20at%20the%20top%0A%20%20%20%20%20%20%20%20_plot_series.iloc%5B%3A%3A-1%5D.plot(kind%3D'barh'%2C%20ax%3D_ax%2C%20color%3D'salmon'%2C%20alpha%3D0.9%2C%20edgecolor%3D'darkred')%0A%0A%20%20%20%20%20%20%20%20_ax.set_title(%22Most%20Common%20Cypher%20Syntax%20Errors%20(Reasoning%20ON)%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22Frequency%20(Sample%20n%3D200)%22)%0A%20%20%20%20%20%20%20%20_ax.set_ylabel(%22Error%20Description%20(Cleaned)%22)%0A%0A%20%20%20%20%20%20%20%20%23%20Add%20labels%20to%20the%20end%20of%20bars%20for%20clarity%0A%20%20%20%20%20%20%20%20for%20i%2C%20v%20in%20enumerate(_plot_series.iloc%5B%3A%3A-1%5D)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_ax.text(v%20%2B%200.1%2C%20i%2C%20str(int(v))%2C%20color%3D'darkred'%2C%20va%3D'center'%2C%20fontweight%3D'bold')%0A%0A%20%20%20%20%20%20%20%20_ax.grid(axis%3D'x'%2C%20linestyle%3D'--'%2C%20alpha%3D0.3)%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(invalid_re%3A%20int%2C%20plt%2C%20valid_re%3A%20int)%3A%0A%20%20%20%20%23%20Pie%20Chart%3A%20Valid%20vs%20Invalid%20(Reasoning%20ON)%0A%20%20%20%20_labels%20%3D%20%5B'Valid'%2C%20'Invalid'%5D%0A%20%20%20%20_sizes%20%3D%20%5Bvalid_re%2C%20invalid_re%5D%0A%20%20%20%20_colors%20%3D%20%5B'teal'%2C%20'crimson'%5D%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%208))%0A%20%20%20%20_ax.pie(_sizes%2C%20labels%3D_labels%2C%20autopct%3D'%251.1f%25%25'%2C%20startangle%3D140%2C%20colors%3D_colors)%0A%20%20%20%20_ax.set_title('Cypher%20Query%20Syntax%20Validation%20(Reasoning%20ON)')%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
d26778ee4cedd8f96db33029a14ad076