mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +01:00
cities path
This commit is contained in:
90
clitests/cities.psil
Normal file
90
clitests/cities.psil
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
(define (equal? a b)
|
||||||
|
(if (nil? a) (if (nil? b) 1 0)
|
||||||
|
(if (atom a)
|
||||||
|
(if (atom b) (= a b) 0)
|
||||||
|
(if (atom b) 0 (if (equal? (car a) (car b)) (equal? (cdr a) (cdr b)) 0))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define (empty? l)
|
||||||
|
(equal? l (nil))
|
||||||
|
)
|
||||||
|
|
||||||
|
(define (not a)
|
||||||
|
(if a 0 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
(not 2)
|
||||||
|
(not 1)
|
||||||
|
(not 0)
|
||||||
|
|
||||||
|
|
||||||
|
(define (lhas list what)
|
||||||
|
(if (empty? list) 0
|
||||||
|
(if (equal? (car list) what) 1 (lhas (cdr list) what))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define (onehas list l)
|
||||||
|
(if (empty? list) 0
|
||||||
|
(if (l (car list)) 1 (onehas (cdr list) l))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define (appfront list what)
|
||||||
|
(cons what list)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define (pathslist acc paths from)
|
||||||
|
(if (empty? paths)
|
||||||
|
acc
|
||||||
|
(if (equal? (car (car paths)) from)
|
||||||
|
(pathslist (appfront acc (car(cdr (car paths)))) (cdr paths) from)
|
||||||
|
(pathslist acc (cdr paths) from)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(equal? (pathslist () (quote((1 2))) 1) (quote(2)))
|
||||||
|
|
||||||
|
|
||||||
|
(define (filter p l)
|
||||||
|
(if (empty? l) (nil)
|
||||||
|
(if (p (car l))
|
||||||
|
(cons (car l) (filter p (cdr l)) )
|
||||||
|
(filter p (cdr l))
|
||||||
|
)
|
||||||
|
))
|
||||||
|
|
||||||
|
(filter (lambda (x) (if (> x 0) 1 0 )) (quote(-1 2 0 3 -3 1)))
|
||||||
|
(equal? (filter (lambda (x) (if (> (car x) 0) (if (> (car(cdr x)) 0) 1 0) 0 )) (quote((-1 2) (0 3) (-3 1) (1 1)))) (quote((1 1))))
|
||||||
|
|
||||||
|
(define (cities-path-impl seen paths from to)
|
||||||
|
(if (equal? from to)
|
||||||
|
1
|
||||||
|
(onehas
|
||||||
|
(filter (lambda (w) (not (lhas (appfront seen from) w))) (pathslist (nil) paths from))
|
||||||
|
(lambda (f) (cities-path-impl (appfront seen from) paths f to))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define (cities-path? paths from to)
|
||||||
|
(cities-path-impl (nil) paths from to)
|
||||||
|
)
|
||||||
|
|
||||||
|
(cities-path? (nil) 1 2)
|
||||||
|
(cities-path? (nil) 2 2)
|
||||||
|
(cities-path? (quote((1 2))) 1 2)
|
||||||
|
(cities-path? (quote((1 2))) 1 3)
|
||||||
|
(cities-path? (quote((1 2))) 2 1)
|
||||||
|
(cities-path? (quote((2 1))) 1 2)
|
||||||
|
(cities-path? (quote((1 2) (2 1))) 1 2)
|
||||||
|
(cities-path? (quote((1 2) (2 1))) 2 1)
|
||||||
|
(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 1 2)
|
||||||
|
(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 1 3)
|
||||||
|
(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 1 4)
|
||||||
|
(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 2 3)
|
||||||
|
(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 2 4)
|
||||||
|
(cities-path? (quote((4 2) (3 4) (2 3) (1 2))) 3 2)
|
||||||
20
clitests/cities.psil.ex
Normal file
20
clitests/cities.psil.ex
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(2 3 1)
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
@@ -26,6 +26,8 @@ public:
|
|||||||
// 3 - debug
|
// 3 - debug
|
||||||
// 4 - trace
|
// 4 - trace
|
||||||
static void set_level(const std::string &tag, int level);
|
static void set_level(const std::string &tag, int level);
|
||||||
|
static int get_level(const std::string &tag);
|
||||||
|
static bool en_level(const std::string &tag, int level);
|
||||||
|
|
||||||
static void set_out(std::ostream &out);
|
static void set_out(std::ostream &out);
|
||||||
static void set_out_err(std::ostream &out_err);
|
static void set_out_err(std::ostream &out_err);
|
||||||
|
|||||||
@@ -14,29 +14,23 @@ Logger &Logger::get() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Logger::log(const std::string &tag, const std::string &what, int level) {
|
void Logger::log(const std::string &tag, const std::string &what, int level) {
|
||||||
std::shared_lock l(get()._mutex);
|
if (!en_level(tag, level)) return;
|
||||||
int en_level = Options::get_int("default_log_level");
|
{
|
||||||
if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag);
|
std::shared_lock l(get()._mutex);
|
||||||
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
std::stringstream out;
|
||||||
|
out << std::setprecision(4) << std::fixed << "["
|
||||||
|
<< static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(now - get()._start_time).count()) / 1000.0 << "s]"
|
||||||
|
<< "[" << tag << "][" << get()._level_names.at(level) << "] " << what << '\n';
|
||||||
|
|
||||||
if (en_level < level) return;
|
if (level == 1) get()._out_err.get() << out.str();
|
||||||
|
else
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
get()._out.get() << out.str();
|
||||||
std::stringstream out;
|
}
|
||||||
out << std::setprecision(4) << std::fixed << "["
|
|
||||||
<< static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(now - get()._start_time).count()) / 1000.0 << "s]"
|
|
||||||
<< "[" << tag << "][" << get()._level_names.at(level) << "] " << what << '\n';
|
|
||||||
|
|
||||||
if (level == 1) get()._out_err.get() << out.str();
|
|
||||||
else
|
|
||||||
get()._out.get() << out.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::log(const std::string &tag, const std::function<void(std::ostream &)> &fn, int level) {
|
void Logger::log(const std::string &tag, const std::function<void(std::ostream &)> &fn, int level) {
|
||||||
std::shared_lock l(get()._mutex);
|
if (!en_level(tag, level)) return;
|
||||||
int en_level = Options::get_int("default_log_level");
|
|
||||||
if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag);
|
|
||||||
|
|
||||||
if (en_level < level) return;
|
|
||||||
|
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
fn(out);
|
fn(out);
|
||||||
@@ -59,3 +53,14 @@ void Logger::reset() {
|
|||||||
std::lock_guard l(get()._mutex);
|
std::lock_guard l(get()._mutex);
|
||||||
get()._levels = {};
|
get()._levels = {};
|
||||||
}
|
}
|
||||||
|
int Logger::get_level(const std::string &tag) {
|
||||||
|
std::shared_lock l(get()._mutex);
|
||||||
|
int en_level = Options::get_int("default_log_level");
|
||||||
|
if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag);
|
||||||
|
return en_level;
|
||||||
|
}
|
||||||
|
bool Logger::en_level(const std::string &tag, int level) {
|
||||||
|
int en_level = get_level(tag);
|
||||||
|
if (en_level < level) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ private:
|
|||||||
Handle _globals_vals = Handle::cons(nullptr, nullptr);
|
Handle _globals_vals = Handle::cons(nullptr, nullptr);
|
||||||
std::vector<std::pair<Handle, std::string>> _globals_names_map;
|
std::vector<std::pair<Handle, std::string>> _globals_names_map;
|
||||||
size_t _cur_global = 0;
|
size_t _cur_global = 0;
|
||||||
|
size_t _cur_call_level = 0;
|
||||||
Handle _s = Handle::cons(nullptr, nullptr);
|
Handle _s = Handle::cons(nullptr, nullptr);
|
||||||
Handle _e = Handle::cons(_globals_vals, nullptr);
|
Handle _e = Handle::cons(_globals_vals, nullptr);
|
||||||
Handle _c = Handle::cons(nullptr, nullptr);
|
Handle _c = Handle::cons(nullptr, nullptr);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -86,6 +87,15 @@ void VM::step() {
|
|||||||
_d.push(_e);
|
_d.push(_e);
|
||||||
_d.push(_c);
|
_d.push(_c);
|
||||||
|
|
||||||
|
std::optional<std::string> name;
|
||||||
|
if (Logger::en_level("VM", Logger::DEBUG)) {
|
||||||
|
name = "unknown";
|
||||||
|
for (const auto &p: _globals_names_map) {
|
||||||
|
if (p.first == closureH) name = p.second;
|
||||||
|
}
|
||||||
|
_d.push(Handle(*name));
|
||||||
|
}
|
||||||
|
|
||||||
_s = Handle::cons(nullptr, nullptr);
|
_s = Handle::cons(nullptr, nullptr);
|
||||||
_c = closureH.car();
|
_c = closureH.car();
|
||||||
_e = closureH.cdr();
|
_e = closureH.cdr();
|
||||||
@@ -93,17 +103,21 @@ void VM::step() {
|
|||||||
Logger::log(
|
Logger::log(
|
||||||
"VM",
|
"VM",
|
||||||
[&](std::ostream &out) {
|
[&](std::ostream &out) {
|
||||||
out << "Applying ";
|
out << _cur_call_level;
|
||||||
for (const auto &p: _globals_names_map) {
|
for (int i = 0; i < _cur_call_level; i++) out << " ";
|
||||||
if (p.first == closureH) out << p.second;
|
out << " Applying " << *name;
|
||||||
}
|
|
||||||
out << " with args " << argsH;
|
out << " with args " << argsH;
|
||||||
},
|
},
|
||||||
Logger::DEBUG);
|
Logger::DEBUG);
|
||||||
|
|
||||||
|
_cur_call_level++;
|
||||||
_e.push(argsH);
|
_e.push(argsH);
|
||||||
} else if (poppedCmd == RET) {
|
} else if (poppedCmd == RET) {
|
||||||
|
_cur_call_level--;
|
||||||
|
|
||||||
|
Handle n;
|
||||||
|
if (Logger::en_level("VM", Logger::DEBUG)) n = _d.pop();
|
||||||
|
|
||||||
Handle c = _d.pop();
|
Handle c = _d.pop();
|
||||||
Handle e = _d.pop();
|
Handle e = _d.pop();
|
||||||
Handle s = _d.pop();
|
Handle s = _d.pop();
|
||||||
@@ -114,6 +128,19 @@ void VM::step() {
|
|||||||
_e = e;
|
_e = e;
|
||||||
_s = s;
|
_s = s;
|
||||||
|
|
||||||
|
Logger::log(
|
||||||
|
"VM",
|
||||||
|
[&](std::ostream &out) {
|
||||||
|
out << _cur_call_level;
|
||||||
|
for (int i = 0; i < _cur_call_level; i++) out << " ";
|
||||||
|
out << " Returning from " << n << " ";
|
||||||
|
bool cons = !ret.atom();
|
||||||
|
if (cons) out << "(";
|
||||||
|
out << ret;
|
||||||
|
if (cons) out << ")";
|
||||||
|
},
|
||||||
|
Logger::DEBUG);
|
||||||
|
|
||||||
_s.push(ret);
|
_s.push(ret);
|
||||||
} else if (poppedCmd == DUM) {
|
} else if (poppedCmd == DUM) {
|
||||||
_e.push(nullptr);
|
_e.push(nullptr);
|
||||||
@@ -127,6 +154,8 @@ void VM::step() {
|
|||||||
_d.push(origE);
|
_d.push(origE);
|
||||||
_d.push(_c);
|
_d.push(_c);
|
||||||
|
|
||||||
|
if (Logger::en_level("VM", Logger::DEBUG)) _d.push(Handle("rap"));
|
||||||
|
|
||||||
_s = Handle::cons(nullptr, nullptr);
|
_s = Handle::cons(nullptr, nullptr);
|
||||||
_c = closureH.car();
|
_c = closureH.car();
|
||||||
_e = closureH.cdr();
|
_e = closureH.cdr();
|
||||||
@@ -134,6 +163,8 @@ void VM::step() {
|
|||||||
Handle fnEnv = closureH.cdr();
|
Handle fnEnv = closureH.cdr();
|
||||||
assert(_e == fnEnv);
|
assert(_e == fnEnv);
|
||||||
|
|
||||||
|
_cur_call_level++;
|
||||||
|
|
||||||
_e.push(argsH);
|
_e.push(argsH);
|
||||||
fnEnv.setcar(argsH);
|
fnEnv.setcar(argsH);
|
||||||
} else if (poppedCmd == STOP) {
|
} else if (poppedCmd == STOP) {
|
||||||
|
|||||||
Reference in New Issue
Block a user