loa

Virtual machine for the Logic of Assumptions
Log | Files | Refs

commit 73b5c1b66e955db70e1c34db37636ab534c94fb6
parent 4427db8f18e506b5b1ab4c23964b3f0518850a98
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date:   Sat,  6 Jan 2024 18:16:43 -0300

Add goals and tactics for building terms

Diffstat:
Acoding/build.sh | 3+++
Acoding/formating.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acoding/formating.h | 10++++++++++
Mcoding/vm.c | 208+++++++++++++++++++++++++++++++------------------------------------------------
Acoding/vm.h | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acoding/vm.txt | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 355 insertions(+), 126 deletions(-)

diff --git a/coding/build.sh b/coding/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cc -o vm vm.c formating.c && ./vm diff --git a/coding/formating.c b/coding/formating.c @@ -0,0 +1,105 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "formating.h" + +void print_term(FILE *f, struct state *st, struct term t); + +void +print_ref(FILE *f, struct state *st, address ref) +{ + struct ref cur = st->refs[ref]; + if (cur.resolved) { + switch (cur.type) { + case TERM: + print_term(f, st, resolve(st, term, cur.addr)); + break; + case SYMBOL: + break; + case JUDGMENT_FORM: + break; + case ASSUMPTION: + break; + } + } else { + char v = type_variable(cur.type); + fprintf(f, "%c%ld", v, ref); + } +} + +void +print_symbol(FILE *f, struct state *st, struct symbol s) +{ + (void)st; + fprintf(f, "%s", s.name); +} + +void +print_term(FILE *f, struct state *st, struct term t) +{ + if (t.nargs == 0) { + print_symbol(f, st, resolve(st, symbol, t.head)); + } else { + fputc('(', f); + print_symbol(f, st, resolve(st, symbol, t.head)); + for (size_t i = 0; i < t.nargs; i++) { + fputc(' ', f); + print_ref(f, st, t.subterms + i); + } + fputc(')', f); + } +} + +void +print_goal(FILE *f, struct state *st, struct goal *g) +{ + if (!g) { + fprintf(f, "Nothing to do."); + } else { + struct ref r = st->refs[g->target]; + fprintf(f, "Build %c at %ld", type_variable(r.type), g->target); + if (g->state == CLOSED) { + fprintf(f, " [CLOSED]"); + } + } +} + +void +print_state(FILE *f, struct state *st) +{ + size_t i; + + fprintf(f, "----------\n"); + + fprintf(f, "SYMBOLS\n"); + for (i = 0; i < st->nsymbols; i++) { + fprintf(f, "%ld: ", i); + print_symbol(f, st, resolve(st, symbol, i)); + fputc('\n', f); + } + + fprintf(f, "\nTERMS\n"); + for (i = 0; i < st->nterms; i++) { + fprintf(f, "%ld: ", i); + print_term(f, st, st->terms[i]); + fputc('\n', f); + } + + fprintf(f, "\nREFS (%ld/%ld)\n", st->nrefs, st->crefs); + for (i = 0; i < st->nrefs; i++) { + fprintf(f, "%ld: ", i); + fprintf(f, "%c -> ", type_variable(st->refs[i].type)); + if (st->refs[i].resolved) + fprintf(f, "%ld", st->refs[i].addr); + else + fputs("?", f); + fputc('\n', f); + } + + fprintf(f, "\nGOALS\n"); + for (struct goal *cur = st->focus; cur; cur = cur->next) { + print_goal(f, st, cur); + fputc('\n', f); + } +} + diff --git a/coding/formating.h b/coding/formating.h @@ -0,0 +1,10 @@ +#include "vm.h" + +#define type_variable(t) ("SJAT"[t]) + +void print_term(FILE *f, struct state *st, struct term t); +void print_ref(FILE *f, struct state *st, address ref); +void print_symbol(FILE *f, struct state *st, struct symbol s); +void print_term(FILE *f, struct state *st, struct term t); +void print_state(FILE *f, struct state *st); +void print_goal(FILE *f, struct state *st, struct goal *g); diff --git a/coding/vm.c b/coding/vm.c @@ -2,76 +2,21 @@ #include <stdlib.h> #include <assert.h> -typedef size_t address; - -typedef enum { - SYMBOL, - JUDGMENT_FORM, - ASSUMPTION, - TERM -} ref_t; - -char -type_variable(ref_t t) -{ - char *cs = "SJAT"; - return cs[t]; -} - -struct ref { - ref_t type; - address addr; - int resolved; -}; - -struct symbol { - char *name; -}; - -struct term { - address head; - size_t nargs; - address subterms; -}; - -struct state { - - size_t nrefs; - size_t crefs; - struct ref *refs; - - size_t nsymbols; - size_t csymbols; - struct symbol *symbols; - - size_t nterms; - size_t cterms; - struct term *terms; - -}; +#include "vm.h" +#include "formating.h" struct state new_state(void) { - struct state s = { - .nrefs = 0, - .crefs = 1, - .refs = malloc(sizeof(struct ref)), - .nsymbols = 0, - .csymbols = 1, - .symbols = malloc(sizeof(struct symbol)), - .nterms = 0, - .cterms = 1, - .terms = malloc(sizeof(struct term)) - }; + struct state s; + init(s, ref); + init(s, symbol); + init(s, term); + s.focus = NULL; + s.cursor = NULL; return s; } -#define cap(st, t) st -> c ## t ## s -#define num(st, t) st -> n ## t ## s -#define vec(st, t) st -> t ## s -#define push(s, t, x) (((cap(s,t) == num(s,t)) ? (vec(s,t) = realloc(vec(s,t), (cap(s,t) *= 2)*sizeof(struct t))) : NULL), (vec(s,t)[num(s,t)++] = x), (num(s,t)-1)) - address allocate_refs(struct state *st, size_t n, ref_t type) { @@ -111,8 +56,6 @@ create_symbol(struct state *st, char *name) return push(st, symbol, sym); } -#define resolve(state, type, addr) state -> type ## s [addr] - void assign(struct state *st, address ref, address dest) { @@ -120,95 +63,108 @@ assign(struct state *st, address ref, address dest) st->refs[ref].resolved = 1; } -void print_term(FILE *f, struct state *st, struct term t); - void -print_ref(FILE *f, struct state *st, address ref) +add_subgoal(struct state *st, address target) { - struct ref cur = st->refs[ref]; - if (cur.resolved) { - switch (cur.type) { - case TERM: - print_term(f, st, resolve(st, term, cur.addr)); - break; - case SYMBOL: - break; - case JUDGMENT_FORM: - break; - case ASSUMPTION: - break; - } + struct goal *g = malloc(sizeof(struct goal)); + + if (!st->cursor) { + // Creating first subgoal + g->next = st->focus; + st->focus = g; + st->cursor = g; } else { - char v = type_variable(cur.type); - fprintf(f, "%c%ld", v, ref); + // There are already subgoals + g->next = st->cursor->next; + st->cursor->next = g; + st->cursor = g; } + g->target = target; } void -print_symbol(FILE *f, struct state *st, struct symbol s) +commit(struct state *st) { - (void)st; - fprintf(f, "%s", s.name); + if (st->cursor) { + st->cursor = NULL; + } else { + st->focus->state = CLOSED; + } } void -print_term(FILE *f, struct state *st, struct term t) +solve(struct state *st, address dest) { - if (t.nargs == 0) { - print_symbol(f, st, resolve(st, symbol, t.head)); - } else { - fputc('(', f); - print_symbol(f, st, resolve(st, symbol, t.head)); - for (size_t i = 0; i < t.nargs; i++) { - fputc(' ', f); - print_ref(f, st, t.subterms + i); - } - fputc(')', f); - } + assert(st->focus); + st->focus->state = CLOSED; + assign(st, st->focus->target, dest); } void -print_state(FILE *f, struct state *st) +tactic_term(struct state *st, address head, size_t arity) { - size_t i; + assert(!st->focus || resolve(st, ref, st->focus->target).type == TERM); + + address sol = create_term(st, head, arity); + struct term t = resolve(st, term, sol); - fprintf(f, "----------\n"); + if (st->focus) solve(st, sol); - fprintf(f, "SYMBOLS\n"); - for (i = 0; i < st->nsymbols; i++) { - fprintf(f, "%ld: ", i); - print_symbol(f, st, resolve(st, symbol, i)); - fputc('\n', f); + for (size_t i = 0; i < arity; i++) { + add_subgoal(st, t.subterms + i); } - fprintf(f, "\nTERMS\n"); - for (i = 0; i < st->nterms; i++) { - fprintf(f, "%ld: ", i); - print_term(f, st, st->terms[i]); - fputc('\n', f); + commit(st); +} + +void +step(struct state *st) +{ + struct goal *g; + + assert(!st->cursor); + + if (!st->focus) { + return; // read in next input } - fprintf(f, "\nREFS (%ld/%ld)\n", st->nrefs, st->crefs); - for (i = 0; i < st->nrefs; i++) { - fprintf(f, "%ld: ", i); - fprintf(f, "%c -> ", type_variable(st->refs[i].type)); - if (st->refs[i].resolved) - fprintf(f, "%ld", st->refs[i].addr); - else - fputs("?\n", f); - fputc('\n', f); + switch (st->focus->state) { + case OPEN: + // read in next input + break; + + case CLOSED: + // verify it, maybe + g = st->focus; + st->focus = st->focus->next; + free(g); + break; } } -int main(void) { +int +main(void) { struct state state = new_state(); address cur, cur2; - cur = create_symbol(&state, "first"); - cur2 = create_symbol(&state, "second"); - cur = create_term(&state, cur, 1); - cur2 = create_term(&state, cur2, 0); - assign(&state, 0, 1); + cur = create_symbol(&state, "x"); + + tactic_term(&state, cur, 2); + step(&state); + + tactic_term(&state, cur, 2); + step(&state); + + tactic_term(&state, cur, 0); + step(&state); + + tactic_term(&state, cur, 0); + step(&state); + step(&state); + + tactic_term(&state, cur, 0); + step(&state); + print_state(stdout, &state); return 0; } diff --git a/coding/vm.h b/coding/vm.h @@ -0,0 +1,85 @@ +#ifndef VM_H +#define VM_H +typedef size_t address; + +typedef enum { + SYMBOL, + JUDGMENT_FORM, + ASSUMPTION, + TERM +} ref_t; + +typedef enum { + OPEN, + CLOSED +} goal_s; + +struct ref { + ref_t type; + address addr; + int resolved; +}; + +struct symbol { + char *name; +}; + +struct term { + address head; + size_t nargs; + address subterms; +}; + +struct goal { + goal_s state; + struct goal *next; + address target; +}; + +#define cap(t) c ## t ## s +#define num(t) n ## t ## s +#define vec(t) t ## s + +#define init(s, t) do { \ + s . cap(t) = 1; \ + s . num(t) = 0; \ + s . vec(t) = malloc(sizeof(struct t)); \ + } while(0) + +#define push(s, t, x) ( \ + ( \ + (s -> cap(t) == s -> num(t)) ? \ + (s -> vec(t) = realloc(s -> vec(t), \ + (s -> cap(t) *= 2)*sizeof(struct t))) : \ + NULL \ + ), \ + (s -> vec(t)[s -> num(t)++] = x), \ + (s -> num(t)-1) \ +) + +#define list(t) size_t num(t); size_t cap(t); struct t * vec(t) + +struct state { + struct goal *focus; + struct goal *cursor; + + list(ref); + list(symbol); + list(term); +}; + +struct state new_state(void); + +address allocate_refs(struct state *st, size_t n, ref_t type); + +address create_term(struct state *st, address symbol, size_t nargs); + +address create_symbol(struct state *st, char *name); + +#define resolve(state, type, addr) state -> type ## s [addr] + +void add_subgoal(struct state *st, address target); + +void assign(struct state *st, address ref, address dest); + +#endif diff --git a/coding/vm.txt b/coding/vm.txt @@ -0,0 +1,70 @@ +NEXT STEPS +========== + +- Implement goals for building terms + + +NOTES +===== + +GOALS +----- +Goals specify a thing to build and a destination. + +- NONE None (JUDGMENT, ASSUMPTION) +- JUDG-VAR Give judgment parameter name (SYMBOL) +- JUDG-PRE Construct pressuposition term (TERM) +- ASMP-VAR Give assumption parameter name (SYMBOL) +- ASMP-SUB Construct assumption (ASSUMPTION) +- ASMP-JUG Construct judgment term (TERM) +- ASMP-PRF Prove judgment (PROOF) +- ASMP-ARG Construct proof argument (TERM) + +TACTICS +------- +Tactics take arguments and build things for solving goals. + +- JUG (symbol, arity, subsize) Start a judgment form [construct JUDGMENT] +- ASM (symbol, arity, subsize) Start an assumption [construct ASSUMPTION] +- NAM (symbol) Name a symbol [construct SYMBOL] +- ATM (symbol) Construct an atomic term [construct TERM] +- APP (symbol, arity) Start a complex term [TERM] +- REF (symbol) Reference an assumption [PROOF] + +EFFECTS +------- +Each tactic changes the state of the system and possibly creates more +goals, but also discharges the current one. + +- JUG (symbol name, int arity, int subsize): + - allocate new judgment and set target to point to it + - create `arity` symbol goals pointing to its variables + - create `subsize` term goals pointing to its pressupositions + +- ASM (symbol name, int arity, int subsize): + - allocate new assumption and set target to point to it + - create `arity` symbol goals pointing to its variables + - create `subsize` assumption goals pointing to its subassumptions + - create a term goal pointing to its judgment + - create a proof goal pointing to its judgment + +- NAM (symbol): set target's value to givem symbol + +- ATM (symbol): + - allocate new term with arity 0 + - set term's head to given symbol + - set target to point to term + +- APP (symbol head, int arity): + - allocate new term with arity `arity` + - set term's head to `head` + - create `arity` symbol goals pointing to the term's subterms + +- REF (symbol): + - set target proposition's candidate to given symbol + - create one term goal for each variable in assumption refered to by symbol + - create one proof goal for each subassumption of the assumption refered to by symbol + +RESOLUTION +---------- +When all subgoals of a goal are resolved, extra logic might be needed to verify the resolution of the current goal.