- ...
This commit is contained in:
		
							parent
							
								
									cf8c7a3e21
								
							
						
					
					
						commit
						6e54324d4f
					
				@ -59,38 +59,38 @@ class LogicFunction implements JsonSerializable
 | 
			
		||||
        return join("", $tt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function genTerm(array $vars, int $ftn, int $tn, int $mind, int $maxd, bool $top = true, int $opindex = 1): string
 | 
			
		||||
    {
 | 
			
		||||
        $term = "";
 | 
			
		||||
        $m = max($ftn, random_int(1, $tn));
 | 
			
		||||
        if ((($maxd === 0) || ($m === 1)) && ($ftn === 0)) {
 | 
			
		||||
            $neg = random_int(0, 1) === 1;
 | 
			
		||||
            $var = $vars[array_rand($vars, 1)];
 | 
			
		||||
            $term = ($neg ? "~" : "") . $var;
 | 
			
		||||
        } else {
 | 
			
		||||
            $depth = random_int(0, max(0, $maxd - 1));
 | 
			
		||||
 | 
			
		||||
            $verilog_ops = [" & ", " | "];
 | 
			
		||||
            $verilog_op = $verilog_ops[$opindex];
 | 
			
		||||
            $term = !$top ? "(" : "";
 | 
			
		||||
 | 
			
		||||
            $nextopindex = ($opindex === 0) ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
            for ($i = 0; $i < $m; $i++) {
 | 
			
		||||
                $subterm = self::genTerm($vars, (($mind - 1) > 0) ? $ftn : 0, $tn, $mind - 1, $depth, false, $nextopindex);
 | 
			
		||||
                $term .= $subterm;
 | 
			
		||||
                if ($i < $m - 1) {
 | 
			
		||||
                    $term .= $verilog_op;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $term .= !$top ? ")" : "";
 | 
			
		||||
        }
 | 
			
		||||
        return $term;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function genRandom(array $input_vars, int $min_depth = 2, int $max_depth = 3): LogicFunction
 | 
			
		||||
    {
 | 
			
		||||
        function genTerm(array $vars, int $ftn, int $tn, int $mind, int $maxd, bool $top = true, int $opindex = 1): string
 | 
			
		||||
        {
 | 
			
		||||
            $term = "";
 | 
			
		||||
            $m = max($ftn, random_int(1, $tn));
 | 
			
		||||
            if ((($maxd === 0) || ($m === 1)) && ($ftn === 0)) {
 | 
			
		||||
                $neg = random_int(0, 1) === 1;
 | 
			
		||||
                $var = $vars[array_rand($vars, 1)];
 | 
			
		||||
                $term = ($neg ? "~" : "") . $var;
 | 
			
		||||
            } else {
 | 
			
		||||
                $depth = random_int(0, max(0, $maxd - 1));
 | 
			
		||||
 | 
			
		||||
                $verilog_ops = [" & ", " | "];
 | 
			
		||||
                $verilog_op = $verilog_ops[$opindex];
 | 
			
		||||
                $term = !$top ? "(" : "";
 | 
			
		||||
 | 
			
		||||
                $nextopindex = ($opindex === 0) ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
                for ($i = 0; $i < $m; $i++) {
 | 
			
		||||
                    $subterm = genTerm($vars, (($mind - 1) > 0) ? $ftn : 0, $tn, $mind - 1, $depth, false, $nextopindex);
 | 
			
		||||
                    $term .= $subterm;
 | 
			
		||||
                    if ($i < $m - 1) {
 | 
			
		||||
                        $term .= $verilog_op;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                $term .= !$top ? ")" : "";
 | 
			
		||||
            }
 | 
			
		||||
            return $term;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $term = genTerm($input_vars, count($input_vars), count($input_vars), $min_depth, $max_depth);
 | 
			
		||||
        $term = self::genTerm($input_vars, count($input_vars), count($input_vars), $min_depth, $max_depth);
 | 
			
		||||
        return new LogicFunction($term, $input_vars);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -249,7 +249,8 @@ class LogicFunction implements JsonSerializable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function drawNetwork(string $outvar = "f"): string {
 | 
			
		||||
        return PythonUtils::execPy("draw_logic_network.py", [ $this->getExpression(), $outvar ]);
 | 
			
		||||
        $expr = str_replace(["^"], ["xor"], $this->getExpression());
 | 
			
		||||
        return PythonUtils::execPy("draw_logic_network.py", [ $expr, $outvar ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,11 @@ require_once "LogicFunction.php";
 | 
			
		||||
 | 
			
		||||
class LuaUtils
 | 
			
		||||
{
 | 
			
		||||
    public static function l2pA(array $la): array {
 | 
			
		||||
    public static function l2pA(array|null $la): array {
 | 
			
		||||
        if ($la === null) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $r = [];
 | 
			
		||||
        $i = 0;
 | 
			
		||||
        foreach ($la as $v) {
 | 
			
		||||
@ -13,6 +17,19 @@ class LuaUtils
 | 
			
		||||
        return $r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function p2lA(array|null $pa): array {
 | 
			
		||||
        if ($pa === null) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $r = [];
 | 
			
		||||
        $i = 1;
 | 
			
		||||
        foreach ($pa as $v) {
 | 
			
		||||
            $r[$i++] = $v;
 | 
			
		||||
        }
 | 
			
		||||
        return $r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function registerLuaLibs(LuaSandbox &$sandbox): void {
 | 
			
		||||
        self::registerLogicUtils($sandbox);
 | 
			
		||||
    }
 | 
			
		||||
@ -24,11 +41,11 @@ class LuaUtils
 | 
			
		||||
            "changeRepresentation" => fn() => [ call_user_func(array(LogicUtils::class, "changeRepresentation"), ...func_get_args()) ],
 | 
			
		||||
            "genRandomLogicFunction" => fn($iv, $mind, $maxd) => [ call_user_func(array(LogicFunction::class, "genRandom"), self::l2pA($iv), $mind, $maxd)->getExpression() ],
 | 
			
		||||
            "genRandomLogicFunctionDNF" => fn($iv) => [ call_user_func(array(LogicFunction::class, "genRandomDNF"), self::l2pA($iv))->getExpression() ],
 | 
			
		||||
            "isLogicFunctionValid" => fn($expr) => [ (new LogicFunction($expr))->isValid() ],
 | 
			
		||||
            "isLogicFunctionADNF" => fn($iv, $expr) => [ call_user_func(array(LogicFunction::class, "isCorrectDNF"), self::l2pA($iv), $expr) ],
 | 
			
		||||
            "collectVariablesFromLogicFunction" => fn($expr) => call_user_func(array(LogicFunction::class, "collectVariables"), $expr),
 | 
			
		||||
            "convertLogicFunctionToTruthTable" => fn($expr, $iv) => [ (new LogicFunction($expr, self::l2pA($iv)))->getTruthTable() ],
 | 
			
		||||
            "drawLogicFunction" => fn($expr, $iv, $ov) => [ (new LogicFunction($expr, self::l2pA($iv)))->drawNetwork($ov) ],
 | 
			
		||||
            "isLogicFunctionValid" => fn($expr) => [ (new LogicFunction($expr ?? "0"))->isValid() ],
 | 
			
		||||
            "isLogicFunctionADNF" => fn($iv, $expr) => [ call_user_func(array(LogicFunction::class, "isCorrectDNF"), self::l2pA($iv), $expr ?? "0") ],
 | 
			
		||||
            "collectVariablesFromLogicFunction" => fn($expr) => call_user_func(array(LogicFunction::class, "collectVariables"), $expr ?? ""),
 | 
			
		||||
            "convertLogicFunctionToTruthTable" => fn($expr, $iv) => [ (new LogicFunction($expr ?? "0", self::l2pA($iv)))->getTruthTable() ],
 | 
			
		||||
            "drawLogicFunction" => fn($expr, $iv, $ov) => [ (new LogicFunction($expr ?? "0", self::l2pA($iv)))->drawNetwork($ov) ],
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -18,35 +18,54 @@ class Task implements JsonSerializable
 | 
			
		||||
 | 
			
		||||
    // -------------
 | 
			
		||||
 | 
			
		||||
    protected function addLuaLibraries(): void {
 | 
			
		||||
    protected function addLuaLibraries(): void
 | 
			
		||||
    {
 | 
			
		||||
        // register member methods
 | 
			
		||||
        $method_names = get_class_methods($this);
 | 
			
		||||
        $methods = [];
 | 
			
		||||
        foreach ($method_names as $method_name) {
 | 
			
		||||
            $methods[$method_name] = fn() => [ call_user_func(array(&$this, $method_name), ...func_get_args()) ];
 | 
			
		||||
            $methods[$method_name] = fn() => [call_user_func(array(&$this, $method_name), ...func_get_args())];
 | 
			
		||||
        }
 | 
			
		||||
        $this->lua_sandbox->registerLibrary("task", $methods);
 | 
			
		||||
 | 
			
		||||
        // register generic functionality
 | 
			
		||||
        $this->lua_sandbox->registerLibrary("php", [
 | 
			
		||||
            "print" => function($str) {
 | 
			
		||||
            "print" => function ($str) {
 | 
			
		||||
                printf("%s\n", $str);
 | 
			
		||||
            },
 | 
			
		||||
            "replace" => "str_replace",
 | 
			
		||||
            "replace_field" => function($field, $replacement, $str) {
 | 
			
		||||
                return [ str_replace("{{" . $field . "}}", $replacement, $str) ];
 | 
			
		||||
            }
 | 
			
		||||
            "replace" => function ($search, $replace, $str) {
 | 
			
		||||
                return [str_replace(LuaUtils::l2pA($search), LuaUtils::l2pA($replace), $str)];
 | 
			
		||||
            },
 | 
			
		||||
            "replace_field" => function ($field, $replacement, $str) {
 | 
			
		||||
                return [str_replace("{{" . $field . "}}", $replacement, $str)];
 | 
			
		||||
            },
 | 
			
		||||
            "trim" => function ($str, $chars = " \n\r\t\v\0") {
 | 
			
		||||
                return [trim($str, $chars)];
 | 
			
		||||
            },
 | 
			
		||||
            "ltrim" => function ($str, $chars = " \n\r\t\v\0") {
 | 
			
		||||
                return [ltrim($str, $chars)];
 | 
			
		||||
            },
 | 
			
		||||
            "rtrim" => function ($str, $chars = " \n\r\t\v\0") {
 | 
			
		||||
                return [rtrim($str, $chars)];
 | 
			
		||||
            },
 | 
			
		||||
            "starts_with" => function ($str, $start) {
 | 
			
		||||
                return [str_starts_with($str, $start)];
 | 
			
		||||
            },
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        LuaUtils::registerLuaLibs($this->lua_sandbox);
 | 
			
		||||
    }
 | 
			
		||||
    private function createLuaSandbox(): void {
 | 
			
		||||
 | 
			
		||||
    private function createLuaSandbox(): void
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->lua_sandbox === null) {
 | 
			
		||||
            $this->lua_sandbox = new LuaSandbox;
 | 
			
		||||
            $this->addLuaLibraries();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private function luaCall(string $lua_function): void {
 | 
			
		||||
 | 
			
		||||
    private function luaCall(string $lua_function): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->createLuaSandbox();
 | 
			
		||||
        $implementation = file_get_contents($this->getGameDir() . DIRECTORY_SEPARATOR . $this->lua_script);
 | 
			
		||||
        $function_call = "$lua_function()";
 | 
			
		||||
@ -97,7 +116,8 @@ class Task implements JsonSerializable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // set task type
 | 
			
		||||
    function setType(string $type): void {
 | 
			
		||||
    function setType(string $type): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->type = $type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -117,7 +137,8 @@ class Task implements JsonSerializable
 | 
			
		||||
        return $this->max_mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setMark(float $mark): void {
 | 
			
		||||
    function setMark(float $mark): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->mark = max($mark, 0.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -126,15 +147,18 @@ class Task implements JsonSerializable
 | 
			
		||||
        return $this->mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function luaCheck(): void {
 | 
			
		||||
    private function luaCheck(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->luaCall("check");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function staticCheck(): void {
 | 
			
		||||
    protected function staticCheck(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->mark = $this->max_mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function autoCheck(): void {
 | 
			
		||||
    function autoCheck(): void
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->lua_script !== "") {
 | 
			
		||||
            $this->luaCheck();
 | 
			
		||||
        } else {
 | 
			
		||||
@ -207,15 +231,18 @@ class Task implements JsonSerializable
 | 
			
		||||
        return $this->lua_script;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLuaParams(): array {
 | 
			
		||||
    public function getLuaParams(): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->lua_params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setLuaParams(array $lua_params): void {
 | 
			
		||||
    public function setLuaParams(array $lua_params): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->lua_params = $lua_params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getPlayerAnswer(): mixed {
 | 
			
		||||
    function getPlayerAnswer(): mixed
 | 
			
		||||
    {
 | 
			
		||||
        return $this->player_answer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -234,15 +261,22 @@ class Task implements JsonSerializable
 | 
			
		||||
        return $this->correct_answer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setComment(string $comment): void {
 | 
			
		||||
    function setComment(string $comment): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->comment = $comment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getComment(): string {
 | 
			
		||||
    function addCommentLine(string $cmtl): void {
 | 
			
		||||
        $this->comment .= $cmtl . "<br>";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getComment(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->comment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function luaRandomize(): void {
 | 
			
		||||
    private function luaRandomize(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->luaCall("randomize");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -253,15 +287,18 @@ class Task implements JsonSerializable
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setGovernor(Game|Test|null &$governor): void {
 | 
			
		||||
    function setGovernor(Game|Test|null &$governor): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->governor =  &$governor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function &getGovernor(): Game|Test|null {
 | 
			
		||||
    function &getGovernor(): Game|Test|null
 | 
			
		||||
    {
 | 
			
		||||
        return $this->governor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getGameDir(): string {
 | 
			
		||||
    function getGameDir(): string
 | 
			
		||||
    {
 | 
			
		||||
        $gov = $this->getGovernor();
 | 
			
		||||
        if ($gov == null) {
 | 
			
		||||
            return "";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user