User:Ledrug/bits: Difference between revisions

no edit summary
mNo edit summary
No edit summary
Line 1:
<lang c>#include <ucontext.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
 
struct hist_t {
ucontext_t caller, callee;
void **in, *out;
int first;
struct hist_t *prev;
} *hist;
 
void backtrack() {
if (!hist) {
puts("backtracking exhausted");
abort();
}
setcontext(&hist->callee);
}
 
ucontext_t* hpush()
{
struct hist_t *h = malloc(sizeof(*h));
h->in = 0;
h->out = 0;
h->prev = hist;
hist = h;
return &hist->caller;
}
 
void hpop() {
struct hist_t *s = hist;
hist = hist->prev;
 
if (s->in) free(s->in);
free(s->callee.uc_stack.ss_sp);
free(s);
 
backtrack();
}
 
void yield(void *p)
{
hist->out = p;
swapcontext(&hist->callee, &hist->caller);
}
 
void hinit(void **in, void (*func)())
{
if (!hist->in) {
hist->in = in;
getcontext(&hist->callee);
hist->callee.uc_stack.ss_sp = malloc(4096);
hist->callee.uc_stack.ss_size = 4096;
hist->callee.uc_link = &hist->caller;
makecontext(&hist->callee, func, 0);
setcontext(&hist->callee);
}
}
 
#define amb (getcontext(hpush())+_amb)
void *_amb(int n, ...)
{
void iter() {
int i;
for (i = 0; hist->in[i]; i++)
yield(hist->in[i]);
hpop();
}
 
int i;
va_list ap;
void **buf = calloc((1 + n), sizeof(buf[0]));
 
va_start(ap, n);
for (i = 0; i < n; i++)
buf[i] = va_arg(ap, void*);
va_end(ap);
 
hinit(buf, iter);
return hist->out;
}
 
int main(void)
{
int join(char *a, char *b) {
return a[strlen(a) - 1] == b[0];
}
 
char *a = amb(3, "the", "that", "a"),
*b = amb(3, "frog", "elephant", "thing"),
*c = amb(3, "walked", "treaded", "grows"),
*d = amb(3, "slowly", "quickly", "deathly");
 
if (join(a, b) && join(b, c) && join(c, d))
printf("%s %s %s %s\n", a, b, c, d);
else
amb(0);
 
// should put a backtrack barrier here
 
int s[] = {1, 2, 3, 4};
 
int x = *(int*)amb(4, s, s+1, s+2, s+3);
int y = *(int*)amb(3, s, s+1, s+2);
int z = *(int*)amb(3, s, s+1, s+2);
 
//if (! (x > y && y < z && z < x && (x > 4))) // make "thing grows slowly"
if (! (x > y && y < z && z < x && !(x & 1)))
backtrack();
 
printf("%d %d %d\n", x, y, z);
 
return 0;
}</lang>
 
<lang lisp>(defmacro or= (x y) `(setf ,x (logior ,x ,y)))
(defmacro and= (x y) `(setf ,x (logand ,x ,y)))
Anonymous user