@prefix :     <http://example.org/quad#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix math: <http://www.w3.org/2000/10/swap/math#> .
@prefix log:  <http://www.w3.org/2000/10/swap/log#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .

############################################################
# P3: Prompt → Program → Proof (Answer, Reason, Check)
# Solve ax^2 + bx + c = 0, a ≠ 0
############################################################

# --- Vocabulary ---
:Quadratic  a rdfs:Class .
:RealRoot   a rdfs:Class .
:ComplexRoot a rdfs:Class .
:Check      a rdfs:Class .

# Properties on a quadratic instance:
:a a rdf:Property .
:b a rdf:Property .
:c a rdf:Property .
:answer a rdf:Property .        # links a Q to root nodes (real or complex)
:why a rdf:Property .           # links a Q to a "reason" record
:check a rdf:Property .         # links a Q to check results
:status a rdf:Property .

# Properties used in reasoning/explanation:
:discriminant a rdf:Property .
:denominator a rdf:Property .
:negB a rdf:Property .
:sqrtDiscriminant a rdf:Property .
:value a rdf:Property .
:real a rdf:Property .
:imag a rdf:Property .
:multiplicity a rdf:Property .
:val a rdf:Property .

# Properties used in checks:
:kind a rdf:Property .
:ok a rdf:Property .
:residual a rdf:Property .
:residualRe a rdf:Property .
:residualIm a rdf:Property .

# Global numeric tolerance for plug-back checks
:eps :val 0.000000001 .   # 1e-9

############################################################
# Core math facts shared by all branches
############################################################
{
  ?q a :Quadratic; :a ?a; :b ?b; :c ?c .
  ?a math:notEqualTo 0 .
  (?b 2)          math:exponentiation ?b2 .
  (4 ?a ?c)       math:product        ?fourac .
  (?b2 ?fourac)   math:difference     ?D .             # D = b^2 - 4ac
  (2 ?a)          math:product        ?den .           # 2a
  ?b              math:negation       ?negB .          # -b
}
=>
{
  ?q :why [
      :discriminant ?D ;
      :denominator  ?den ;
      :negB         ?negB
  ] .
} .

############################################################
# Branch 1: Two real roots (D > 0)
############################################################
{
  ?q a :Quadratic; :a ?a; :b ?b; :c ?c .
  ?a math:notEqualTo 0 .
  (?b 2)        math:exponentiation ?b2 .
  (4 ?a ?c)     math:product        ?fourac .
  (?b2 ?fourac) math:difference     ?D .
  ?D math:greaterThan 0 .
  (2 ?a)        math:product        ?den .
  ?b            math:negation       ?negB .
  (?D 0.5)      math:exponentiation ?sqrtD .           # sqrt(D) as D^0.5
  (?negB ?sqrtD) math:sum          ?numPlus .
  (?negB ?sqrtD) math:difference   ?numMinus .
  (?numPlus ?den)  math:quotient   ?x1 .
  (?numMinus ?den) math:quotient   ?x2 .
}
=>
{
  ?q :answer [ a :RealRoot; :value ?x1 ],
             [ a :RealRoot; :value ?x2 ] ;
     :why    [ :sqrtDiscriminant ?sqrtD ] ;
     :status "two-real-roots" .
} .

############################################################
# Branch 2: One real double root (D = 0)
############################################################
{
  ?q a :Quadratic; :a ?a; :b ?b; :c ?c .
  ?a math:notEqualTo 0 .
  (?b 2)        math:exponentiation ?b2 .
  (4 ?a ?c)     math:product        ?fourac .
  (?b2 ?fourac) math:difference     ?D .
  ?D math:equalTo 0 .
  (2 ?a)        math:product        ?den .
  ?b            math:negation       ?negB .
  (?negB ?den)  math:quotient       ?x .
}
=>
{
  ?q :answer [ a :RealRoot; :value ?x; :multiplicity 2 ] ;
     :why    [ :sqrtDiscriminant 0 ] ;
     :status "double-root" .
} .

############################################################
# Branch 3: Complex conjugate roots (D < 0)
#   real = (-b)/(2a), imag = sqrt(-D)/(2a)
############################################################
{
  ?q a :Quadratic; :a ?a; :b ?b; :c ?c .
  ?a math:notEqualTo 0 .
  (?b 2)        math:exponentiation ?b2 .
  (4 ?a ?c)     math:product        ?fourac .
  (?b2 ?fourac) math:difference     ?D .
  ?D math:lessThan 0 .
  (2 ?a)        math:product        ?den .
  ?b            math:negation       ?negB .

  ?D            math:negation       ?Dn .             # -D > 0
  (?Dn 0.5)     math:exponentiation ?sqrtDn .         # sqrt(-D)

  (?negB ?den)  math:quotient       ?re .
  (?sqrtDn ?den) math:quotient      ?im .
  ?im           math:negation       ?imNeg .
}
=>
{
  ?q :answer
      [ a :ComplexRoot; :real ?re; :imag ?im ],
      [ a :ComplexRoot; :real ?re; :imag ?imNeg ] ;
     :why [ :sqrtDiscriminant ?sqrtDn ] ;
     :status "complex-roots" .
} .

############################################################
# Checks – plug back f(x)=ax^2+bx+c≈0
############################################################

# Real roots: |a*x^2 + b*x + c| ≤ eps
{
  ?q a :Quadratic; :a ?a; :b ?b; :c ?c .
  ?q :answer ?r .
  ?r a :RealRoot; :value ?x .
  (?x 2)        math:exponentiation ?x2 .
  (?a ?x2)      math:product        ?ax2 .
  (?b ?x)       math:product        ?bx .
  (?ax2 ?bx ?c) math:sum            ?f .
  ?f            math:absoluteValue  ?abs .
  :eps :val ?eps .
  ?abs          math:notGreaterThan ?eps .
}
=>
{
  ?q :check [
      a :Check ;
      :kind "plug-in/real" ;
      :root ?x ;
      :residual ?abs ;
      :ok true
  ] .
} .

# Complex roots z = u + i*v:
#   z^2 = (u^2 - v^2) + i*(2uv)
#   Re(f) = a*(u^2 - v^2) + b*u + c
#   Im(f) = a*(2uv) + b*v
#   Both |Re(f)| and |Im(f)| ≤ eps
{
  ?q a :Quadratic; :a ?a; :b ?b; :c ?c .
  ?q :answer ?z .
  ?z a :ComplexRoot; :real ?u; :imag ?v .

  (?u 2)          math:exponentiation ?u2 .
  (?v 2)          math:exponentiation ?v2 .
  (?u2 ?v2)       math:difference     ?u2_minus_v2 .
  (2 ?u ?v)       math:product        ?two_uv .

  (?a ?u2_minus_v2) math:product      ?a_u2mV2 .
  (?a ?two_uv)      math:product      ?a_2uv .
  (?b ?u)           math:product      ?b_u .
  (?b ?v)           math:product      ?b_v .

  (?a_u2mV2 ?b_u ?c) math:sum         ?re_f .
  (?a_2uv ?b_v)      math:sum         ?im_f .

  ?re_f            math:absoluteValue ?re_abs .
  ?im_f            math:absoluteValue ?im_abs .
  :eps :val ?eps .
  ?re_abs          math:notGreaterThan ?eps .
  ?im_abs          math:notGreaterThan ?eps .
}
=>
{
  ?q :check [
      a :Check ;
      :kind "plug-in/complex" ;
      :root [ :real ?u; :imag ?v ] ;
      :residualRe ?re_abs ;
      :residualIm ?im_abs ;
      :ok true
  ] .
} .

############################################################
# ----------------------- HARNESS -------------------------
# ≥5 independent quadratics to exercise all branches
############################################################

# H1: Two distinct real roots: x^2 - 3x + 2 = 0 → {1, 2}
:Q1 a :Quadratic; :a 1; :b -3; :c 2 .

# H2: Double root: x^2 + 2x + 1 = 0 → {-1 (mult. 2)}
:Q2 a :Quadratic; :a 1; :b 2; :c 1 .

# H3: Two real roots with negative leading coefficient: -x^2 + 1 = 0 → { -1, 1 }
:Q3 a :Quadratic; :a -1; :b 0; :c 1 .

# H4: Non-integer coefficients: 2x^2 + 10x + 8 = 0 → { -4, -1 }
:Q4 a :Quadratic; :a 2; :b 10; :c 8 .

# H5: No real roots (complex): x^2 + 1 = 0 → { i, -i }
:Q5 a :Quadratic; :a 1; :b 0; :c 1 .

# H6 (extra): Mixed signs: 3x^2 - 12x + 9 = 0 → {1, 3}
:Q6 a :Quadratic; :a 3; :b -12; :c 9 .

