Compare commits

...

8 Commits

Author SHA1 Message Date
Martin Berg Alstad
d64e2497a8 Updated deps.
Fixed type errors.
2024-07-18 16:30:03 +02:00
Martin Berg Alstad
2376eadea9 Changed operators before sending to backend 2024-07-04 13:29:28 +02:00
Martin Berg Alstad
fea9b8324d Updated name of law 2024-06-27 19:23:47 +02:00
Martin Berg Alstad
ed1fc8ef59 IgnoreCase and changed imply symbol 2024-06-21 18:06:54 +02:00
Martin Berg Alstad
b75cbba462 Merge remote-tracking branch 'origin/master' into simplify-truths-v2 2024-06-21 17:54:17 +02:00
Martin Berg Alstad
2c92ef38df Fixed hideIntermediateSteps 2024-06-17 23:12:44 +02:00
Martin Berg Alstad
5043a7b4bd Updated types and adapted to new API 2024-06-17 00:47:23 +02:00
Martin Berg Alstad
e834476526 Updated types and adapted to new API 2024-06-13 18:44:02 +02:00
6 changed files with 1594 additions and 2018 deletions

View File

@ -11,22 +11,22 @@
},
"license": "MIT",
"devDependencies": {
"autoprefixer": "^10.4.17",
"postcss": "^8.4.35",
"prettier": "3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
"vite": "^5.1.4",
"vite-plugin-solid": "^2.10.1"
"autoprefixer": "^10.4.19",
"postcss": "^8.4.39",
"prettier": "3.3.3",
"prettier-plugin-tailwindcss": "^0.6.5",
"tailwindcss": "^3.4.6",
"typescript": "^5.5.3",
"vite": "^5.3.4",
"vite-plugin-solid": "^2.10.2"
},
"dependencies": {
"@solidjs/router": "^0.12.4",
"@types/diff": "^5.0.9",
"@solidjs/router": "^0.14.1",
"@types/diff": "^5.2.1",
"diff": "^5.2.0",
"solid-headless": "^0.13.1",
"solid-heroicons": "^3.2.4",
"solid-js": "^1.8.15",
"solid-js": "^1.8.18",
"xlsx": "^0.18.5"
}
}

3454
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ import { For } from "solid-js/web"
import { type Component } from "solid-js"
interface TruthTableProps extends SimpleProps {
table?: Table
table?: TruthMatrix
header?: string[]
}
@ -20,8 +20,7 @@ const TruthTable: Component<TruthTableProps> = ({ table, header, className, styl
<th
scope={"col"}
class={
`sticky top-0 bg-default-bg text-center outline
outline-2 outline-offset-[-1px] outline-gray-500 [position:-webkit-sticky;]` /*TODO sticky header at the top of the screen */
`sticky top-0 bg-default-bg text-center outline outline-2 outline-offset-[-1px] outline-gray-500 [position:-webkit-sticky;]` /*TODO sticky header at the top of the screen */
}
>
<p class={"w-max px-2"}>{exp}</p>
@ -37,8 +36,7 @@ const TruthTable: Component<TruthTableProps> = ({ table, header, className, styl
<For each={row}>
{(value) => (
<td
class={`border border-gray-500 text-center last:underline
${value ? "bg-green-700" : "bg-red-700"}`}
class={`border border-gray-500 text-center last:underline ${value ? "bg-green-700" : "bg-red-700"}`}
>
<p>{value ? "T" : "F"}</p>
</td>

View File

@ -25,18 +25,20 @@ type Option = {
}
const fetchUrls = [
"http://localhost:8080/simplify/table/",
"https://api.martials.no/simplify-truths/simplify/table/"
"http://localhost:8000/simplify/table/",
"https://api.martials.no/simplify-truths/v2/simplify/table/"
]
// TODO move some code to new components
// TODO option to ignore case
// TODO more user friendly options
const TruthTablePage: Component = () => {
const [searchParams, setSearchParams] = useSearchParams()
let inputElement: HTMLInputElement | undefined = undefined
let inputElement!: HTMLInputElement
let simplifyDefault = searchParams.simplify === undefined || searchParams.simplify === "true",
inputContent = !!searchParams.exp,
hideIntermediate = searchParams.hideIntermediate === "true"
hideIntermediate = searchParams.hideIntermediateSteps === "true"
const [simplifyEnabled, setSimplifyEnabled] = createSignal(simplifyDefault)
const [fetchResult, setFetchResult] = createSignal<FetchResult | null>(null)
@ -75,14 +77,14 @@ const TruthTablePage: Component = () => {
simplify: simplifyEnabled(),
hide: hideValues().value,
sort: sortValues().value,
hideIntermediate: hideIntermediates()
hideIntermediateSteps: hideIntermediates()
})
getFetchResult(exp)
void getFetchResult(exp)
}
}
function getFetchResult(exp: string | null): void {
async function getFetchResult(exp: string | null): Promise<void> {
setFetchResult(null)
if (exp && exp !== "") {
@ -90,18 +92,30 @@ const TruthTablePage: Component = () => {
setError(null)
setIsLoaded(false)
fetch(`${fetchUrls[useLocalhost() ? 0 : 1]}${encodeURIComponent(exp)}?
simplify=${simplifyEnabled()}&hide=${hideValues().value}&sort=${sortValues().value}&caseSensitive=false&
hideIntermediate=${hideIntermediates()}`)
.then((res) => res.json())
.then((res) => {
if (res.status !== "OK" && !res.ok) {
return setError({ title: "Input error", message: res.message })
}
return setFetchResult(res)
try {
const response =
await fetch(`${fetchUrls[useLocalhost() ? 0 : 1]}${encodeURIComponent(exp)}?
simplify=${simplifyEnabled()}&hide=${hideValues().value}&sort=${sortValues().value}&ignoreCase=false&
hideIntermediateSteps=${hideIntermediates()}`)
const body = await response.json()
if (!response.ok) {
setError({
title: "Input error",
message: body.message
})
} else {
const fetchResult: FetchResult = body
setFetchResult(fetchResult)
}
} catch (e: any) {
setError({
title: "Error",
message: e.message
})
.catch((err) => setError({ title: "Fetch error", message: err.toString() }))
.finally(() => setIsLoaded(true))
} finally {
setIsLoaded(true)
}
}
}
@ -120,7 +134,7 @@ hideIntermediate=${hideIntermediates()}`)
setSortValues(sortOptions.find((o) => o.value === sort) ?? sortOptions[0])
}
getFetchResult(exp)
void getFetchResult(exp)
}
// Focuses searchbar on load
@ -286,12 +300,12 @@ hideIntermediate=${hideIntermediates()}`)
/>
</Show>
<Show when={simplifyEnabled() && (fetchResult()?.orderOperations?.length ?? 0) > 0} keyed>
<Show when={simplifyEnabled() && (fetchResult()?.operations?.length ?? 0) > 0} keyed>
<ShowMeHow fetchResult={fetchResult} />
</Show>
</div>
<Show when={isLoaded() && error() === null} keyed>
<Show when={isLoaded() && error() === null && fetchResult()?.truthTable} keyed>
<Show when={simplifyEnabled()} keyed>
<InfoBox
className={"mx-auto w-fit pb-1 text-center text-lg"}
@ -305,8 +319,8 @@ hideIntermediate=${hideIntermediates()}`)
<div class={"m-2 flex justify-center"}>
<div id={"table"} class={"h-[45rem] overflow-auto"}>
<TruthTable
header={fetchResult()?.header ?? undefined}
table={fetchResult()?.table?.truthMatrix}
header={fetchResult()!.truthTable!.header}
table={fetchResult()!.truthTable!.truthMatrix}
id={tableId}
/>
</div>
@ -354,7 +368,7 @@ const ShowMeHow: Component<ShowMeHowProps> = ({ fetchResult }) => (
<MyDisclosure title={"Show me how it's done"}>
<table class={"table"}>
<tbody>
<For each={fetchResult()?.orderOperations}>{orderOperationRow()}</For>
<For each={fetchResult()?.operations}>{operationRow()}</For>
</tbody>
</table>
</MyDisclosure>
@ -372,7 +386,8 @@ const HowTo: Component = () => (
Parentheses is also allowed.
</p>
<p>
API docs can be found <Link to={"https://api.martials.no/simplify-truths"}>here</Link>.
API docs can be found{" "}
<Link to={"https://api.martials.no/simplify-truths/v2/openapi"}>here</Link>.
</p>
</MyDisclosure>
@ -380,7 +395,7 @@ const HowTo: Component = () => (
</MyDisclosureContainer>
)
const orderOperationRow = () => (operation: OrderOfOperation, index: Accessor<number>) => (
const operationRow = () => (operation: Operation, index: Accessor<number>) => (
<tr class={"border-b border-dotted border-gray-500"}>
<td>{index() + 1}:</td>
<td class={"px-2"}>
@ -437,7 +452,7 @@ const KeywordsDisclosure: Component = () => (
</tr>
<tr>
<td class={"pr-2"}>Implication:</td>
<td>{"->"}</td>
<td>{"=>"}</td>
<td class={"px-2"}>IMPLICATION</td>
<td>IMP</td>
</tr>

53
src/types/types.d.ts vendored
View File

@ -37,34 +37,51 @@ interface CardProps extends LinkProps {
title?: string
}
type Expression = {
leading: string
left: Expression | null
operator: Operator | null
right: Expression | null
trailing: string
atomic: string | null
type AtomicExpression = {
atomic: string
}
type Operator = "AND" | "OR" | "NOT" | "IMPLICATION"
type NotExpression = {
not: Expression
}
type Table = boolean[][]
type BinaryExpression = {
left: Expression
operator: BinaryOperator
right: Expression
}
type OrderOfOperation = {
type Expression = AtomicExpression | NotExpression | BinaryExpression
type BinaryOperator = "AND" | "OR" | "IMPLICATION"
type Law =
| "ELIMINATION_OF_IMPLICATION"
| "DE_MORGANS_LAWS"
| "ABSORPTION_LAW"
| "ASSOCIATIVE_LAW"
| "DISTRIBUTIVE_LAW"
| "DOUBLE_NEGATION_ELIMINATION"
| "COMMUTATIVE_LAW"
type TruthMatrix = boolean[][]
type Operation = {
before: string
after: string
law: string
law: Law
}
type Table = {
header: string[]
truthMatrix: TruthMatrix
}
type FetchResult = {
status: string
version: string | null
version: string
before: string
after: string
orderOperations: OrderOfOperation[] | null
operations: Operation[]
expression: Expression | null
header: string[] | null
table: {
truthMatrix: Table
} | null
truthTable?: Table | null
}

View File

@ -7,8 +7,8 @@ export function replaceOperators(expression: string): string {
return expression
.replaceAll(/\//g, "|")
.replaceAll(/¬/g, "!")
.replaceAll(/\sOR\s/gi, " | ")
.replaceAll(/\sAND\s/gi, " & ")
.replaceAll(/\s(IMPLICATION|IMP)\s/gi, " -> ")
.replaceAll(/\s(OR|)\s/gi, " | ")
.replaceAll(/\s(AND|⋀)\s/gi, " & ")
.replaceAll(/\s(IMPLICATION|IMP|->)\s/gi, " => ")
.replaceAll(/\sNOT\s/gi, " !")
}