From Undecidability.FOL.Arithmetics Require Import FA Signature.
From Undecidability.FOL Require Import PA.
Require Import Lia List Vector.
Import Vector.VectorNotations.

Local Set Implicit Arguments.
Local Unset Strict Implicit.


Section StdModel.

  Definition interp_nat : interp .
  Proof.
    split.
    - destruct f; intros v.
      + exact 0.
      + exact (S (Vector.hd v) ).
      + exact (Vector.hd v + Vector.hd (Vector.tl v) ).
      + exact (Vector.hd v * Vector.hd (Vector.tl v) ).
    - destruct P. intros v.
      exact (Vector.hd v = Vector.hd (Vector.tl v) ).
  Defined.


  Fact nat_extensional : extensional interp_nat.
  Proof.
    now intros x y.
  Qed.


  Lemma nat_is_FA_model : rho phi, List.In FAeq sat interp_nat .
  Proof.
    intros . intros H.
    repeat (destruct H as [ | H]; auto).
    all: cbn; try congruence. inversion H.
  Qed.


  Lemma nat_is_Q_model : rho phi, List.In Qeq sat interp_nat .
  Proof.
    intros . intros H.
    repeat (destruct H as [ | H]; auto).
    all: cbn; try congruence.
    2: inversion H.
    induction d. now left.
    right. destruct IHd.
    exists 0. congruence.
    exists d. reflexivity.
  Qed.


  Fact nat_eval_num (sigma : env ) n : @eval _ _ _ interp_nat (μ n) = n.
  Proof.
    induction n.
    - reflexivity.
    - cbn. now rewrite IHn.
  Qed.


  Fact nat_induction phi : rho, sat interp_nat (ax_induction ).
  Proof.
    intros IH d. induction d; cbn in *.
    rewrite sat_single in . apply .
    apply IH in IHd. rewrite sat_comp in IHd.
    revert IHd. apply sat_ext. intros []; reflexivity.
  Qed.


  Fact nat_is_PAeq_model : ax rho, PAeq ax sat interp_nat ax.
  Proof.
    intros [].
    now apply nat_is_FA_model.
    all: cbn; try congruence.
    apply nat_induction.
 Qed.


  Fact nat_is_PA_model : ax rho, PA ax sat interp_nat ax.
  Proof.
    intros [].
    repeat (destruct H as [ | H]; auto).
    all: cbn; try congruence. inversion H.
    apply nat_induction.
  Qed.


End StdModel.